ode-0.11.1/0000777000076400007640000000000011206343457007363 500000000000000ode-0.11.1/CHANGELOG.txt0000644000076400007640000006215711206342116011331 00000000000000ODE 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). ------------------------------------------------------------------------------ 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 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 . 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 . * 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 * 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 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. ode-0.11.1/build/0000777000076400007640000000000011206343334010454 500000000000000ode-0.11.1/build/premake4.lua0000644000076400007640000002675311206274560012624 00000000000000---------------------------------------------------------------------- -- Premake4 configuration script for OpenDE -- Contributed by Jason Perkins (starkos@industriousone.com) -- For more information on Premake: http://industriousone.com/premake ---------------------------------------------------------------------- ---------------------------------------------------------------------- -- Demo list: add/remove demos from here and the rest of the build -- should just work. ---------------------------------------------------------------------- local demos = { "boxstack", "buggy", "cards", "chain1", "chain2", "collision", "crash", "cylvssphere", "feedback", "friction", "gyroscopic", "heightfield", "hinge", "I", "jointPR", "jointPU", "joints", "kinematic", "motion", "motor", "ode", "piston", "plane2d", "slider", "space", "space_stress", "step", } local trimesh_demos = { "basket", "cyl", "moving_trimesh", "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 = "no-dif", description = "Exclude DIF (Dynamics Interchange Format) exports" } newoption { trigger = "no-trimesh", description = "Exclude trimesh collision geometry" } newoption { trigger = "no-alloca", description = "Use heap memory instead of the stack (experimental)" } newoption { trigger = "enable-ou", description = "Use TLS for global variables (experimental)" } 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" } -- always clean all of the optional components and toolsets if _ACTION == "clean" then _OPTIONS["with-demos"] = "" _OPTIONS["with-tests"] = "" for action in pairs(premake.actions) do os.rmdir(action) end 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" } -- define all the possible build configurations configurations { "DebugSingleDLL", "ReleaseSingleDLL", "DebugSingleLib", "ReleaseSingleLib", "DebugDoubleDLL", "ReleaseDoubleDLL", "DebugDoubleLib", "ReleaseDoubleLib" } configuration { "Debug*" } defines { "_DEBUG" } flags { "Symbols" } configuration { "Release*" } flags { "OptimizeSpeed", "NoFramePointer" } configuration { "*Single*" } defines { "dSINGLE" } configuration { "*Double*" } defines { "dDOUBLE" } 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" } -- 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", "../ou/include" } 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", } configuration { "no-dif" } excludes { "../ode/src/export-dif.cpp" } configuration { "no-trimesh" } excludes { "../ode/src/collision_trimesh_colliders.h", "../ode/src/collision_trimesh_internal.h", "../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_distance.cpp", "../ode/src/collision_trimesh_ray.cpp", "../ode/src/collision_trimesh_sphere.cpp", "../ode/src/collision_trimesh_trimesh.cpp", "../ode/src/collision_trimesh_plane.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 { "enable-ou" } files { "../ou/**.h", "../ou/**.cpp" } defines { "_OU_NAMESPACE=odeou" } configuration { "windows" } links { "user32" } configuration { "*Lib" } kind "StaticLib" defines "ODE_LIB" configuration { "*DLL" } kind "SharedLib" defines "ODE_DLL" configuration { "DebugSingle*" } targetname "ode_singled" defines "dSINGLE" configuration { "ReleaseSingle*" } targetname "ode_single" defines "dSINGLE" configuration { "DebugDouble*" } targetname "ode_doubled" defines "dDOUBLE" configuration { "ReleaseDouble*" } targetname "ode_double" defines "dDOUBLE" ---------------------------------------------------------------------- -- Write a custom to src/ode, based on the supplied flags ---------------------------------------------------------------------- if _ACTION then io.input("config-default.h") local text = io.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 if _OPTIONS["no-alloca"] then text = string.gsub(text, "/%* #define dUSE_MALLOC_FOR_ALLOCA %*/", "#define dUSE_MALLOC_FOR_ALLOCA") end if _OPTIONS["enable-ou"] then text = string.gsub(text, "/%* #define dOU_ENABLED 1 %*/", "#define dOU_ENABLED 1") text = string.gsub(text, "/%* #define dATOMICS_ENABLED 1 %*/", "#define dATOMICS_ENABLED 1") text = string.gsub(text, "/%* #define dTLS_ENABLED 1 %*/", "#define dTLS_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 io.output("../ode/src/config.h") io.write(text) io.close() 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 { "*Lib" } kind "StaticLib" defines { "DS_LIB" } configuration { "*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 ode-0.11.1/build/config-default.h0000644000076400007640000001123311206274560013434 00000000000000/* 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. * * dUSE_MALLOC_FOR_ALLOCA (experimental)- * Use malloc() instead of alloca(). Slower, * but allows for larger systems and more * graceful out-of-memory handling. * * dTRIMESH_OPCODE_USE_NEW_TRIMESH_TRIMESH_COLLIDER (experimental)- * Use an alternative trimesh-trimesh collider * which should yield better results. * * dOU_ENABLED (experimental) * dATOMICS_ENABLED (experimental) * dTLS_ENABLED (experimental) * Use generic features of OU library, atomic * API and TLS API respectively. Using TLS for * global variables allows calling ODE from * multiple threads. * ******************************************************************/ #define dTRIMESH_ENABLED 1 #define dTRIMESH_OPCODE 1 #define dTRIMESH_16BIT_INDICES 0 #define dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER 0 /* #define dUSE_MALLOC_FOR_ALLOCA */ /* #define dOU_ENABLED 1 */ /* #define dATOMICS_ENABLED 1 */ /* #define dTLS_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 #endif #if !defined(ODE_PLATFORM_WINDOWS) #include #endif // Use the error-checking memory allocation system. Because this system uses heap // (malloc) instead of stack (alloca), it is slower. However, it allows you to // simulate larger scenes, as well as handle out-of-memory errors in a somewhat // graceful manner #ifdef dUSE_MALLOC_FOR_ALLOCA enum { d_MEMORY_OK = 0, /* no memory errors */ d_MEMORY_OUT_OF_MEMORY /* malloc failed due to out of memory error */ }; #endif #ifdef dSINGLE #define dEpsilon FLT_EPSILON #else #define dEpsilon DBL_EPSILON #endif /* An integer type that can be safely cast to a pointer. This definition * should be safe even on 64-bit systems */ typedef size_t intP; /* 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. */ #define EFFICIENT_ALIGNMENT 16 /* Basic OU functionality is required if either atomic API or TLS support * is enabled. */ #if dATOMICS_ENABLED || dTLS_ENABLED #undef dOU_ENABLED #define dOU_ENABLED 1 #endif #endif ode-0.11.1/build/premake4.exe0000644000076400007640000062100011140715014012575 00000000000000MZ@ !L!This program cannot be run in DOS mode. $PELOI 8F`@`o" P .textDF``.data`J@.rdatapL@@.bss@.idata P @U]U1ۉu1=wC=r[$1҉T$T=tzt$л؋u]]=twJ=t؋u]]=t[=u$1t$<tjt$=$L$<v7l$ 1ɉL$<t0R$ ?$D$l<%$ \$R< 'US$]$@Ab6]7E@CU\$ `AD$T$L$ $@C<0@Ctc`ARCt 0@CD$RCK0 $;RCt&0@C\$ RCQP$;t&';`A~5V;L$@CT$@C$";$@D$RCB$E;RCJv'U$RC&U$RC&U RC]t&U RC]ᐐU]7UVuSjjVPV@ uVaShpAVO jVe[^]ÐUW}VSjjW]jjWQjPS@uWVh0pAW jWe[^_]ÐU@S"9Sh@?1҅t-t8\u/@8Pu]ÐUS0]jjS 8ujEPR$9YZu E%@PjSX]ZÐUEЃ0Pu8Z1҅Yu UɉUS]jjSP$S]ÐUW}VSjjWhH9Í@PV>SWCle[^_]USju ZËYtPy>S8]1US]jS 4PS ]US]jS @PS]UVuSjVd X1;Zt913jV${uCP3=t؀{4.Cu܍e[^]ÐUVuSjjVjP= uVo ShPpAV]  jV"e[^]UWVSV}EuWVY[juWLà j;S7^Zt)PSWC S1Wr Y[jWhppAW] jWjW jjW2 PZtjW ,jWY[t CrEW9EZ<1e[^_]ÐUVuSjjV~P< uV1 ShpAV  jV e[^]ÐUS@=@CuhpAV<hpAP[<@CE]P@CEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPhpAS5HSu ]ÐUWVSj=R5Y[t/)~SVwP5Ƅ+ VqAP5XZVj Sj hqASn5u >t5 @Ce1[^_]UW}VS0w#P袀hqAhrAShrAS h-rAhS $h8rAS h)@VYGuVF;BrBe[^_]UVu S]PjSw^PSFBSJKBCAPSjPSWWe[^]UPPE jUEEEB+B PEPh)@ROYUWVS u}uCu]u SWiVSWgZe[^_]UMQzu"Bxujuu BpQ?]UE]@UU W}EV1S_w$CC@rCDC@jW5mXasD YsDNSD 9w)K@4C@9S@w(Wl{XtCD9C@sPCP sTCTe[^_]UuK1UU S]USR0S ‹CtC]UVuS] ~4VB@9BDrVkXF+F HPSVF)؃F!u ^jhCVDFC e[^]UU MtA@]A@ UEPEBE B ]US]SB@9BDrSNkXPu SSCB]U1ɉVuSxuGyt~$A9DC#ҋY~;S$~1D@CL[^]UWVSR}U URUƅXt]OSCQAOe[^_]UWVSSSU EUǍEP3EYtDE]pNVHFSACy~VBt@t RPuj Ee[^_]ÐUVuSp]Vu S= t(VhCSEE ~PEPhCS] jhCSe[^]UVuS]jSVu SjShSe[^]UWVuSp}V] jW = u uShC.VhCWEhCu}uKuuuhCWm}uE9CuuSh;CWLe[^_]UWVS} ]uWSZYPSZYPVhYCS]E} ]e[^_]0UVSuPZYPVSe[^]UVu S]VhSdjS61҅u+jSejjS jSVhSe[^]UWVu S]VS8DžXZt8VSZYt+uhSjjSt jS uVS1e[^_]UVS]uu SYZuuE mC]e[^]e[^]UWVSu }]VWCY9Zt]e[^_]e[^_]UVuS] SVY@ZuhCSV e[^]UW}Vu SuVW/ u jSYe[^_]UWVSSE} u]EWPZYt/1t эA]E} Ee[^_]ue[^_]UWVSSSE}EE EEtjPuutjuu- 1?tS4ZYt3F<ShCuEE E EEe[^_]e[^_]UVSQQ] uSVnX]EZuzSVZYu j^Ee[^]UVSSS] uE]SVfZY~] ue[^]Ee[^]UWVuS] SV DžXZuSVZYu j^e[^_]UWVS] u}SVYZ~] ue[^_]뗍e[^_]US]u SYZ1҅t9uSjS&jSu jS1 jS]UW}Vu S'='w WY\0uSWx 1҅tSWjjWe[^_]UE U@PP ]UWVuS]u VXZj.S6Y_u߃1э|)PSVjV9jVuBjV?.EuPjV)PSV jVLjVTjVfYZt jVj_V?.XZJ1e[^_]UWVSPP] Euۋ}EE8tEjhChVSjV jV$tAjV uShVtShCV1 jVqSjVjVPVKU:tC~PV6YKXuWEpVKUG2PVOEE8뻉u׉} e[^_]_Ujuu uU1҉VS) tP^ Sv Fe[^]US]ssC]UWVS x~jExjWMYXE@EPW9ZFZE+E@ 9 ШtEˉEE9E|uWWF+E@FXZe[^_]US]tdC []UW}Vu S]Kt 9rWXFݍe[^_]U1WU IQRu}UW1VS}u 򮍅IPu^[_!)PVWauW4uVZYuVWhWajju}e[^_]UEWVSQ]sPjV\ lj؋U ) 9wRWQEjV t jVXZC e[^_]UW}VS] '='w W^tjWY[u jWNjVWjWMjWtSVWjVW VWCXZSVW؍e[^_]UWVSQE}] ExR'='w W ZtjVWuVWuWE u }e[^_]e[^_]UM VuS9tC+Q1B u RYhjSu1҉Ѝe[^]UWVSS0\juSV@PWhCS$uSe[^_]UWVSuV&Dž@} XujhCVRC 8u hCVhCu uClBHBx @ R_#ucDžBHBx @ R[t u u$BHBx @ R\Y1҃} …thhCu  uCBHBx @ RZtuDžQbjjV PPh8@VNjX } tPXt ViCVe[^_]U1M QtEA]UPPE uEEEEPh;@u`UWU 1RIQRu}UEU t E UGR1Ujju PRChC@P1USjh<@蝹YÅXt h3<@S XZ؋]ÐUWVSQ]S/huChSE;}mjSWSjjS)jjS(u hxCS4F~RC Pj XZRCG PVjS뎡RC Pj 1e[^_]UWVSVuj jV@ u*jVjVjVY[jjVǍC "vhCjV SEPW_ ;}tT@EERC8uRCP jRG_ZEuˀ8u1RS,$$VsVSe[^_]UVS]jjSWjSjSt~VShjSjS@]e[^]US]jSjS0uS hCjS]UVuSjVjjVjƒ ШuhCjVZ hCjV t hCVXZjVjVe[^]UWVSpjPMZYu jS_XtjjS" jSY^yhCjS }WVS+ uhCjS Wh$CS3jSuVh&CSD e[^_]US]>jSZYt hSXjS[]XUS]jjS1҉jS jSt1jSXZuzSjSjS1.jS?ZYujSZYu hXCSn[X]US]jSjSjjS PSR]US]jjS=jSljSjS]US]jjS jS9jS1jS$jS]US]jjSF PS!]UW}VShChCjWjjWP4CWƋC(tt#*jjWV$$$ CVW=V$$Wue[^_]US]jSLjSfYZPS|YZPS]US]jjSjSqjSu S]US]jjShSjSS]UVuSjVjCjVaSVSjV\(jVYЃ[e[^]US]jjS"hSAjS9jSf]U҉SøtSjS]UEVSV]PjS%jPjSMPuVS"ƒe[^]US]jjjSPSZ‰Y]mUVS]uhCjSjStjjS jSYZu=jSYZt"jSXZuE ]e[^]h*CS[^e1[^]UVS]jhOCjScjjSjSO$VjhC@Se‰[^]UWVuSjjjVVSVtVYjjV Ve)[^_]US]jSmjSt ]]jhWCjSPhiCS]UWVSjjujju)ju$ZY ju ju^1_9@)؍x~WuZYuhlCu]Sju|؃ C9|e[^_]UW}VSWjW u#jjW 8#uFPW2jW"ÅXZy9~hCjW )؍e[^_]US]jSjjSNH$SPS jSYX]]US]jSjSjSjjjSp(PSQjS]]US]jShhCjSjSjZYt.tK[ttOjjS P#jSjSUZCYuCRSt[X?jhCS& -jSZYPjSZYPSZYPhCS]UVuSjVjVgjVjV[HZu*jjVujVPjVhV$LjVZYt$hVjVnjV|uhCjV jVH[XjV[e[^]USӃp19tDSZt Ht1*EPjS" SY҃B]UVuSjVYÅXuhCjV@ ډu4CVe[^]UWVSMuWdZYu hCVYXt4ChCV]uWVWVuW!9w2W$Í@PV u h CV]XZSVWN jVWAe[^_]UVuSjV!ÅXZuhCjVH VHډ$ÅXyjV jV-jCVPV؍e[^]UVuShVVS$ډ y0jVZYtjV$jVjVVYe[^]UVS]SjS ujSZYth;CjSS jSajVSe[^]US]SjhfJ@SY]US]Sy$S7]US]S ZtS[]UVSju PjuSVjSe[^]US]hSYXhQChS hChQCS jhTCS h\ChS غeChB@hC@^XZlCh[B@hB@FYXjjSA jSXZjSYXjhrCSP huCjS, jhG@S h|ChS hpChCS]ÐU1҉8uxuxu]UVS]@ )Ӎ4C1)=~hCq \XZ? ‰e[^]UUBB]U@ -tL]UWVSu}E t-u0 Éډuuډ[^_]@[^_]Uҋ@ ~A?*CyA]UVSӃt'ډ?tډ?1[^]UV1S]Ѓ?u@t9t?? ډ Ѓ[^]UVSӃthډYډߍe[^]UWVSӃt2ډu ډljFZtuuډ [ɍe[^_]US]S=u C PSa]UEMU ;Hu]͉ME M]qUVuS^$] @K9~~hCv YYXXKe[^]UVu S]VSs$e[^]Uu @29|I$]U: u]R]UWVS @RvEP? x{(u!}E fEm]mEF(@F(@;C(~!hCC(hjPsumC;{(}SDG;{(|F(}COWHP~@tCt PSuH V(BF(Ѝe[^_]UEM UREMUE EEUR]UWVSPEu }E u$^H E@?% ‰RuM^H E@ ‰^G$%?? ‰E }X[^_]X[^_]UES]  u S@ %C#u KP % []UR?u@]UEHE RD]UWVS0ËP php}C C @;F,~!hCF,hjPv s~kF CV [uvFPW V;VEEuVt=> t WYjUjkjUjEZSWEWuËVuPxuVuSgFEF Fe[^_]UVSu ]VS$jSC$HEe[^]UVuS] SV; XZu#CS9CuF29| RSVCe[^]UU MB9Bt]량U M]zUVS0u ]VSXZt}w uz{(quECUEEEP-uv vSI EUREȉYF F=VSe[^]UWVS ÉUEu FE@E wt$tCqmڞztoZڞzt\U]$EXEZ$Ƀ\$$ u z UZv؃}1҃}1t VSVY_uSIY9EZ~U UWujuSUB e[^_]UVS E Eu]EE]t YXuIV@ ?u6؉t ^H G ‰FGVSXZu }Lu }?u }2u }%u }u } u }e[^_]u} E u} EDu} Eu} E!u} Eu} Ee[^_]e[^_]UVSE u]$C] ue[^]SVXZtwHtt tV-C jډYPCPV sVXZC-] ue[^]xu] ue[^]e[^]US] uuC  ]UWVuS]u S\U U{$jSVSYZPE pWj S؃$%E x e[^_]UWVSu ]}t4wtmt7 tJaFEe[^_]WSjvPj(WSvPjSWSPv vj Se؉[^_]uU2WEV} uSHXEu1SPWj"VjPWj"VF pGF$e[^_]ÐUhuƾɸUS]jSjSuSX]US]jS谾Zƒ YuhYCjSH jSżjSZYPS]UjuɸUS]jjSjS}jSu hoCS[X]UVSuPcSjV e[^]UVSuPSjVe[^]UVSjP½ZYujS)؍e[^]U9ЉSujP[jS jPR ujSs]UUWVSt]xjNjEhCPSuƋE@PS脽Ut)EPBPSZYPW u[SBPSZYu4VhCSjjSƋE@PS蒼 jWS6 hCE@EPVW uhCEPS9jjS`jSVtOuC=ECP-uC@uC1uCjlVWZYtuغ CXjuV9ZYtuCYjnVYZt uCuCXZjLVZYth(CYjfV^Zth4C؉[e[^_]UUWVSt]uwSNjE@PVZYPW Euh9C@PVGPVZYPSW tjVWuSVKjV趺 V諾e[^_]UUW}VSt]WƋE@PS\ZYPVz Euh9C@PSCJtt ECNuC Ut _t݋M؍T1E9}EE9EC UEEe[^_]UEP,h;ZUtЋQ|uC]UWVS uEE UEUBxxXEPǍFPSU t CVYƒ? $CCUCo9}`g؁UC?CCt EC؁UC1e[^_]UWVSE E}E8>uE UMBP@QEG`tUkR(ЉE@E}EE EuWGCG$GCG CGGG GCjCHd1CPC@[^]USE] UHyu []\CQ$ЈC[]UU EHbA(BQ(]UEM @PH@$AEA]UVuS] NAYS¨uAu=yu)CSx~(@t tPSV= A$ˆSe[^]ÐU=$CVuS Ct)jsV3VGjjV< {Սe[^]ÐUWVSۋ8tjVILVn}XtW詴$uhCVJW荴$hCV1 WV`e[^_]UVSJ0S$uhCSjjSm PVSʓe[^]UVS]jSٕjSEhChStjSYZtjjS蚄 u S與Z>u j hCjhCS踇 e[^]UVShCjP{ 8u hCVY^e[^]UVSjPhChSSjSme[^]US]Sjh CS#]UVSuhCjV0u1Ee[^]UVSuhCjV觓0r1Ee[^]USjP݉h) CjS~jS}ZYSЋ]US]jS7Z@YujhS׈ ؋]US]hCjS 8t}]1US]hCjSܒ uj h1 CS Ph? CS~ ]UWVSS}jjW蛓EjhI CjW输É!Su赱$uE1҉Ee[^_]e[^_]UWVSV}jjW5EjhI CjWXÉSu菲$uE1҉Ee[^_] e[^_]UVSuu=uE1[^][^]UWVSRhPyhVzy1e[^]UWVS]PUxZE@SWzZYu5Et%SWN|$h CuA~Eu9EPSWsE tuujP藫;EuEuMC}qj]e[^_]US]gE‰[]US]_E‰[]UWVSu=h Ch CjVQjjV蛍4 CPWҪ(tEe[1^_]W螪$Vp}e[^_]UWVS]h!CjjS܋hjS#P4 CjW8E,1҅e[^_]9US]KPY1҅E؋]US]5P©Z1҅E؋]UW}VS7~jVNxWhVKjV7xjV8u jV`e[^_]UVSjjP&jVS'}h) CjS/e[^]US]hCS贈XZjSwYXh!CjS hCjS غ@hSvhCh!CS藎غ@_h!CRCjh!!CRCj RC$h(!Cj@jSuhCjSv}@jS$jSqu]ÐUWVS1Pu!CE}1IQuVPH Cƒ P~ʍe[^_]UVuS] @RC8uRCX j SAZYtSh`"CShi"Cv4$Ce[^]UWVSP]jPu} F@PS$WvShl"Cv4$ }t:E-w16F< uV;[ZPWhv"Cv4s$jv4e[^_]UWVSSX~+OmS8H@t B@B RY -t -S8H@t B@B RZ [u1‹C<@xR1/C<@_ 1҃ …AS8H@t B@B Rm^ 뿉]xPU@[hh#CS S8H@t B@B RY ==S8H@t B@B RߕZ S8H@t B@B R賕_ =<pS8H@t B@B R胕^ DS8H@t B@B RWY =>S8H@t B@B R'Z S8H@t B@B R_ =~S8H@t B@B R˔^ S8H@t B@B R薔Y 9 t @t t\t$hhh:#CS K8H@t A@A Q-Z‰btJ t Bu tlat!}rtB ft'nt,jtt9vt>^  غ RC8uRCP jR1Y^E1k S8pЋH@t B@B R)ZE }(RC8uRCH jQɛZYu~hhL#CS /S8H@t B@B R裒^ 9;S8H@t B@B RqY SWYUe[^_]ÐUWtVSĀ芕jhWjPjh聕t WVidXZSh&CVd e[^_]USh)&CjupË tPG1]UWVSRh2&Ch<&CPqdhSeY_jS__ZtjSbZYdjS]_XjSmZYh)&ChSre jShYXVh2&Ch<&CScjS^XZhSfYX?uVDu7t&uR1u jPSc1e[^_]UVuSjjVpjjVpPډÃ۸t'VXbjVG]KA&CtF&CPVbe[^]UWVSQQ]hK&ChM&CRPUEvShuEPdjjun`(uShO&Cum jhm&Cub ;;uC1;t3j;S$^_u߃1эt)PSua tuuhn&Cjju_ Puuju\hp&CS蹍ZYu*Shr&Cu'bju[juYjLPX1e[^_]UVSjjPf_ PVjjSW_ Ph&CS~le[^]UVuSjjVnh&C‰ttPVwZYt ډe[^]UVSj-RZYtXh&ChM&CSVtPh&CV`e[^_]UVS]jjS[mh&ChSdajS6[ t h&CSjYXVjS>ajS[uVh'CS_ e[^]UWVS]jjSljSYh0'ChS` VjS`jS\t)jS]Z=&CYJVh8'CS j 6hc'ChS`jSeZt hk'CSiY_jhm&CS_^ WjS`jS*ZujjSi\ PVh'CSiVS]^jjSRdjSYt%jSsZYZt jSfjSXXGZh&CSw_VjSaVS^jjSc(jSYZYt VjSa VjS_jS\=&CujS^jS$YVjSWae[^_]UWVSp]jjS/kSKWh0'CxhS/_VWS'_(jSXZYtAjS'WjVhSmtVh'CSLh@jSXVWS`h'CjS^jSXt jSVY^mjSVXZjSEXYXh'CjSr` VS\XZh'CjSY` j.V\ZYu@)PVSM\ h'CjS)` jSW^uXVjS t!Vh'CS tjSXZYt h'CSVgY^jOSWXZjSaY^jSUXZ9#VFSoWYXjSeWXZjjSa 1e[^_]US]jjSijS^ujjS=^jSWjS`hSWh(CjS1_]1UWVSuu Zu VST[)h(Ch (CPS/oVh(CPS"o jSWU^XhVjA= Шuj\V趉ZYu h(CSf(Vh.(CjjSX PSnjST^XWjSb^e[^_]UVuS1h)&CVfjh@V#[h0(CjV+^ h%Ch5(CVljVUhVUjjV\(=%Ct&j4%CCVZSjV^<%Chc'CjV]h=(C&Chw(C|h(C&Ch(Cfj h(CVY(h(CjVs]jh0'ChVJjh(CjVT](jjV(\h&CjV:]hVT h%CjVkjVJSe[^]ÐU1ɉEv@Av  ]UUSЉt HZ[]UE=v(C]U1S]M S;Qu6t'Ұt)tu 9[]UWVuSS]V} S{EZ19YttTW耀$uh,CV!UWVSTe[^_]US]jjjSmbP?$S!T]UVSujjV b PZ1҅]e[^]GUVS]jjSajjSaPV诃YZ1҅ue[^]UVS]SurYu h,CV^ SVSe[^]US]jjS\a PS$SS]UP$5,C$uSɸUVSuPSSjVWe[^]UWVSRjPTjV-OtjVP_X]yWh,CV/^ jVL؍e[^_]UWVS]jh,CjS`jSjN_Z j(Y9jSaٽXZ f٭۝٭>!u PFāP謁Xu SQ`h,CV_}ZYj jST7,Cw,Cw,Cw ,CG,C@PvG ,ClP^G,C@PMG,C@Ptg>%u~u+E9rRdX.FWEEPhSJPSPdF딍PcXe[^_]UVS0]jSnL^Z j,jjS]jSJj,CMEȺ,CjXtZSPw0| w0WoBW1X _0j‰X4s$$S|lY^wjX4ZVPSl{C2 CJSk T S‰Y,C=uݺ=-t Dž1ҍPRkXZ6Ww0X_ u;uDž1! wMjSVl 1҃…tP F2Dž!u SV8sY[ SVrXF2ZPVo W[|R_0 uP %?@jDž Y1;ÉW0B2B$u_wW4B4HfB4e[^_]UWVS]UEu׉E1IQRV Pu SVdd@JSغVde[^_]UWVSLQU P<(}t(jh/CV? ‰jXN01ۋ9GJ~)tvF=t=uBS‰XC:V$h/CV ‰SCZYGJ h!/CVXZJu,눉ډ WJA2(ЈGIA2PQhY)[VP@u h XF0Z@,{4@9~!h:/CC4hjPsv4CS49}CG9|􋍨A,K@B,@tCt PSv4 1ۋA,HPjj$Qj P_xHt;]1Ҁ]jPjCRk@H9|ōe[^_]UWVS(EЉUbUЋB-t#tC=t 51ujŰEűESp0q7= +={= =tp =tU=t =t&jE̺XUЋEBXUЋErU]jLjCj:EЋX0xJuhR/Cu^_`Jjjjj%SiPE [:ŰE6uYUЋErUjXZŰE uXEЋP^E-*%m1+f< tl/S >ItL#t@ $ t| t Q?`-C;EvIuЍ]űUWr0r?a-CPElSƋEuWp0p$uEЋP4B4HfB4e[^_]Uj-UVu؉S }uEVs0jEe[^]UVSPVs0l e[]^]xUWVSL@0UP$EUu+Ex~h}/CE[Uԉ UԉrU]B= EPu>lƉډSu*lZUYPVBpj ugUEP$e[^_]UVS{ ~F0h}/C'^C C$e[^]UWVS8Ӌx0@jjjj WEfP EEEE]jE1Sv0j${~}}Et1PWj}2XEZuj2EupWBrEF[t=UuV~ =UXuUĉ2,lq;X]u}j{~}YM[tRUčBw%jQW^c EjupWqM"t QWiXZuEupWnqp Eu ËEp Eu?% ËEe[^_]UWVSVGs0,i؉YX,Vuۍe[^_]UWVS(x0UЋ@E̋F{tk (t=tdyE;Ft h/CV舺XZV~)Xu E]ԉPjSWb u̺)j(UԉQ$vUԉVCY[ h/CVZEЃMԋXAvt EPW+hXZW$jBPSjWc PEuWbCG$e[^_]UWVSD@0EF(t =t18V^Y0S)j(%XZWv0c h/CVLY[F:tW(t}.t{tn[t|=t^sW]uwgډSWumV]ډgSWumtWuf[e[^_]UWVSHBUv h/CV{Y[,E}E}ue^01ɋUC$҉EtSz u&G9Bu EBG9Bu EBu΅tjws$jSajS.^XZF4@4)9U~h0CF0XEU@PXI=}H;EtWUPs;]_X~+]F0)X$ Wv0_WF0]Ժ @$HPSEPv0le[^_]UWVuԉS V}s0Tee[^_]UUVSËp0jCe[^]UVSPƺde[^]UWVSX0U(-}thuj S_S`_jǍUU u S\/WS[}thujS_u juj!S_uS^}GPuS_^PS[e[^_]ÐUVShjjR hjC(CjVC0C$CpSSC C,-BC@CC C@Be[^]UVSjkB0Pr(VjC,Ps Vze[^]UWVSP]CڍsHE3jjS"CHFsjj~`S"F`Gj S= S2Sjh 0CSH UBDB@e[^_]U]P@ @,@p@D@8@<@9@@@h@0f@6f@4@@@(@@t@PUVSpp P蹔S轞jSBP2SEjvFPxWXP$:e[^_]U卅WV1S]PjS4ǍPS7;s7E9rRn:XC>FPVXP9e[^_]U卅WVS]PjSR4jS5ƍPS 7N~WP: ፅP(9e[^_]UEWVSVVPju3jjuE5U %Pju5] 9v19O)x>9h!1Cu0Y[h!1CWu2 ~EtFPuM%XKZue[^_]UWVS}WMPW5 ;JVW4Z9Yth71CVW0 E9rR8XF뮍P7e[^_]Uuu u{81UVS]jjS2jSVS75Vh@S,,(t hE1CS/[XV]7e[^]UVSC%t[tN;uDhc1Cv/Y^31;^À;uh1Cvd/XZC<%u<;]u׍C؍e[^]UVSRTYaV$1CRC8uRCX%"hRC8uRCX j RC8uRCXjRC8uRCXjRC8uRCXjRC8uRCXnjbRC8uRCXPjDRC8uRCX%0h!RC8uRCX% hSN[Z 193RC8uRCp jVNZYu1҅‰Ѝe[^]UWVSӀz^uf1CC;]sD<%uCt({-uS;UsB999u1[^_]UVSuȃ.t%t,[t%)R[^]FE[^]G9[^]UWVSuE%*$(<(t )t'-~)ujFjFPEUFB Hx M|th2CEp6,[ZUÉ+DDEVXYMD~Vƒbt ft~~^t{uh(2CEp+XZ1:u=WEE[]X9s;EuIuB;EB1҅҉>[th;2CUrZ+Y[EEM1;9tG]KSZS[uYRC҃8uRCP jRKZYF1xU;B } Mƒ|uh^2CEp*Y[MA\)9rSWt4O t1҅҉~uU;zE1EM;ysuZtU+t=*t.~-tF?uttEW@PE2YuluF5uV 1tUuWVEDE@PEZu.M;Ysu_tCυu1 uGe[^_]UWVSp Ã~ht2Cp\)XZ|E DFuC {YuK e[^_]UWVS1C;GsUu ZuxE @P.YuK1e[^_]UWVSËU;{ E |#u)PRYE ^2CCEe[^_](tuh2Cs(YX!uD+@E CEe[^_]Vts e[^_]UWVSQH Uɉƒ} Шuht2C1Sw* 9}uFu&XZe[^_]UWVS4PjO*Pj5*jj , gǃOy19v߃j[^uh2CKZY)to9v ^O)'WC@PSK t܉+)ƅFVPK u+CPSDž8^uMDž@:+CP+Vj1҉DžƅXtgVډW$C;s te[^_]UE]uU1҉E]gU卅WVSPhujhuEhua ;wZڍDžƅXt31)9Pu4hu8VڍFC1e[^_]US]jjS&jjS&jS! jSjhAS]Uh2Cu5$U卅WVS@Pju&jju&jurË @PjuQ( Dž8^uDž@DžCƒ Шuth2Cju# Pu(_UX9WDž][jSpZY" 7'1Pj ;]<%u3CRC8uRCP jRCZYu# 9rW*Y D<0u)PVW* !Ѓ1V*XZWU+XCHjS<YX$PS 1ҍVXZjS&YXjSCYZujSMXZ)PVS-jSZYu"jSZYPSZYPh2CSR! W*X19…t5;s:9rRO)XF)PVS8)Sk(u;e[^_]U1҉WVSƈэQ\fDl\D[^_]U卅WVS`PjuDž"ƋPu%;>%uF>%u,E9rRN([FGtPh3C?ZYu)vh3CuY[RC8uRCP jR@[ZRC8uRCP jRh@ZY?.u[RCG8uRCP jR5@Y[RC8uRCP jR@[ZRC8uRCP jR?ZYth83CuY[)C%APVFQ> Dg>eWXECG:ctJdqE itqous7xu!ٽXZ f٭۝٭P1uO!_ٽX f٭۝٭Lu!ٽZ f٭߽٭YPSu $PP<PuWE 9rS%X"H@ tH tK "t\uN 9;rS$X\@9rS$X7jhe3Cjhh3CS$ 9rS]$XP 9rS2$X"PuKj.ÍP{;u%cvu P$NSPPK; FPhm3Cu_:1эIQRP# P"e[^_]US]h0Ch3CS_"ha0CjSh[0CjSq$jjSE jh 1CSh jS XZjSzYXjSh XZjS YXh3CjS jSD X]ZÐUSSSEuzS'KE EJE1҉ESZY[]UVSQQBtIt5@tt4r2^ZCKH#J(KH# K21HKe[^]URRxu"3C]EP$ztɉUWVSSu} ~~R;GMHP$FO U AQAVFQFAVFVCPZYu{ u~~9Cu +GG[uh3Cu*bY1[_P9}G |BF9؉|_+W9}-EGM|% BM9|1e[^_]USH1=wPD]UVuSӍF=wPBPr Q>QZC S9}DB9|se[^]UWVSQ]uB3CE|CPWZ@E~ h3CV`[XMC=wPjjV袦V胦YG~$1ɉڋGȃ @J@@uE_G_e[^_]UVuSj jjV?jPV要CډCCC CC3Cu ue[^]UVuS] S3Ctj KPRVjCPs V謥jj SV补e[^]UPPU MB;AsQ B?;R$$]ZYzuBEzt͋Ru(CUSU] JH#CBxu9Xt @u(C[]UVSSSu MVt Ҹ(Cte<u76QT3C]UR$uz RQ+'VCP,ZYu[u(Ce[^]UWVS]u }SV^F=(CYZu>Cuh3Cuzt h4CWG^XZ]e[^_]Se[^_]UWVS}EBUM9ljEIRMU~ WUEk^u UE;}[EU܉xMU܋A |t#FPQu KSHPEF;u|ÍG=weMWuq uL u+YUB MNx9U{t"CPuu KSHP Nyҁ}3CtM jPuu͢e[^_]UWVSU|xu =3C]WOBG9vWztBG҉1D@~DžpDžxDžtt1G9~9ÉG;tG @C9~pxѥtt@x~DžlpDžhOUKt0GxtUhlK uՋEUhMplEDž\F9\EDž`DžXDžd}vdD~2`ȉә9`P~X`\U9`Pt%d әP9ЉT+\X|VQM|XZuW|zS9t)9Xt@pj SV1C C CFsMQCSACy~@tGtW|W{_X؍e[^_]UVSu] VSEY=(CZuVE$$EE]e[^]U1VSU u]z3CtJE ][^]sUVSu] VS0Y=(CZuuEPEEe[^]UEWVSHt:p |u+1ۃv  |uӉ)؃މzUȉ΍yz3Cu-eSuxYZu݉ىe[^_]ÐUWVS]jjS$jS2jjS 9GjS+VSYVjSjjS (jS5YZtjFS_XZ1e[^_]US]jjSjjSSDjSjSjSjjS& $jSZYtjSYXjSt YZu]USQQ]jjS]#SI7jSjSaujS EXZv]jS ZYuuuS ]US]jjS jSZYPS]US]jjS}h4CSQ jS]UWVSjjuNjuZXuZttL>EEULD>MD9xreEUECjBCBC KMI Mgt ]DCExht uPG^XMċUJWRw:M Y[]C@CG GʞvٞGUG8U_0O UĉME_PtWWTYZuh7C@{tGPS7ÅXZuh7C!Myt"G PQYE[uh8CuP4XZG]/EčEG O0W$]ĉGPG(WTWGXGWDWG@GW4UGHZG0GAG`B%PQR=E U@ E̋M̋BY8@ۉBt!Y(A0Q4A Q$MċMăEju]C)pC@Cu UċUĉƒ(k2MD0;AE~ PQuK 8uMuu KSHP{~@tE@t PuS_XNWuDY[UB@KHr MQuqCX1ۃ ;]}@EċЃ?uMDDEPuCDXZEC뻉7]EGSCB@9BDrS/RYUR UM]IHES+AMRI)H}EuKEUċ]P@+A9 uQ5XZEU@ MUE̍A1;uk1;u}$UE )ًQ;AT;D;D;F;u|*e[^_]USP]EPs sS tEuKHACЋ]US];uSZ@t KC]UU EBEBBEB ]UW}VuSt3WY@u'9vSwu ) _] )1e[^_]UMVu S]V9v-w CwSR6QvQuZ^e[^]ÐU9CQ@9Cr]ÐUSX5 PX1Щ 1Ӂft @@Ct @@Ct @@Ct @@Ct @@C t @@C@ t @@C=v+@@C@t @@Ct&[]à @@CM[ @@C]ÐU]ÐU`A8t `AQA`AuÍ&USTAt)t'TAKu$HAzY[]1=TA @TAu뾍'USP@Cu5TA P@Ct$tt&TAKu$HA X[]1=TA @TAuÐU@C]HUBSdT$U1ۉT$$pRC uFJx|*Au Jy; 1 then i = i - 1 end return p:sub(1, i) else return "." end end function path.getdrive(p) local ch1 = p:sub(1,1) local ch2 = p:sub(2,2) if ch2 == ":" then return ch1 end end function path.getextension(p) local i = p:findlast(".", true) if (i) then return p:sub(i) else return "" end end function path.getname(p) local i = p:findlast("[/\\]") if (i) then return p:sub(i + 1) else return p end end function path.getrelative(src, dst) -- normalize the two paths src = path.getabsolute(src) dst = path.getabsolute(dst) -- same directory? if (src == dst) then return "." end -- different drives? Must use absolute path if path.getdrive(src) ~= path.getdrive(dst) then return dst end src = src .. "/" dst = dst .. "/" -- trim off the common directories from the front local i = src:find("/") while (i) do if (src:sub(1,i) == dst:sub(1,i)) then src = src:sub(i + 1) dst = dst:sub(i + 1) else break end i = src:find("/") end -- back up from dst to get to this common parent local result = "" i = src:find("/") while (i) do result = result .. "../" i = src:find("/", i + 1) end -- tack on the path down to the dst from here result = result .. dst -- remove the trailing slash return result:sub(1, -2) end function path.isabsolute(p) local ch1 = p:sub(1,1) local ch2 = p:sub(2,2) return (ch1 == "/" or ch1 == "\\" or ch2 == ":") end function path.iscfile(fname) local extensions = { ".c", ".s" } local ext = path.getextension(fname):lower() return table.contains(extensions, ext) end function path.iscppfile(fname) local extensions = { ".cc", ".cpp", ".cxx", ".c", ".s" } local ext = path.getextension(fname):lower() return table.contains(extensions, ext) end function path.isresourcefile(fname) local extensions = { ".rc" } local ext = path.getextension(fname):lower() return table.contains(extensions, ext) end function path.join(leading, trailing) if (not leading) then leading = "" end if (not trailing) then return leading end if (path.isabsolute(trailing)) then return trailing end if (leading == ".") then leading = "" end if (leading:len() > 0 and not leading:endswith("/")) then leading = leading .. "/" end return leading .. trailing end function path.rebase(p, oldbase, newbase) p = path.getabsolute(path.join(oldbase, p)) p = path.getrelative(newbase, p) return p end function path.translate(p, sep) if (type(p) == "table") then local result = { } for _, value in ipairs(p) do table.insert(result, path.translate(value)) end return result else if (not sep) then if (os.is("windows")) then sep = "\\" else sep = "/" end end local result = p:gsub("[/\\]", sep) return result end end -- function string.endswith(haystack, needle) if (haystack and needle) then local hlen = haystack:len() local nlen = needle:len() if (hlen >= nlen) then return (haystack:sub(-nlen) == needle) end end return false end function string.explode(s, pattern, plain) if (pattern == '') then return false end local pos = 0 local arr = { } for st,sp in function() return s:find(pattern, pos, plain) end do table.insert(arr, s:sub(pos, st-1)) pos = sp + 1 end table.insert(arr, s:sub(pos)) return arr end function string.findlast(s, pattern, plain) local curr = 0 repeat local next = s:find(pattern, curr + 1, plain) if (next) then curr = next end until (not next) if (curr > 0) then return curr end end function string.startswith(haystack, needle) return (haystack:find(needle, 1, true) == 1) end-- function table.contains(t, value) for _,v in pairs(t) do if (v == value) then return true end end return false end function table.extract(arr, fname) local result = { } for _,v in ipairs(arr) do table.insert(result, v[fname]) end return result end function table.implode(arr, before, after, between) local result = "" for _,v in ipairs(arr) do if (result ~= "" and between) then result = result .. between end result = result .. before .. v .. after end return result end function table.join(...) local result = { } for _,t in ipairs(arg) do if type(t) == "table" then for _,v in ipairs(t) do table.insert(result, v) end else table.insert(result, t) end end return result end function table.translate(arr, translation) local result = { } for _, value in ipairs(arr) do local tvalue if type(translation) == "function" then tvalue = translation(value) else tvalue = translation[value] end if (tvalue) then table.insert(result, tvalue) end end return result end -- _SOLUTIONS = { } _TEMPLATES = { } premake = { } premake.actions = { } premake.options = { } local builtin_dofile = dofile function dofile(fname) -- remember the current working directory; I'll restore it shortly local oldcwd = os.getcwd() -- if the file doesn't exist, check the search path if (not os.isfile(fname)) then local path = os.pathsearch(fname, _OPTIONS["scripts"], os.getenv("PREMAKE_PATH")) if (path) then fname = path.."/"..fname end end -- use the absolute path to the script file, to avoid any file name -- ambiguity if an error should arise fname = path.getabsolute(fname) -- switch the working directory to the new script location local newcwd = path.getdirectory(fname) os.chdir(newcwd) -- run the chunk. How can I catch variable return values? local a, b, c, d, e, f = builtin_dofile(fname) -- restore the previous working directory when done os.chdir(oldcwd) return a, b, c, d, e, f end function iif(expr, trueval, falseval) if (expr) then return trueval else return falseval end end function include(fname) return dofile(fname .. "/premake4.lua") end local builtin_open = io.open function io.open(fname, mode) if (mode) then if (mode:find("w")) then local dir = path.getdirectory(fname) ok, err = os.mkdir(dir) if (not ok) then error(err, 0) end end end return builtin_open(fname, mode) end function printf(msg, ...) print(string.format(msg, unpack(arg))) end local builtin_type = type function type(t) local mt = getmetatable(t) if (mt) then if (mt.__type) then return mt.__type end end return builtin_type(t) end -- local function literal(str) local code = "" for line in str:gmatch("[^\n]*") do if (line:len() > 0) then code = code .. "io.write[=[" .. line .. "]=]" else code = code .. "io.write(eol)\n" end end return code:sub(1, -15) end function premake.encodetemplate(tmpl) code = "" -- normalize line endings tmpl = tmpl:gsub("\r\n", "\n") while (true) do -- find an escaped block start, finish = tmpl:find("<%%.-%%>") if (not start) then break end local before = tmpl:sub(1, start - 1) local after = tmpl:sub(finish + 1) -- get the block type and contents local block local isexpr = (tmpl:sub(start + 2, start + 2) == "=") if (isexpr) then block = tmpl:sub(start + 3, finish - 2) else block = tmpl:sub(start + 2, finish - 2) end -- if a statement block, strip out everything else on that line if (not isexpr) then finish = before:findlast("\n", true) if (finish) then before = before:sub(1, finish) else before = nil end start = after:find("\n", 1, true) if (start) then after = after:sub(start + 1) end end -- output everything before the block if (before) then code = code .. literal(before) end -- output the block itself if (isexpr) then code = code .. "io.write(" .. block .. ")" else code = code .. block .. "\n" end -- do it again, with everything after the block tmpl = after end -- tack on everything after the last block code = code .. literal(tmpl) return code end function premake.loadtemplatestring(name, str) local code = premake.encodetemplate(str) local fn, msg = loadstring("return function (this) eol='\\n';" .. code .. " end", name) if (not fn) then error(msg, 0) end return fn() end function premake.getoutputname(this, namespec) local fname if (type(namespec) == "function") then fname = namespec(this) else fname = this.name .. namespec end return path.join(this.location, fname) end function premake.loadtemplatefile(fname) local f = io.open(fname, "rb") local tmpl = f:read("*a") f:close() return premake.loadtemplatestring(path.getname(fname), tmpl) end -- function premake.eachconfig(prj) -- I probably have the project root config, rather than the actual project if prj.project then prj = prj.project end local i = 0 local t = prj.solution.configurations return function () i = i + 1 if (i <= #t) then return prj.__configs[t[i]] end end end function premake.eachfile(prj) -- project root config contains the file config list if not prj.project then prj = premake.getconfig(prj) end local i = 0 local t = prj.files return function () i = i + 1 if (i <= #t) then return prj.__fileconfigs[t[i]] end end end function premake.eachproject(sln) local i = 0 return function () i = i + 1 if (i <= #sln.projects) then local prj = sln.projects[i] local cfg = premake.getconfig(prj) cfg.name = prj.name cfg.blocks = prj.blocks return cfg end end end function premake.esc(value) if (type(value) == "table") then local result = { } for _,v in ipairs(value) do table.insert(result, premake.esc(v)) end return result else value = value:gsub('&', "&") value = value:gsub('"', """) value = value:gsub("'", "'") value = value:gsub('<', "<") value = value:gsub('>', ">") value = value:gsub('\r', " ") value = value:gsub('\n', " ") return value end end function premake.findproject(name) name = name:lower() for _, sln in ipairs(_SOLUTIONS) do for _, prj in ipairs(sln.projects) do if (prj.name:lower() == name) then return prj end end end end function premake.findfile(prj, extension) for _, fname in ipairs(prj.files) do if fname:endswith(extension) then return fname end end end function premake.getconfig(prj, cfgname) -- might have the root configuration, rather than the actual project if prj.project then prj = prj.project end return prj.__configs[cfgname or ""] end function premake.getdependencies(cfg) local results = { } for _, link in ipairs(cfg.links) do local prj = premake.findproject(link) if (prj) then table.insert(results, prj) end end return results end function premake.getlinks(cfg, kind, part) -- if I'm building a list of link directories, include libdirs local result = iif (part == "directory" and kind == "all", cfg.libdirs, {}) -- am I getting links for a configuration or a project? local cfgname = iif(cfg.name == cfg.project.name, "", cfg.name) local function canlink(source, target) if (target.kind ~= "SharedLib" and target.kind ~= "StaticLib") then return false end if (source.language == "C" or source.language == "C++") then if (target.language ~= "C" and target.language ~= "C++") then return false end return true elseif (source.language == "C#") then if (target.language ~= "C#") then return false end return true end end for _, link in ipairs(cfg.links) do local item -- is this a sibling project? local prj = premake.findproject(link) if prj and kind ~= "system" then local prjcfg = premake.getconfig(prj, cfgname) if kind == "dependencies" or canlink(cfg, prjcfg) then if (part == "directory") then item = path.rebase(prjcfg.linktarget.directory, prjcfg.location, cfg.location) elseif (part == "basename") then item = prjcfg.linktarget.basename elseif (part == "fullpath") then item = path.rebase(prjcfg.linktarget.fullpath, prjcfg.location, cfg.location) elseif (part == "object") then item = prjcfg end end elseif not prj and (kind == "system" or kind == "all") then if (part == "directory") then local dir = path.getdirectory(link) if (dir ~= ".") then item = dir end elseif (part == "fullpath") then item = link if premake.actions[_ACTION].targetstyle == "windows" then item = item .. iif(cfg.language == "C" or cfg.language == "C++", ".lib", ".dll") end if item:find("/", nil, true) then item = path.getrelative(cfg.basedir, item) end else item = link end end if item then if premake.actions[_ACTION].targetstyle == "windows" and part ~= "object" then item = path.translate(item, "\\") end if not table.contains(result, item) then table.insert(result, item) end end end return result end function premake.gettarget(cfg, direction, style, os) -- normalize the arguments if not os then os = _G["os"].get() end if (os == "bsd") then os = "linux" end local kind = cfg.kind if (cfg.language == "C" or cfg.language == "C++") then -- On Windows, shared libraries link against a static import library if (style == "windows" or os == "windows") and kind == "SharedLib" and direction == "link" then kind = "StaticLib" end -- Linux name conventions only apply to static libs on windows (by user request) if (style == "linux" and os == "windows" and kind ~= "StaticLib") then style = "windows" end elseif (cfg.language == "C#") then -- .NET always uses Windows naming conventions style = "windows" end -- Initialize the target components local field = iif(direction == "build", "target", "implib") local name = cfg[field.."name"] or cfg.targetname or cfg.project.name local dir = cfg[field.."dir"] or cfg.targetdir or path.getrelative(cfg.location, cfg.basedir) local prefix = "" local suffix = "" -- If using an import library and "NoImportLib" flag is set, library will be in objdir if cfg.kind == "SharedLib" and kind == "StaticLib" and cfg.flags.NoImportLib then dir = cfg.objectsdir end if style == "windows" then if kind == "ConsoleApp" or kind == "WindowedApp" then suffix = ".exe" elseif kind == "SharedLib" then suffix = ".dll" elseif kind == "StaticLib" then suffix = ".lib" end elseif style == "linux" then if (kind == "WindowedApp" and os == "macosx") then dir = path.join(dir, name .. ".app/Contents/MacOS") elseif kind == "SharedLib" then prefix = "lib" suffix = ".so" elseif kind == "StaticLib" then prefix = "lib" suffix = ".a" end end prefix = cfg[field.."prefix"] or cfg.targetprefix or prefix suffix = cfg[field.."extension"] or cfg.targetextension or suffix local result = { } result.basename = name result.name = prefix .. name .. suffix result.directory = dir result.fullpath = path.join(result.directory, result.name) return result end local function walksources(prj, files, fn, group, nestlevel, finished) local grouplen = group:len() local gname = iif(group:endswith("/"), group:sub(1, -2), group) -- open this new group if (nestlevel >= 0) then fn(prj, gname, "GroupStart", nestlevel) end -- scan the list of files for items which belong in this group for _,fname in ipairs(files) do if (fname:startswith(group)) then -- is there a subgroup within this item? local _,split = fname:find("[^\.]/", grouplen + 1) if (split) then local subgroup = fname:sub(1, split) if (not finished[subgroup]) then finished[subgroup] = true walksources(prj, files, fn, subgroup, nestlevel + 1, finished) end end end end -- process all files that belong in this group for _,fname in ipairs(files) do if (fname:startswith(group) and not fname:find("[^\.]/", grouplen + 1)) then fn(prj, fname, "GroupItem", nestlevel + 1) end end -- close the group if (nestlevel >= 0) then fn(prj, gname, "GroupEnd", nestlevel) end end function premake.walksources(prj, files, fn) walksources(prj, files, fn, "", -1, {}) end -- -- do not copy these fields into the configurations local nocopy = { blocks = true, keywords = true, projects = true, } -- leave these paths as absolute, rather than converting to project relative local nofixup = { basedir = true, location = true, } function premake.getactiveterms() local terms = { _ACTION:lower(), os.get() } -- add option keys or values for key, value in pairs(_OPTIONS) do if value ~= "" then table.insert(terms, value:lower()) else table.insert(terms, key:lower()) end end return terms end function premake.escapekeyword(keyword) keyword = keyword:gsub("([%.%-%^%$%(%)%%])", "%%%1") if keyword:find("**", nil, true) then keyword = keyword:gsub("%*%*", ".*") else keyword = keyword:gsub("%*", "[^/]*") end return keyword:lower() end function premake.iskeywordmatch(keyword, terms) -- is it negated? if keyword:startswith("not ") then return not premake.iskeywordmatch(keyword:sub(5), terms) end for _, word in ipairs(keyword:explode(" or ")) do local pattern = "^" .. word .. "$" for termkey, term in pairs(terms) do if term:match(pattern) then return termkey end end end end function premake.iskeywordsmatch(keywords, terms) local hasrequired = false for _, keyword in ipairs(keywords) do local matched = premake.iskeywordmatch(keyword, terms) if not matched then return false end if matched == "required" then hasrequired = true end end if terms.required and not hasrequired then return false else return true end end local function copyfields(cfg, this) for field,value in pairs(this) do if (not nocopy[field]) then if (type(value) == "table") then if (not cfg[field]) then cfg[field] = { } end cfg[field] = table.join(cfg[field], value) else cfg[field] = value end end end end local function buildconfig(prj, terms) -- fields are copied first from the solution, then the solution's configs, -- then from the project, then the project's configs. Each can overwrite -- or add to the values set previously. The objdir field gets special -- treatment, in order to provide a project-level default and still enable -- solution-level overrides local cfg = { } copyfields(cfg, prj.solution) for _,blk in ipairs(prj.solution.blocks) do if (premake.iskeywordsmatch(blk.keywords, terms)) then copyfields(cfg, blk) end end copyfields(cfg, prj) for _,blk in ipairs(prj.blocks) do if (premake.iskeywordsmatch(blk.keywords, terms)) then copyfields(cfg, blk) end end return cfg end local function buildprojectconfig(prj, cfgname) -- create the base configuration, flattening the list of objects and -- filtering out settings which do not match the current environment local terms = premake.getactiveterms() terms.config = (cfgname or ""):lower() local cfg = buildconfig(prj, terms) cfg.name = cfgname cfg.project = prj -- set the project location, if not already set cfg.location = cfg.location or cfg.basedir -- remove excluded files from the file list local files = { } for _, fname in ipairs(cfg.files) do local excluded = false for _, exclude in ipairs(cfg.excludes) do excluded = (fname == exclude) if (excluded) then break end end if (not excluded) then table.insert(files, fname) end end cfg.files = files -- fixup the data for name, field in pairs(premake.fields) do -- convert absolute paths to project relative if (field.kind == "path" or field.kind == "dirlist" or field.kind == "filelist") and (not nofixup[name]) then if type(cfg[name]) == "table" then for i,p in ipairs(cfg[name]) do cfg[name][i] = path.getrelative(prj.location, p) end else if cfg[name] then cfg[name] = path.getrelative(prj.location, cfg[name]) end end end -- re-key flag fields for faster lookups if field.isflags then local values = cfg[name] for _, flag in ipairs(values) do values[flag] = true end end end -- build configuration objects for all files cfg.__fileconfigs = { } for _, fname in ipairs(cfg.files) do terms.required = fname:lower() local fcfg = buildconfig(prj, terms) fcfg.name = fname -- add indexed by name and integer cfg.__fileconfigs[fname] = fcfg table.insert(cfg.__fileconfigs, fcfg) end return cfg end local function buildtargets(cfg) -- deduce and store the applicable tool for this configuration if cfg.language == "C" or cfg.language == "C++" then if _OPTIONS.cc then cfg.tool = premake[_OPTIONS.cc] end elseif cfg.language == "C#" then if _OPTIONS.dotnet then cfg.tool = premake[_OPTIONS.dotnet] end end -- deduce the target and path style from the current action/tool pairing local action = premake.actions[_ACTION] local targetstyle = action.targetstyle or "linux" if (cfg.tool) then targetstyle = cfg.tool.targetstyle or targetstyle end -- build a unique objects directory local function getbasedir(cfg) return path.join(cfg.location, cfg.objdir or cfg.project.objdir or "obj") end local function getuniquedir(cfg) local thisbase = getbasedir(cfg) local thislocal = path.join(thisbase, cfg.name) local isbasematched = false for _, sln in ipairs(_SOLUTIONS) do for _, prj in ipairs(sln.projects) do for _, thatcfg in pairs(prj.__configs) do if thatcfg ~= cfg then local thatbase = getbasedir(thatcfg) if thisbase == thatbase then isbasematched = true if thislocal == path.join(thatbase, thatcfg.name) then return path.join(thislocal, cfg.project.name) end end end end end end return iif(isbasematched, thislocal, thisbase) end cfg.objectsdir = path.getrelative(cfg.location, getuniquedir(cfg)) -- precompute the target names and paths cfg.buildtarget = premake.gettarget(cfg, "build", targetstyle) cfg.linktarget = premake.gettarget(cfg, "link", targetstyle) -- translate the paths as appropriate local pathstyle = action.pathstyle or targetstyle if (pathstyle == "windows") then cfg.buildtarget.directory = path.translate(cfg.buildtarget.directory, "\\") cfg.buildtarget.fullpath = path.translate(cfg.buildtarget.fullpath, "\\") cfg.linktarget.directory = path.translate(cfg.linktarget.directory, "\\") cfg.linktarget.fullpath = path.translate(cfg.linktarget.fullpath, "\\") cfg.objectsdir = path.translate(cfg.objectsdir, "\\") end end function premake.buildconfigs() -- walk the object tree once and flatten the configurations for _, sln in ipairs(_SOLUTIONS) do for _, prj in ipairs(sln.projects) do prj.__configs = { } prj.__configs[""] = buildprojectconfig(prj) for _, name in ipairs(sln.configurations) do prj.__configs[name] = buildprojectconfig(prj, name) end end end -- walk it again and build the targets and unique directories for _, sln in ipairs(_SOLUTIONS) do for _, prj in ipairs(sln.projects) do for _, cfg in pairs(prj.__configs) do buildtargets(cfg) end end end end -- premake.fields = { basedir = { kind = "path", scope = "container", }, buildaction = { kind = "string", scope = "config", allowed = { "Compile", "Copy", "Embed", "None" } }, buildoptions = { kind = "list", scope = "config", }, configurations = { kind = "list", scope = "solution", }, defines = { kind = "list", scope = "config", }, excludes = { kind = "filelist", scope = "config", }, files = { kind = "filelist", scope = "config", }, flags = { kind = "list", scope = "config", isflags = true, allowed = { "ExtraWarnings", "FatalWarnings", "Managed", "NativeWChar", "No64BitChecks", "NoEditAndContinue", "NoExceptions", "NoFramePointer", "NoImportLib", "NoManifest", "NoNativeWChar", "NoPCH", "NoRTTI", "Optimize", "OptimizeSize", "OptimizeSpeed", "SEH", "StaticRuntime", "Symbols", "Unicode", "Unsafe", "WinMain" } }, implibdir = { kind = "path", scope = "config", }, implibextension = { kind = "string", scope = "config", }, implibname = { kind = "string", scope = "config", }, implibprefix = { kind = "string", scope = "config", }, includedirs = { kind = "dirlist", scope = "config", }, kind = { kind = "string", scope = "config", allowed = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" } }, language = { kind = "string", scope = "container", allowed = { "C", "C++", "C#" } }, libdirs = { kind = "dirlist", scope = "config", }, linkoptions = { kind = "list", scope = "config", }, links = { kind = "list", scope = "config", allowed = function(value) -- if library name contains a '/' then treat it as a path to a local file if value:find('/', nil, true) then value = path.getabsolute(value) end return value end }, location = { kind = "path", scope = "container", }, objdir = { kind = "path", scope = "config", }, pchheader = { kind = "path", scope = "config", }, pchsource = { kind = "path", scope = "config", }, postbuildcommands = { kind = "list", scope = "config", }, prebuildcommands = { kind = "list", scope = "config", }, prelinkcommands = { kind = "list", scope = "config", }, resdefines = { kind = "list", scope = "config", }, resincludedirs = { kind = "dirlist", scope = "config", }, resoptions = { kind = "list", scope = "config", }, targetdir = { kind = "path", scope = "config", }, targetextension = { kind = "string", scope = "config", }, targetname = { kind = "string", scope = "config", }, targetprefix = { kind = "string", scope = "config", }, uuid = { kind = "string", scope = "container", allowed = function(value) local ok = true if (#value ~= 36) then ok = false end for i=1,36 do local ch = value:sub(i,i) if (not ch:find("[ABCDEFabcdef0123456789-]")) then ok = false end end if (value:sub(9,9) ~= "-") then ok = false end if (value:sub(14,14) ~= "-") then ok = false end if (value:sub(19,19) ~= "-") then ok = false end if (value:sub(24,24) ~= "-") then ok = false end if (not ok) then return nil, "invalid UUID" end return value:upper() end }, } local function checkvalue(value, allowed) if (allowed) then if (type(allowed) == "function") then return allowed(value) else for _,v in ipairs(allowed) do if (value:lower() == v:lower()) then return v end end return nil, "invalid value '" .. value .. "'" end else return value end end function premake.getobject(t) local container if (t == "container" or t == "solution") then container = premake.CurrentContainer else container = premake.CurrentConfiguration end if t == "solution" then if type(container) == "project" then container = container.solution end if type(container) ~= "solution" then container = nil end end local msg if (not container) then if (t == "container") then msg = "no active solution or project" elseif (t == "solution") then msg = "no active solution" else msg = "no active solution, project, or configuration" end end return container, msg end function premake.setarray(ctype, fieldname, value, allowed) local container, err = premake.getobject(ctype) if (not container) then error(err, 4) end if (not container[fieldname]) then container[fieldname] = { } end local function doinsert(value, depth) if (type(value) == "table") then for _,v in ipairs(value) do doinsert(v, depth + 1) end else value, err = checkvalue(value, allowed) if (not value) then error(err, depth) end table.insert(container[fieldname], value) end end if (value) then doinsert(value, 5) end return container[fieldname] end local function domatchedarray(ctype, fieldname, value, matchfunc) local result = { } function makeabsolute(value) if (type(value) == "table") then for _,item in ipairs(value) do makeabsolute(item) end else if value:find("*") then makeabsolute(matchfunc(value)) else table.insert(result, path.getabsolute(value)) end end end makeabsolute(value) return premake.setarray(ctype, fieldname, result) end function premake.setdirarray(ctype, fieldname, value) return domatchedarray(ctype, fieldname, value, os.matchdirs) end function premake.setfilearray(ctype, fieldname, value) return domatchedarray(ctype, fieldname, value, os.matchfiles) end function premake.setstring(ctype, fieldname, value, allowed) -- find the container for this value local container, err = premake.getobject(ctype) if (not container) then error(err, 4) end -- if a value was provided, set it if (value) then value, err = checkvalue(value, allowed) if (not value) then error(err, 4) end container[fieldname] = value end return container[fieldname] end local function accessor(name, value) local kind = premake.fields[name].kind local scope = premake.fields[name].scope local allowed = premake.fields[name].allowed if (kind == "string") then return premake.setstring(scope, name, value, allowed) elseif (kind == "path") then if value then value = path.getabsolute(value) end return premake.setstring(scope, name, value) elseif (kind == "list") then return premake.setarray(scope, name, value, allowed) elseif (kind == "dirlist") then return premake.setdirarray(scope, name, value) elseif (kind == "filelist") then return premake.setfilearray(scope, name, value) end end for name,_ in pairs(premake.fields) do _G[name] = function(value) return accessor(name, value) end end function configuration(keywords) if not keywords then return premake.CurrentConfiguration end local container, err = premake.getobject("container") if (not container) then error(err, 2) end local cfg = { } table.insert(container.blocks, cfg) premake.CurrentConfiguration = cfg -- create a keyword list using just the indexed keyword items cfg.keywords = { } for _, word in ipairs(table.join({}, keywords)) do table.insert(cfg.keywords, premake.escapekeyword(word)) end -- if file patterns are specified, convert them to Lua patterns and add them too if keywords.files then for _, pattern in ipairs(table.join({}, keywords.files)) do pattern = pattern:gsub("%.", "%%.") if pattern:find("**", nil, true) then pattern = pattern:gsub("%*%*", ".*") else pattern = pattern:gsub("%*", "[^/]*") end table.insert(cfg.keywords, "^" .. pattern .. "$") end end -- initialize list-type fields to empty tables for name, field in pairs(premake.fields) do if (field.kind ~= "string" and field.kind ~= "path") then cfg[name] = { } end end return cfg end function project(name) if not name then return iif(type(premake.CurrentContainer) == "project", premake.CurrentContainer, nil) end -- identify the parent solution local sln if (type(premake.CurrentContainer) == "project") then sln = premake.CurrentContainer.solution else sln = premake.CurrentContainer end if (type(sln) ~= "solution") then error("no active solution", 2) end -- if this is a new project, create it premake.CurrentContainer = sln.projects[name] if (not premake.CurrentContainer) then local prj = { } premake.CurrentContainer = prj -- add to master list keyed by both name and index table.insert(sln.projects, prj) sln.projects[name] = prj -- attach a type setmetatable(prj, { __type = "project", }) prj.solution = sln prj.name = name prj.basedir = os.getcwd() prj.location = prj.basedir prj.uuid = os.uuid() prj.blocks = { } end -- add an empty, global configuration to the project configuration { } return premake.CurrentContainer end function solution(name) if not name then if type(premake.CurrentContainer) == "project" then return premake.CurrentContainer.solution else return premake.CurrentContainer end end premake.CurrentContainer = _SOLUTIONS[name] if (not premake.CurrentContainer) then local sln = { } premake.CurrentContainer = sln -- add to master list keyed by both name and index table.insert(_SOLUTIONS, sln) _SOLUTIONS[name] = sln -- attach a type setmetatable(sln, { __type="solution" }) sln.name = name sln.location = os.getcwd() sln.projects = { } sln.blocks = { } sln.configurations = { } end -- add an empty, global configuration configuration { } return premake.CurrentContainer end -- local requiredactionfields = { "description", "trigger", } local requiredoptionfields = { "description", "trigger" } function newaction(a) -- some sanity checking local missing for _, field in ipairs(requiredactionfields) do if (not a[field]) then missing = field end end if (missing) then error("action needs a " .. missing, 2) end -- add it to the master list premake.actions[a.trigger] = a end function newoption(opt) -- some sanity checking local missing for _, field in ipairs(requiredoptionfields) do if (not opt[field]) then missing = field end end if (missing) then error("action needs a " .. missing, 2) end -- add it to the master list premake.options[opt.trigger] = opt end newoption { trigger = "cc", value = "compiler", description = "Choose a C/C++ compiler set", allowed = { { "gcc", "GNU GCC compiler (gcc/g++)" }, { "ow", "OpenWatcom compiler" }, } } newoption { trigger = "dotnet", value = "value", description = "Choose a .NET compiler set", allowed = { { "ms", "Microsoft .NET (csc)" }, { "mono", "Novell Mono (mcs)" }, { "pnet", "Portable.NET (cscc)" }, } } newoption { trigger = "file", value = "filename", description = "Process the specified Premake script file" } newoption { trigger = "help", description = "Display this information" } newoption { trigger = "os", value = "value", description = "Generate files for a different operating system", allowed = { { "bsd", "OpenBSD, NetBSD, or FreeBSD" }, { "linux", "Linux" }, { "macosx", "Apple Mac OS X" }, { "windows", "Microsoft Windows" }, } } newoption { trigger = "scripts", value = "path", description = "Search for additional scripts on the given path" } newoption { trigger = "version", description = "Display version information" } -- premake.csc = { } local flags = { FatalWarning = "/warnaserror", Optimize = "/optimize", OptimizeSize = "/optimize", OptimizeSpeed = "/optimize", Symbols = "/debug", Unsafe = "/unsafe" } function premake.csc.getbuildaction(fcfg) local ext = path.getextension(fcfg.name):lower() if fcfg.buildaction == "Compile" or ext == ".cs" then return "Compile" elseif fcfg.buildaction == "Embed" or ext == ".resx" then return "EmbeddedResource" elseif fcfg.buildaction == "Copy" or ext == ".asax" or ext == ".aspx" then return "Content" else return "None" end end function premake.csc.getcompilervar(cfg) if (_OPTIONS.dotnet == "ms") then return "csc" elseif (_OPTIONS.dotnet == "mono") then return "gmcs" else return "cscc" end end function premake.csc.getflags(cfg) local result = table.translate(cfg.flags, flags) return result end function premake.csc.getkind(cfg) if (cfg.kind == "ConsoleApp") then return "Exe" elseif (cfg.kind == "WindowedApp") then return "WinExe" elseif (cfg.kind == "SharedLib") then return "Library" end end-- premake.gcc = { } premake.targetstyle = "linux" local cflags = { ExtraWarnings = "-Wall", FatalWarning = "-Werror", NoFramePointer = "-fomit-frame-pointer", Optimize = "-O2", OptimizeSize = "-Os", OptimizeSpeed = "-O3", Symbols = "-g", } local cxxflags = { NoExceptions = "--no-exceptions", NoRTTI = "--no-rtti", } function premake.gcc.getcppflags(cfg) -- if $(ARCH) contains multiple targets, then disable the incompatible automatic -- dependency generation. This allows building universal binaries on MacOSX, sorta. return "$(if $(word 2, $(ARCH)), , -MMD)" end function premake.gcc.getcflags(cfg) local result = table.translate(cfg.flags, cflags) if (cfg.kind == "SharedLib" and not os.is("windows")) then table.insert(result, "-fPIC") end return result end function premake.gcc.getcxxflags(cfg) local result = table.translate(cfg.flags, cxxflags) return result end function premake.gcc.getldflags(cfg) local result = { } if (cfg.kind == "SharedLib") then if os.is("macosx") then result = table.join(result, { "-dynamiclib", "-flat_namespace" }) else table.insert(result, "-shared") end -- create import library for DLLs under Windows if (os.is("windows") and not cfg.flags.NoImportLib) then table.insert(result, '-Wl,--out-implib="'..premake.gettarget(cfg, "link", "linux").fullpath..'"') end end if (os.is("windows") and cfg.kind == "WindowedApp") then table.insert(result, "-mwindows") end -- OS X has a bug, see http://lists.apple.com/archives/Darwin-dev/2006/Sep/msg00084.html if (not cfg.flags.Symbols) then if (os.is("macosx")) then table.insert(result, "-Wl,-x") else table.insert(result, "-s") end end return result end function premake.gcc.getlinkflags(cfg) local result = { } for _, value in ipairs(premake.getlinks(cfg, "all", "directory")) do table.insert(result, '-L' .. _MAKE.esc(value)) end for _, value in ipairs(premake.getlinks(cfg, "all", "basename")) do table.insert(result, '-l' .. _MAKE.esc(value)) end return result end function premake.gcc.getdefines(defines) local result = { } for _,def in ipairs(defines) do table.insert(result, '-D' .. def) end return result end function premake.gcc.getincludedirs(includedirs) local result = { } for _,dir in ipairs(includedirs) do table.insert(result, "-I" .. _MAKE.esc(dir)) end return result end -- premake.ow = { } premake.ow.targetstyle = "windows" local cflags = { ExtraWarnings = "-wx", FatalWarning = "-we", Optimize = "-ox", OptimizeSize = "-os", OptimizeSpeed = "-ot", Symbols = "-d2", } local cxxflags = { NoExceptions = "-xd", NoRTTI = "-xr", } function premake.ow.getcppflags(cfg) return "" end function premake.ow.getcflags(cfg) local result = table.translate(cfg.flags, cflags) if (cfg.flags.Symbols) then table.insert(result, "-hw") -- Watcom debug format for Watcom debugger end return result end function premake.ow.getcxxflags(cfg) local result = table.translate(cfg.flags, cxxflags) return result end function premake.ow.getldflags(cfg) local result = { } if (cfg.flags.Symbols) then table.insert(result, "op symf") end return result end function premake.ow.getlinkflags(cfg) local result = { } return result end function premake.ow.getdefines(defines) local result = { } for _,def in ipairs(defines) do table.insert(result, '-D' .. def) end return result end function premake.ow.getincludedirs(includedirs) local result = { } for _,dir in ipairs(includedirs) do table.insert(result, '-I "' .. dir .. '"') end return result end -- function premake.checkoptions() for key, value in pairs(_OPTIONS) do -- is this a valid option? local opt = premake.options[key] if (not opt) then return false, "invalid option '" .. key .. "'" end -- does it need a value? if (opt.value and value == "") then return false, "no value specified for option '" .. key .. "'" end -- is the value allowed? if (opt.allowed) then for _, match in ipairs(opt.allowed) do if (match[1] == value) then return true end end return false, "invalid value '" .. value .. "' for option '" .. key .. "'" end end return true end function premake.checkprojects() local action = premake.actions[_ACTION] for _, sln in ipairs(_SOLUTIONS) do -- every solution must have at least one project if (#sln.projects == 0) then return nil, "solution '" .. sln.name .. "' needs at least one project" end -- every solution must provide a list of configurations if (#sln.configurations == 0) then return nil, "solution '" .. sln.name .. "' needs configurations" end for prj in premake.eachproject(sln) do -- every project must have a language if (not prj.language) then return nil, "project '" ..prj.name .. "' needs a language" end -- and the action must support it if (action.valid_languages) then if (not table.contains(action.valid_languages, prj.language)) then return nil, "the " .. action.shortname .. " action does not support " .. prj.language .. " projects" end end for cfg in premake.eachconfig(prj) do -- every config must have a kind if (not cfg.kind) then return nil, "project '" ..prj.name .. "' needs a kind in configuration '" .. cfgname .. "'" end -- and the action must support it if (action.valid_kinds) then if (not table.contains(action.valid_kinds, cfg.kind)) then return nil, "the " .. action.shortname .. " action does not support " .. cfg.kind .. " projects" end end end end end return true end function premake.checktools() local action = premake.actions[_ACTION] if (not action.valid_tools) then return true end for tool, values in pairs(action.valid_tools) do if (_OPTIONS[tool]) then if (not table.contains(values, _OPTIONS[tool])) then return nil, "the " .. action.shortname .. " action does not support /" .. tool .. "=" .. _OPTIONS[tool] .. " (yet)" end else _OPTIONS[tool] = values[1] end end return true end -- function premake.showhelp() -- sort the lists of actions and options into alphabetical order actions = { } for name,_ in pairs(premake.actions) do table.insert(actions, name) end table.sort(actions) options = { } for name,_ in pairs(premake.options) do table.insert(options, name) end table.sort(options) -- display the basic usage printf("Premake %s, a build script generator", _PREMAKE_VERSION) printf(_PREMAKE_COPYRIGHT) printf("%s %s", _VERSION, _COPYRIGHT) printf("") printf("Usage: premake4 [options] action [arguments]") printf("") -- display all options printf("OPTIONS") printf("") for _,name in ipairs(options) do local opt = premake.options[name] local trigger = opt.trigger local description = opt.description if (opt.value) then trigger = trigger .. "=" .. opt.value end if (opt.allowed) then description = description .. "; one of:" end printf(" --%-15s %s", trigger, description) if (opt.allowed) then table.sort(opt.allowed, function(a,b) return a[1] < b[1] end) for _, value in ipairs(opt.allowed) do printf(" %-14s %s", value[1], value[2]) end end printf("") end -- display all actions printf("ACTIONS") printf("") for _,name in ipairs(actions) do printf(" %-17s %s", name, premake.actions[name].description) end printf("") -- see more printf("For additional information, see http://industriousone.com/premake") end -- local scriptfile = "premake4.lua" local shorthelp = "Type 'premake4 --help' for help" local versionhelp = "premake4 (Premake Build Script Generator) %s" local function doaction(name) local action = premake.actions[name] -- walk the session objects and generate files from the templates local function generatefiles(this, templates) if (not templates) then return end for _,tmpl in ipairs(templates) do local output = true if (tmpl[3]) then output = tmpl[3](this) end if (output) then local fname = path.getrelative(os.getcwd(), premake.getoutputname(this, tmpl[1])) printf("Generating %s...", fname) local f, err = io.open(fname, "wb") if (not f) then error(err, 0) end io.output(f) -- call the template function to generate the output tmpl[2](this) io.output():close() end end end for _,sln in ipairs(_SOLUTIONS) do generatefiles(sln, action.solutiontemplates) for prj in premake.eachproject(sln) do generatefiles(prj, action.projecttemplates) end end if (action.execute) then action.execute() end end function _premake_main(scriptpath) -- if running off the disk (in debug mode), load everything -- listed in _manifest.lua; the list divisions make sure -- everything gets initialized in the proper order. if (scriptpath) then local scripts, templates, actions = dofile(scriptpath .. "/_manifest.lua") -- core code first for _,v in ipairs(scripts) do dofile(scriptpath .. "/" .. v) end -- then the templates for _,v in ipairs(templates) do local name = path.getbasename(v) _TEMPLATES[name] = premake.loadtemplatefile(scriptpath .. "/" .. v) end -- finally the actions for _,v in ipairs(actions) do dofile(scriptpath .. "/" .. v) end end -- If there is a project script available, run it to get the -- project information, available options and actions, etc. local fname = _OPTIONS["file"] or scriptfile if (os.isfile(fname)) then dofile(fname) end -- Process special options if (_OPTIONS["version"]) then printf(versionhelp, _PREMAKE_VERSION) return 1 end if (_OPTIONS["help"]) then premake.showhelp() return 1 end -- If no action was specified, show a short help message if (not _ACTION) then print(shorthelp) return 1 end -- If there wasn't a project script I've got to bail now if (not os.isfile(fname)) then error("No Premake script ("..scriptfile..") found!", 2) end -- Validate the command-line arguments. This has to happen after the -- script has run to allow for project-specific options if (not premake.actions[_ACTION]) then error("Error: no such action '".._ACTION.."'", 0) end ok, err = premake.checkoptions() if (not ok) then error("Error: " .. err, 0) end -- Sanity check the current project setup ok, err = premake.checktools() if (not ok) then error("Error: " .. err, 0) end -- work-in-progress: build the configurations print("Building configurations...") premake.buildconfigs() ok, err = premake.checkprojects() if (not ok) then error("Error: " .. err, 0) end -- Hand over control to the action printf("Running action '%s'...", _ACTION) doaction(_ACTION) print("Done.") return 0 end _TEMPLATES.codeblocks_workspace=premake.loadtemplatestring('codeblocks_workspace',[[ <% for prj in premake.eachproject(this) do %> > <% for _,dep in ipairs(premake.getdependencies(prj)) do %> <% end %> <% end %> ]])_TEMPLATES.codeblocks_cbp=premake.loadtemplatestring('codeblocks_cbp',[[<% local cc = premake[_OPTIONS.cc] %> ]])_TEMPLATES.codelite_workspace=premake.loadtemplatestring('codelite_workspace',[[ <% for i,prj in ipairs(this.projects) do %> " /> <% end %> <% for _, cfgname in ipairs(this.configurations) do %> <% for _,prj in ipairs(this.projects) do %> <% end %> <% end %> ]])_TEMPLATES.codelite_project=premake.loadtemplatestring('codelite_project',[[ <% premake.walksources(this, this.files, _CODELITE.files) %> <% for cfg in premake.eachconfig(this) do %> " DebuggerType="GNU gdb debugger" Type="<%= _CODELITE.kind(cfg.kind) %>"> "/> "> <% for _,v in ipairs(cfg.includedirs) do %> <% end %> <% for _,v in ipairs(cfg.defines) do %> <% end %> "> <% for _,v in ipairs(premake.getlinks(cfg, "all", "directory")) do %> <% end %> <% for _,v in ipairs(premake.getlinks(cfg, "all", "basename")) do %> <% end %> <% if premake.findfile(cfg, ".rc") then %> <%= table.concat(cfg.resoptions, ";") %>"> <% for _,v in ipairs(table.join(cfg.includedirs, cfg.resincludedirs)) do %> <% end %> <% else %> <% end %> <% if #cfg.prebuildcommands > 0 then %> <% for _,v in ipairs(cfg.prebuildcommands) do %> <%= premake.esc(v) %> <% end %> <% end %> <% if #cfg.postbuildcommands > 0 then %> <% for _,v in ipairs(cfg.postbuildcommands) do %> <%= premake.esc(v) %> <% end %> <% end %> None <%end %> <% for _,cfgname in ipairs(this.configurations) do %> <% for _,dep in ipairs(premake.getdependencies(this)) do %> <% end %> <% end %> ]])_TEMPLATES.make_solution=premake.loadtemplatestring('make_solution',[[# <%= premake.actions[_ACTION].shortname %> solution makefile autogenerated by Premake # Usage: make [ config=config_name ] # Where {config_name} is one of: <%= table.implode(this.configurations, '"', '"', ', '):lower() %>. ifndef config config=<%= _MAKE.esc(this.configurations[1]:lower()) %> endif export config PROJECTS := <%= table.concat(_MAKE.esc(table.extract(this.projects, "name")), " ") %> .PHONY: all clean $(PROJECTS) all: $(PROJECTS) <% for _,prj in ipairs(this.projects) do %> <% for cfg in premake.eachconfig(prj) do %> ifeq ($(config),<%= _MAKE.esc(cfg.name:lower())%>) DEPENDENCIES := <%= table.concat(_MAKE.esc(table.extract(premake.getdependencies(cfg), "name")), " ") %> endif <% end %> <%= _MAKE.esc(prj.name) %>: ${DEPENDENCIES} @echo ==== Building <%= prj.name %> ==== @${MAKE} --no-print-directory -C <%=_MAKE.esc(path.getrelative(this.location, prj.location))%> -f <%=_MAKE.esc(_MAKE.getmakefilename(prj, true))%> <% end %> clean: <% for _,prj in ipairs(this.projects) do %> @${MAKE} --no-print-directory -C <%=_MAKE.esc(path.getrelative(this.location, prj.location))%> -f <%=_MAKE.esc(_MAKE.getmakefilename(prj, true))%> clean <% end %> ]])_TEMPLATES.make_cpp=premake.loadtemplatestring('make_cpp',[[<% local cc = premake[_OPTIONS.cc] %> # <%= premake.actions[_ACTION].shortname %> project makefile autogenerated by Premake ifndef config config=<%= _MAKE.esc(this.configurations[1]:lower()) %> endif ifndef verbose SILENT = @ endif <% for cfg in premake.eachconfig(this) do %> ifeq ($(config),<%= _MAKE.esc(cfg.name:lower())%>) TARGETDIR = <%= _MAKE.esc(cfg.buildtarget.directory) %> TARGET = $(TARGETDIR)/<%= _MAKE.esc(cfg.buildtarget.name) %> OBJDIR = <%= _MAKE.esc(cfg.objectsdir) %> DEFINES += <%= table.concat(cc.getdefines(cfg.defines), " ") %> INCLUDES += <%= table.concat(cc.getincludedirs(cfg.includedirs), " ") %> CPPFLAGS += <%= cc.getcppflags(cfg) %> $(DEFINES) $(INCLUDES) CFLAGS += $(CPPFLAGS) $(ARCH) <%= table.concat(table.join(cc.getcflags(cfg), cfg.buildoptions), " ") %> CXXFLAGS += $(CFLAGS) <%= table.concat(cc.getcxxflags(cfg), " ") %> LDFLAGS += <%= table.concat(table.join(cc.getldflags(cfg), cc.getlinkflags(cfg), cfg.linkoptions), " ") %> RESFLAGS += $(DEFINES) $(INCLUDES) <%= table.concat(table.join(cc.getdefines(cfg.resdefines), cc.getincludedirs(cfg.resincludedirs), cfg.resoptions), " ") %> LDDEPS += <%= table.concat(_MAKE.esc(premake.getlinks(cfg, "siblings", "fullpath")), " ") %> <% if cfg.kind == "StaticLib" then %> LINKCMD = ar -rcs $(TARGET) $(OBJECTS) <% else %> LINKCMD = $(<%= iif(cfg.language == "C", "CC", "CXX") %>) -o $(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(ARCH) <% end %> define PREBUILDCMDS <% if #cfg.prebuildcommands > 0 then %> @echo Running pre-build commands <%= table.implode(cfg.prebuildcommands, "", "", "\n\t") %> <% end %> endef define PRELINKCMDS <% if #cfg.prelinkcommands > 0 then %> @echo Running pre-link commands <%= table.implode(cfg.prelinkcommands, "", "", "\n\t") %> <% end %> endef define POSTBUILDCMDS <% if #cfg.postbuildcommands > 0 then %> @echo Running post-build commands <%= table.implode(cfg.postbuildcommands, "", "", "\n\t") %> <% end %> endef endif <% end %> OBJECTS := \ <% for _, file in ipairs(this.files) do %> <% if path.iscppfile(file) then %> $(OBJDIR)/<%= _MAKE.esc(path.getbasename(file)) %>.o \ <% end %> <% end %> RESOURCES := \ <% for _, file in ipairs(this.files) do %> <% if path.isresourcefile(file) then %> $(OBJDIR)/<%= _MAKE.esc(path.getbasename(file)) %>.res \ <% end %> <% end %> SHELLTYPE := msdos ifeq (,$(ComSpec)$(COMSPEC)) SHELLTYPE := posix endif ifeq (/bin,$(findstring /bin,$(SHELL))) SHELLTYPE := posix endif ifeq (posix,$(SHELLTYPE)) define MKDIR_RULE @echo Creating $@ $(SILENT) mkdir -p $@ endef else define MKDIR_RULE @echo Creating $@ $(SILENT) mkdir $(subst /,\\,$@) endef endif .PHONY: clean prebuild prelink <% if os.is("MacOSX") and this.kind == "WindowedApp" then %> all: $(TARGETDIR) $(OBJDIR) prebuild $(OBJECTS) $(RESOURCES) prelink $(TARGET) $(dir $(TARGETDIR))PkgInfo $(dir $(TARGETDIR))Info.plist <% else %> all: $(TARGETDIR) $(OBJDIR) prebuild $(OBJECTS) $(RESOURCES) prelink $(TARGET) <% end %> $(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) @echo Linking <%= this.name %> @$(LINKCMD) $(POSTBUILDCMDS) $(TARGETDIR): $(MKDIR_RULE) $(OBJDIR): $(MKDIR_RULE) <% if os.is("MacOSX") and this.kind == "WindowedApp" then %> $(dir $(TARGETDIR))PkgInfo: $(dir $(TARGETDIR))Info.plist: <% end %> clean: @echo Cleaning <%= this.name %> ifeq (posix,$(SHELLTYPE)) $(SILENT) rm -f $(TARGET) $(SILENT) rm -rf $(OBJDIR) else $(SILENT) if exist $(subst /,\\,$(TARGET)) del $(subst /,\\,$(TARGET)) $(SILENT) if exist $(subst /,\\,$(OBJDIR)) rmdir /s /q $(subst /,\\,$(OBJDIR)) endif prebuild: $(PREBUILDCMDS) prelink: $(PRELINKCMDS) <% for _, file in ipairs(this.files) do %> <% if path.iscppfile(file) then %> $(OBJDIR)/<%= _MAKE.esc(path.getbasename(file)) %>.o: <%= _MAKE.esc(file) %> @echo $(notdir $<) <% if (path.iscfile(file)) then %> $(SILENT) $(CC) $(CFLAGS) -o $@ -c $< <% else %> $(SILENT) $(CXX) $(CXXFLAGS) -o $@ -c $< <% end %> <% elseif (path.getextension(file) == ".rc") then %> $(OBJDIR)/<%= _MAKE.esc(path.getbasename(file)) %>.res: <%= _MAKE.esc(file) %> @echo $(notdir $<) $(SILENT) windres $< -O coff -o $@ $(RESFLAGS) <% end %> <% end %> -include $(OBJECTS:%.o=%.d) ]])_TEMPLATES.make_csharp=premake.loadtemplatestring('make_csharp',[[<% local csc = premake.csc -- -- Given a .resx resource file, builds the path to corresponding .resource -- file, matching the behavior and naming of Visual Studio. -- function getresourcefilename(cfg, fname) if path.getextension(fname) == ".resx" then local name = cfg.buildtarget.basename .. "." local dir = path.getdirectory(fname) if dir ~= "." then name = name .. path.translate(dir, ".") .. "." end return "$(OBJDIR)/" .. name .. path.getbasename(fname) .. ".resources" else return fname end end -- Do some processing up front: build a list of configuration-dependent libraries. -- Libraries that are built to a location other than $(TARGETDIR) will need to -- be copied so they can be found at runtime. local cfglibs = { } local cfgpairs = { } local anycfg for cfg in premake.eachconfig(this) do anycfg = cfg cfglibs[cfg] = premake.getlinks(cfg, "siblings", "fullpath") cfgpairs[cfg] = { } for _, fname in ipairs(cfglibs[cfg]) do if path.getdirectory(fname) ~= cfg.buildtarget.directory then cfgpairs[cfg]["$(TARGETDIR)/"..path.getname(fname)] = fname end end end -- sort the files into categories, based on their build action local sources = {} local embedded = { } local copypairs = { } for fcfg in premake.eachfile(this) do local action = csc.getbuildaction(fcfg) if action == "Compile" then table.insert(sources, fcfg.name) elseif action == "EmbeddedResource" then table.insert(embedded, fcfg.name) elseif action == "Content" then copypairs["$(TARGETDIR)/"..path.getname(fcfg.name)] = fcfg.name elseif path.getname(fcfg.name):lower() == "app.config" then copypairs["$(TARGET).config"] = fcfg.name end end -- Any assemblies that are on the library search paths should be copied -- to $(TARGETDIR) so they can be found at runtime local paths = table.translate(this.libdirs, function(v) return path.join(this.basedir, v) end) paths = table.join({this.basedir}, paths) for _, libname in ipairs(premake.getlinks(this, "system", "fullpath")) do local libdir = os.pathsearch(libname..".dll", unpack(paths)) if (libdir) then local target = "$(TARGETDIR)/"..path.getname(libname) local source = path.getrelative(this.basedir, path.join(libdir, libname))..".dll" copypairs[target] = source end end -- end of preprocessing -- %> # <%= premake.actions[_ACTION].shortname %> project makefile autogenerated by Premake ifndef config config=<%= _MAKE.esc(this.configurations[1]:lower()) %> endif ifndef verbose SILENT = @ endif ifndef CSC CSC=<%= csc.getcompilervar(this) %> endif ifndef RESGEN RESGEN=resgen endif <% for cfg in premake.eachconfig(this) do %> ifeq ($(config),<%= _MAKE.esc(cfg.name:lower())%>) TARGETDIR := <%= _MAKE.esc(cfg.buildtarget.directory) %> OBJDIR := <%= _MAKE.esc(cfg.objectsdir) %> DEPENDS := <%= table.concat(_MAKE.esc(premake.getlinks(cfg, "dependencies", "fullpath")), " ") %> REFERENCES := <%= table.implode(_MAKE.esc(cfglibs[cfg]), "/r:", "", " ") %> FLAGS += <%= table.concat(csc.getflags(cfg), " ") %> <%= table.implode(cfg.defines, "/d:", "", " ") %> define PREBUILDCMDS <% if #cfg.prebuildcommands > 0 then %> @echo Running pre-build commands <%= table.implode(cfg.prebuildcommands, "", "", "\n\t") %> <% end %> endef define PRELINKCMDS <% if #cfg.prelinkcommands > 0 then %> @echo Running pre-link commands <%= table.implode(cfg.prelinkcommands, "", "", "\n\t") %> <% end %> endef define POSTBUILDCMDS <% if #cfg.postbuildcommands > 0 then %> @echo Running post-build commands <%= table.implode(cfg.postbuildcommands, "", "", "\n\t") %> <% end %> endef endif <% end %> # To maintain compatibility with VS.NET, these values must be set at the project level TARGET = $(TARGETDIR)/<%= _MAKE.esc(this.buildtarget.name) %> FLAGS += /t:<%= csc.getkind(this):lower() %> <%= table.implode(_MAKE.esc(this.libdirs), "/lib:", "", " ") %> REFERENCES += <%= table.implode(_MAKE.esc(premake.getlinks(this, "system", "basename")), "/r:", ".dll", " ") %> SOURCES := \ <% for _, fname in ipairs(sources) do %> <%= _MAKE.esc(path.translate(fname)) %> \ <% end %> EMBEDFILES := \ <% for _, fname in ipairs(embedded) do %> <%= _MAKE.esc(getresourcefilename(this, fname)) %> \ <% end %> COPYFILES += \ <% for target, source in pairs(cfgpairs[anycfg]) do %> <%= _MAKE.esc(target) %> \ <% end %> <% for target, source in pairs(copypairs) do %> <%= _MAKE.esc(target) %> \ <% end %> SHELLTYPE := msdos ifeq (,$(ComSpec)$(COMSPEC)) SHELLTYPE := posix endif ifeq (/bin,$(findstring /bin,$(SHELL))) SHELLTYPE := posix endif ifeq (posix,$(SHELLTYPE)) define MKDIR_RULE @echo Creating $@ $(SILENT) mkdir -p $@ endef define COPY_RULE @echo Copying $(notdir $@) $(SILENT) cp -fR $^ $@ endef else define MKDIR_RULE @echo Creating $@ $(SILENT) mkdir $(subst /,\\,$@) endef define COPY_RULE @echo Copying $(notdir $@) $(SILENT) copy /Y $(subst /,\\,$^) $(subst /,\\,$@) endef endif .PHONY: clean prebuild prelink all: $(TARGETDIR) $(OBJDIR) prebuild $(EMBEDFILES) $(COPYFILES) prelink $(TARGET) $(TARGET): $(SOURCES) $(EMBEDFILES) $(DEPENDS) $(SILENT) $(CSC) /nologo /out:$@ $(FLAGS) $(REFERENCES) $(SOURCES) $(patsubst %,/resource:%,$(EMBEDFILES)) $(POSTBUILDCMDS) $(TARGETDIR): $(MKDIR_RULE) $(OBJDIR): $(MKDIR_RULE) clean: @echo Cleaning <%= this.name %> ifeq (posix,$(SHELLTYPE)) $(SILENT) rm -f $(TARGETDIR)/<%= this.buildtarget.basename %>.* $(COPYFILES) $(SILENT) rm -rf $(OBJDIR) else $(SILENT) if exist $(subst /,\\,$(TARGETDIR)/<%= this.buildtarget.basename %>.*) del $(subst /,\\,$(TARGETDIR)/<%= this.buildtarget.basename %>.*) <% for target, source in pairs(cfgpairs[anycfg]) do %> $(SILENT) if exist $(subst /,\\,<%= target %>) del $(subst /,\\,<%= target %>) <% end %> <% for target, source in pairs(copypairs) do %> $(SILENT) if exist $(subst /,\\,<%= target %>) del $(subst /,\\,<%= target %>) <% end %> $(SILENT) if exist $(subst /,\\,$(OBJDIR)) rmdir /s /q $(subst /,\\,$(OBJDIR)) endif prebuild: $(PREBUILDCMDS) prelink: $(PRELINKCMDS) # Per-configuration copied file rules <% for cfg in premake.eachconfig(this) do %> ifeq ($(config),<%= _MAKE.esc(cfg.name:lower())%>) <% for target, source in pairs(cfgpairs[cfg]) do %> <%= _MAKE.esc(target) %>: <%= _MAKE.esc(source) %> $(COPY_RULE) <% end %> endif <% end %> # Copied file rules <% for target, source in pairs(copypairs) do %> <%= _MAKE.esc(target) %>: <%= _MAKE.esc(source) %> $(COPY_RULE) <% end %> # Embedded file rules <% for _, fname in ipairs(embedded) do if path.getextension(fname) == ".resx" then %> <%= _MAKE.esc(getresourcefilename(this, fname)) %>: <%= _MAKE.esc(fname) %> $(SILENT) $(RESGEN) $^ $@ <% end end %> ]])_TEMPLATES.vs2002_solution=premake.loadtemplatestring('vs2002_solution',[[<% eol = "\r\n" %> Microsoft Visual Studio Solution File, Format Version 7.00 <% for prj in premake.eachproject(this) do %> Project("{<%=_VS.tool(prj)%>}") = "<%=prj.name%>", "<%=path.translate(path.getrelative(this.location, _VS.projectfile(prj)))%>", "{<%=prj.uuid%>}" EndProject <% end %> Global GlobalSection(SolutionConfiguration) = preSolution <% for i,cfgname in ipairs(this.configurations) do %> ConfigName.<%= i-1 %> = <%= cfgname %> <% end %> EndGlobalSection GlobalSection(ProjectDependencies) = postSolution <% for prj in premake.eachproject(this) do %> <% for i,dep in ipairs(premake.getdependencies(prj)) do %> {<%= prj.uuid %>}.<%= i - 1 %> = {<%= dep.uuid %>} <% end %> <% end %> EndGlobalSection GlobalSection(ProjectDependencies) = postSolution EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution <% for prj in premake.eachproject(this) do %> <% for i,cfgname in ipairs(this.configurations) do %> {<%=prj.uuid%>}.<%=cfgname%>.ActiveCfg = <%=cfgname%>|<%=_VS.arch(prj)%> {<%=prj.uuid%>}.<%=cfgname%>.Build.0 = <%=cfgname%>|<%=_VS.arch(prj)%> <% end %> <% end %> EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal ]])_TEMPLATES.vs2002_csproj=premake.loadtemplatestring('vs2002_csproj',[[<% eol = "\r\n" local csc = premake.csc -- -- Figure out what elements a particular file need in its item block, -- based on its build action and any related files in the project. -- function getelements(prj, action, fname) if action == "Compile" and fname:endswith(".cs") then return "SubTypeCode" end if action == "EmbeddedResource" and fname:endswith(".resx") then -- is there a matching *.cs file? local basename = fname:sub(1, -6) local testname = path.getname(basename .. ".cs") if premake.findfile(prj, testname) then return "Dependency", testname end end return "None" end -- end of preprocessing; template starts here -- %> " SchemaVersion = "<%= iif(_ACTION == "vs2002", "1.0", "2.0") %>" ProjectGuid = "{<%= this.uuid %>}" > NoStandardLibraries = "false" <% end %> OutputType = "<%= csc.getkind(this) %>" <% if _ACTION == "vs2003" then %> PreBuildEvent = "" PostBuildEvent = "" <% end %> RootNamespace = "<%= this.buildtarget.basename %>" <% if _ACTION == "vs2003" then %> RunPostBuildEvent = "OnBuildSuccess" <% end %> StartupObject = "" > <% for cfg in premake.eachconfig(this) do %> " BaseAddress = "285212672" CheckForOverflowUnderflow = "false" ConfigurationOverrideFile = "" DefineConstants = "<%= premake.esc(table.concat(cfg.defines, ";")) %>" DocumentationFile = "" DebugSymbols = "<%= iif(cfg.flags.Symbols, "true", "false") %>" FileAlignment = "4096" IncrementalBuild = "false" <% if _ACTION == "vs2003" then %> NoStdLib = "false" NoWarn = "" <% end %> Optimize = "<%= iif(cfg.flags.Optimize or cfg.flags.OptimizeSize or cfg.flags.OptimizeSpeed, "true", "false") %>" OutputPath = "<%= premake.esc(cfg.buildtarget.directory) %>" RegisterForComInterop = "false" RemoveIntegerChecks = "false" TreatWarningsAsErrors = "<%= iif(cfg.flags.FatalWarnings, "true", "false") %>" WarningLevel = "4" /> <% end %> <% for _, prj in ipairs(premake.getlinks(this, "siblings", "object")) do %> <% end %> <% for _, linkname in ipairs(premake.getlinks(this, "system", "fullpath")) do %> HintPath = "<%= path.translate(linkname, "\\") %>" <% end %> /> <% end %> <% for fcfg in premake.eachfile(this) do local action = csc.getbuildaction(fcfg) local fname = path.translate(premake.esc(fcfg.name), "\\") local elements, dependency = getelements(this, action, fcfg.name) %> DependentUpon = "<%= premake.esc(path.translate(dependency, "\\")) %>" <% end %> <% if elements == "SubTypeCode" then %> SubType = "Code" <% end %> /> <% end %> ]])_TEMPLATES.vs2002_csproj_user=premake.loadtemplatestring('vs2002_csproj_user',[[<% eol = "\r\n" local csc = premake.csc %> "> <% for cfg in premake.eachconfig(this) do %> <% end %> ]])_TEMPLATES.vs2003_solution=premake.loadtemplatestring('vs2003_solution',[[<% eol = "\r\n" %> Microsoft Visual Studio Solution File, Format Version 8.00 <% for prj in premake.eachproject(this) do %> Project("{<%=_VS.tool(prj)%>}") = "<%=prj.name%>", "<%=path.translate(path.getrelative(this.location, _VS.projectfile(prj)))%>", "{<%=prj.uuid%>}" <% local deps = premake.getdependencies(prj); if #deps > 0 then %> ProjectSection(ProjectDependencies) = postProject <% for _,dep in ipairs(deps) do %> {<%= dep.uuid %>} = {<%= dep.uuid %>} <% end %> EndProjectSection <% end %> EndProject <% end %> Global GlobalSection(SolutionConfiguration) = preSolution <% for i,cfgname in ipairs(this.configurations) do %> <%= cfgname %> = <%= cfgname %> <% end %> EndGlobalSection GlobalSection(ProjectDependencies) = postSolution EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution <% for prj in premake.eachproject(this) do %> <% for i,cfgname in ipairs(this.configurations) do %> {<%=prj.uuid%>}.<%=cfgname%>.ActiveCfg = <%=cfgname%>|<%=_VS.arch(prj)%> {<%=prj.uuid%>}.<%=cfgname%>.Build.0 = <%=cfgname%>|<%=_VS.arch(prj)%> <% end %> <% end %> EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal ]])_TEMPLATES.vs2005_solution=premake.loadtemplatestring('vs2005_solution',[[<% eol = "\r\n" %> <%= "\239\187\191" %> <% local hascpp, hasdotnet %> <% if _ACTION == "vs2005" then %> Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 <% elseif _ACTION == "vs2008" then %> Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 <% end %> <% for prj in premake.eachproject(this) do %> <% if (prj.language == "C" or prj.language == "C++") then hascpp = true end %> <% if (prj.language == "C#") then hasdotnet = true end %> Project("{<%=_VS.tool(prj)%>}") = "<%=prj.name%>", "<%=path.translate(path.getrelative(this.location, _VS.projectfile(prj)),"\\")%>", "{<%=prj.uuid%>}" <% local deps = premake.getdependencies(prj); if #deps > 0 then %> ProjectSection(ProjectDependencies) = postProject <% for _,dep in ipairs(deps) do %> {<%= dep.uuid %>} = {<%= dep.uuid %>} <% end %> EndProjectSection <% end %> EndProject <% end %> Global GlobalSection(SolutionConfigurationPlatforms) = preSolution <% for _, cfgname in ipairs(this.configurations) do %> <% if hasdotnet then %> <%= cfgname %>|Any CPU = <%= cfgname %>|Any CPU <% end; if hasdotnet and hascpp then %> <%= cfgname %>|Mixed Platforms = <%= cfgname %>|Mixed Platforms <% end; if hascpp then %> <%= cfgname %>|Win32 = <%= cfgname %>|Win32 <% end %> <% end %> EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution <% for prj in premake.eachproject(this) do %> <% for _, cfgname in ipairs(this.configurations) do %> <% if hasdotnet then %> {<%= prj.uuid %>}.<%= cfgname %>|Any CPU.ActiveCfg = <%= cfgname %>|<%= _VS.arch(prj) %> <% if (prj.language ~= "C" and prj.language ~= "C++") then %> {<%= prj.uuid %>}.<%= cfgname %>|Any CPU.Build.0 = <%= cfgname %>|<%= _VS.arch(prj) %> <% end %> <% end; if (hasdotnet and hascpp) then %> {<%= prj.uuid %>}.<%= cfgname %>|Mixed Platforms.ActiveCfg = <%= cfgname %>|<%= _VS.arch(prj) %> {<%= prj.uuid %>}.<%= cfgname %>|Mixed Platforms.Build.0 = <%= cfgname %>|<%= _VS.arch(prj) %> <% end; if (hascpp) then %> {<%= prj.uuid %>}.<%= cfgname %>|Win32.ActiveCfg = <%= cfgname %>|<%= _VS.arch(prj) %> <% if (prj.language == "C" or prj.language == "C++") then %> {<%= prj.uuid %>}.<%= cfgname %>|Win32.Build.0 = <%= cfgname %>|<%= _VS.arch(prj) %> <% end %> <% end %> <% end %> <% end %> EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal ]])_TEMPLATES.vs2005_csproj=premake.loadtemplatestring('vs2005_csproj',[[<% eol = "\r\n" local csc = premake.csc -- translate the action to format and tool versions local vsversion, toolversion if _ACTION == "vs2005" then vsversion = "8.0.50727" toolversion = nil elseif _ACTION == "vs2008" then vsversion = "9.0.50727" toolversion = "3.5" end -- -- Figure out what elements a particular source code file need in its item -- block, based on its build action and any related files in the project. -- function getelements(prj, action, fname) if action == "Compile" and fname:endswith(".cs") then if fname:endswith(".Designer.cs") then -- is there a matching *.cs file? local basename = fname:sub(1, -13) local testname = basename .. ".cs" if premake.findfile(prj, testname) then return "Dependency", testname end -- is there a matching *.resx file? testname = basename .. ".resx" if premake.findfile(prj, testname) then return "AutoGen", testname end else -- is there a *.Designer.cs file? local basename = fname:sub(1, -4) local testname = basename .. ".Designer.cs" if premake.findfile(prj, testname) then return "SubTypeForm" end end end if action == "EmbeddedResource" and fname:endswith(".resx") then -- is there a matching *.cs file? local basename = fname:sub(1, -6) local testname = path.getname(basename .. ".cs") if premake.findfile(prj, testname) then if premake.findfile(prj, basename .. ".Designer.cs") then return "DesignerType", testname else return "Dependency", testname end else -- is there a matching *.Designer.cs? testname = path.getname(basename .. ".Designer.cs") if premake.findfile(prj, testname) then return "AutoGenerated" end end end if action == "Content" then return "CopyNewest" end return "None" end -- end of preprocessing; template starts here -- %> <% if toolversion then %> <% else %> <% end %> <%= premake.esc(this.solution.configurations[1]) %> AnyCPU <%= vsversion %> 2.0 {<%= this.uuid %>} <%= csc.getkind(this) %> Properties <%= this.buildtarget.basename %> <%= this.buildtarget.basename %> <% for cfg in premake.eachconfig(this) do %> <% if cfg.flags.Symbols then %> true full <% else %> pdbonly <% end %> <%= iif(cfg.flags.Optimize or cfg.flags.OptimizeSize or cfg.flags.OptimizeSpeed, "true", "false") %> <%= cfg.buildtarget.directory %> <%= table.concat(premake.esc(cfg.defines), ";") %> prompt 4 <% if cfg.flags.Unsafe then %> true <% end %> <% if cfg.flags.FatalWarnings then %> true <% end %> <% end %> <% for _, prj in ipairs(premake.getlinks(this, "siblings", "object")) do %> "> {<%= prj.uuid %>} <%= premake.esc(prj.name) %> <% end %> <% for _, linkname in ipairs(premake.getlinks(this, "system", "basename")) do %> <% end %> <% for fcfg in premake.eachfile(this) do local action = csc.getbuildaction(fcfg) local fname = path.translate(premake.esc(fcfg.name), "\\") local elements, dependency = getelements(this, action, fcfg.name) if elements == "None" then %> <<%= action %> Include="<%= fname %>" /> <% else %> <<%= action %> Include="<%= fname %>"> <% if elements == "AutoGen" then %> True <% elseif elements == "AutoGenerated" then %> Designer ResXFileCodeGenerator <%= premake.esc(path.getbasename(fcfg.name)) %>.Designer.cs <% elseif elements == "SubTypeDesigner" then %> Designer <% elseif elements == "SubTypeForm" then %> Form <% elseif elements == "PreserveNewest" then %> PreserveNewest <% end %> <% if dependency then %> <%= path.translate(premake.esc(dependency), "\\") %> <% end %> > <% end end %> ]])_TEMPLATES.vs2005_csproj_user=premake.loadtemplatestring('vs2005_csproj_user',[[<% eol = "\r\n" %> <%= table.concat(table.translate(this.libdirs, function(v) return path.translate(path.getabsolute(this.location.."/"..v),"\\") end), ";") %> ]])_TEMPLATES.vs200x_vcproj=premake.loadtemplatestring('vs200x_vcproj',[[<% eol = "\r\n" %> Version="7.00" <% elseif _ACTION == "vs2003" then %> Version="7.10" <% elseif _ACTION == "vs2005" then %> Version="8.00" <% elseif _ACTION == "vs2008" then %> Version="9.00" <% end %> Name="<%= premake.esc(this.name) %>" ProjectGUID="{<%= this.uuid %>}" <% if _ACTION > "vs2003" then %> RootNamespace="<%= this.name %>" <% end %> Keyword="<%= iif(this.flags.Managed, "ManagedCProj", "Win32Proj") %>" > <% if _ACTION > "vs2003" then %> <% end %> <% for cfg in premake.eachconfig(this) do %> ManagedExtensions="true" <% end %> > <% for _,block in ipairs(_VS[_ACTION]) do %> <% if (block == "VCALinkTool") then %> <% elseif (block == "VCAppVerifierTool") then %> <% elseif (block == "VCAuxiliaryManagedWrapperGeneratorTool") then %> <% elseif (block == "VCBscMakeTool") then %> <% elseif (block == "VCCLCompilerTool") then %> 0 then %> AdditionalOptions="<%= table.concat(premake.esc(cfg.buildoptions), " ") %>" <% end %> Optimization="<%= _VS.optimization(cfg) %>" <% if cfg.flags.NoFramePointer then %> OmitFramePointers="<%= _VS.bool(true) %>" <% end %> <% if #cfg.includedirs > 0 then %> AdditionalIncludeDirectories="<%= table.concat(premake.esc(cfg.includedirs), ";") %>" <% end %> <% if #cfg.defines > 0 then %> PreprocessorDefinitions="<%= table.concat(premake.esc(cfg.defines), ";") %>" <% end %> <% if cfg.flags.Symbols and not cfg.flags.Managed then %> MinimalRebuild="<%= _VS.bool(true) %>" <% end %> <% if cfg.flags.NoExceptions then %> ExceptionHandling="<%= iif(_ACTION < "vs2005", "FALSE", 0) %>" <% elseif cfg.flags.SEH and _ACTION > "vs2003" then %> ExceptionHandling="2" <% end %> <% if _VS.optimization(cfg) == 0 and not cfg.flags.Managed then %> BasicRuntimeChecks="3" <% end %> <% if _VS.optimization(cfg) ~= 0 then %> StringPooling="<%= _VS.bool(true) %>" <% end %> RuntimeLibrary="<%= _VS.runtime(cfg) %>" EnableFunctionLevelLinking="<%= _VS.bool(true) %>" <% if _ACTION < "vs2005" and not cfg.flags.NoRTTI then %> RuntimeTypeInfo="<%= _VS.bool(true) %>" <% elseif _ACTION > "vs2003" and cfg.flags.NoRTTI then %> RuntimeTypeInfo="<%= _VS.bool(false) %>" <% end %> <% if cfg.flags.NativeWChar then %> TreatWChar_tAsBuiltInType="<%= _VS.bool(true) %>" <% elseif cfg.flags.NoNativeWChar then %> TreatWChar_tAsBuiltInType="<%= _VS.bool(false) %>" <% end %> <% if not cfg.flags.NoPCH and cfg.pchheader then %> UsePrecompiledHeader="<%= iif(_ACTION < "vs2005", 3, 2) %>" PrecompiledHeaderThrough="<%= cfg.pchheader %>" <% else %> UsePrecompiledHeader="<%= iif(_ACTION > "vs2003" or cfg.flags.NoPCH, 0, 2) %>" <% end %> WarningLevel="<%= iif(cfg.flags.ExtraWarnings, 4, 3) %>" <% if cfg.flags.FatalWarnings then %> WarnAsError="<%= _VS.bool(true) %>" <% end %> <% if _ACTION < "vs2008" and not cfg.flags.Managed then %> Detect64BitPortabilityProblems="<%= _VS.bool(not cfg.flags.No64BitChecks) %>" <% end %> ProgramDataBaseFileName="$(OutDir)\$(ProjectName).pdb" DebugInformationFormat="<%= _VS.symbols(cfg) %>" /> <% elseif (block == "VCCustomBuildTool") then %> <% elseif (block == "VCFxCopTool") then %> <% elseif (block == "VCLinkerTool") then %> Name="VCLinkerTool" <% if cfg.flags.NoImportLib then %> IgnoreImportLibrary="<%= _VS.bool(true) %>" <% end %> <% if #cfg.linkoptions > 0 then %> AdditionalOptions="<%= table.concat(premake.esc(cfg.linkoptions), " ") %>" <% end %> <% if #cfg.links > 0 then %> AdditionalDependencies="<%= table.concat(premake.getlinks(cfg, "all", "fullpath"), " ") %>" <% end %> OutputFile="$(OutDir)\<%= cfg.buildtarget.name %>" LinkIncremental="<%= iif(_VS.optimization(cfg) == 0, 2, 1) %>" AdditionalLibraryDirectories="<%= table.concat(premake.esc(path.translate(cfg.libdirs)) , ";") %>" <% local deffile = premake.findfile(cfg, ".def"); if deffile then %> ModuleDefinitionFile="<%= deffile %>" <% end %> <% if cfg.flags.NoManifest then %> GenerateManifest="<%= _VS.bool(false) %>" <% end %> GenerateDebugInformation="<%= _VS.bool(_VS.symbols(cfg) ~= 0) %>" <% if _VS.symbols(cfg) ~= 0 then %> ProgramDatabaseFile="$(OutDir)\$(ProjectName).pdb" <% end %> SubSystem="<%= iif(cfg.kind == "ConsoleApp", 1, 2) %>" <% if _VS.optimization(cfg) ~= 0 then %> OptimizeReferences="2" EnableCOMDATFolding="2" <% end %> <% if (cfg.kind == "ConsoleApp" or cfg.kind == "WindowedApp") and not cfg.flags.WinMain then %> EntryPointSymbol="mainCRTStartup" <% end %> <% if cfg.kind == "SharedLib" then %> <% local implibname = path.translate(premake.gettarget(cfg, "link", "windows").fullpath, "\\") %> ImportLibrary="<%= iif(cfg.flags.NoImportLib, cfg.objectsdir.."\\"..path.getname(implibname), implibname) %>" <% end %> TargetMachine="1" <% else %> Name="VCLibrarianTool" OutputFile="$(OutDir)\<%= cfg.buildtarget.name %>" <% end %> /> <% elseif (block == "VCManagedResourceCompilerTool") then %> <% elseif (block == "VCManagedWrapperGeneratorTool") then %> <% elseif (block == "VCManifestTool") then %> <% elseif (block == "VCMIDLTool") then %> <% elseif (block == "VCPreBuildEventTool") then %> 0 then %> CommandLine="<%= premake.esc(table.implode(cfg.prebuildcommands, "", "", "\r\n")) %>" <% end %> /> <% elseif (block == "VCPreLinkEventTool") then %> 0 then %> CommandLine="<%= premake.esc(table.implode(cfg.prelinkcommands, "", "", "\r\n")) %>" <% end %> /> <% elseif (block == "VCPostBuildEventTool") then %> 0 then %> CommandLine="<%= premake.esc(table.implode(cfg.postbuildcommands, "", "", "\r\n")) %>" <% end %> /> <% elseif (block == "VCResourceCompilerTool") then %> 0 then %> AdditionalOptions="<%= table.concat(premake.esc(cfg.resoptions), " ") %>" <% end %> <% if #cfg.defines > 0 or #cfg.resdefines > 0 then %> PreprocessorDefinitions="<%= table.concat(premake.esc(table.join(cfg.defines, cfg.resdefines)), ";") %>" <% end %> <% if #cfg.includedirs > 0 or #cfg.resincludedirs > 0 then %> AdditionalIncludeDirectories="<%= table.concat(premake.esc(table.join(cfg.includedirs, cfg.resincludedirs)), ";") %>" <% end %> /> <% elseif (block == "VCWebDeploymentTool") then %> <% elseif (block == "VCWebServiceProxyGeneratorTool") then %> <% elseif (block == "VCXDCMakeTool") then %> <% elseif (block == "VCXMLDataGeneratorTool") then %> <% end %> <% end %> <% end %> <% premake.walksources(this, this.files, _VS.files) %> ]])-- local function cleantemplatefiles(this, templates) if (templates) then for _,tmpl in ipairs(templates) do local fname = premake.getoutputname(this, tmpl[1]) os.remove(fname) end end end newaction { trigger = "clean", description = "Remove all binaries and generated files", targetstyle = "windows", execute = function() local solutions = { } local projects = { } local targets = { } local cwd = os.getcwd() local function rebase(parent, dir) return path.rebase(dir, parent.location, cwd) end -- Walk the tree. Build a list of object names to pass to the cleaners, -- and delete any toolset agnostic files along the way. for _,sln in ipairs(_SOLUTIONS) do table.insert(solutions, path.join(sln.location, sln.name)) for prj in premake.eachproject(sln) do table.insert(projects, path.join(prj.location, prj.name)) if (prj.objectsdir) then os.rmdir(rebase(prj, prj.objectsdir)) end for cfg in premake.eachconfig(prj) do table.insert(targets, path.join(rebase(cfg, cfg.buildtarget.directory), cfg.buildtarget.basename)) -- remove all possible permutations of the target binary os.remove(rebase(cfg, premake.gettarget(cfg, "build", "windows").fullpath)) os.remove(rebase(cfg, premake.gettarget(cfg, "build", "linux", "linux").fullpath)) os.remove(rebase(cfg, premake.gettarget(cfg, "build", "linux", "macosx").fullpath)) if (cfg.kind == "WindowedApp") then os.rmdir(rebase(cfg, premake.gettarget(cfg, "build", "linux", "linux").fullpath .. ".app")) end -- if there is an import library, remove that too os.remove(rebase(cfg, premake.gettarget(cfg, "link", "windows").fullpath)) os.remove(rebase(cfg, premake.gettarget(cfg, "link", "linux").fullpath)) os.rmdir(rebase(cfg, cfg.objectsdir)) end end end -- Walk the tree again. Delete templated and toolset-specific files for _,action in pairs(premake.actions) do for _,sln in ipairs(_SOLUTIONS) do cleantemplatefiles(sln, action.solutiontemplates) for prj in premake.eachproject(sln) do cleantemplatefiles(prj, action.projecttemplates) end end if (type(action.onclean) == "function") then action.onclean(solutions, projects, targets) end end end, } -- newaction { trigger = "codeblocks", shortname = "Code::Blocks", description = "Code::Blocks Studio", valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" }, valid_languages = { "C", "C++" }, valid_tools = { cc = { "gcc", "ow" }, }, solutiontemplates = { { ".workspace", _TEMPLATES.codeblocks_workspace }, }, projecttemplates = { { ".cbp", _TEMPLATES.codeblocks_cbp }, }, onclean = function(solutions, projects, targets) for _,name in ipairs(projects) do os.remove(name .. ".depend") os.remove(name .. ".layout") end end } -- _CODELITE = { } function _CODELITE.kind(value) if (value == "ConsoleApp" or value == "WindowedApp") then return "Executable" elseif (value == "StaticLib") then return "Static Library" elseif (value == "SharedLib") then return "Dynamic Library" end end function _CODELITE.files(prj, fname, state, nestlevel) local indent = string.rep(" ", nestlevel + 1) if (state == "GroupStart") then io.write(indent .. '\n') elseif (state == "GroupEnd") then io.write(indent .. '\n') else io.write(indent .. '\n') end end newaction { trigger = "codelite", shortname = "CodeLite", description = "CodeLite (experimental)", targetstyle = "linux", valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" }, valid_languages = { "C", "C++" }, valid_tools = { cc = { "gcc" }, }, solutiontemplates = { { ".workspace", _TEMPLATES.codelite_workspace }, }, projecttemplates = { { ".project", _TEMPLATES.codelite_project }, }, onclean = function(solutions, projects, targets) for _,name in ipairs(solutions) do os.remove(name .. "_wsp.mk") os.remove(name .. ".tags") end for _,name in ipairs(projects) do os.remove(name .. ".mk") os.remove(name .. ".list") os.remove(name .. ".out") end end } -- _MAKE = { } function _MAKE.esc(value) if (type(value) == "table") then local result = { } for _,v in ipairs(value) do table.insert(result, _MAKE.esc(v)) end return result else local result result = value:gsub(" ", "\\ ") result = result:gsub("\\", "\\\\") return result end end function _MAKE.getmakefilename(this, searchprjs) -- how many projects/solutions use this location? local count = 0 for _,sln in ipairs(_SOLUTIONS) do if (sln.location == this.location) then count = count + 1 end if (searchprjs) then for _,prj in ipairs(sln.projects) do if (prj.location == this.location) then count = count + 1 end end end end if (count == 1) then return "Makefile" else return this.name .. ".make" end end function _MAKE.getnames(tbl) local result = table.extract(tbl, "name") for k,v in pairs(result) do result[k] = _MAKE.esc(v) end return result end newaction { trigger = "gmake", shortname = "GNU Make", description = "GNU makefiles for POSIX, MinGW, and Cygwin", targetstyle = "linux", valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" }, valid_languages = { "C", "C++", "C#" }, valid_tools = { cc = { "gcc" }, dotnet = { "mono", "ms", "pnet" }, }, solutiontemplates = { { function(this) return _MAKE.getmakefilename(this, false) end, _TEMPLATES.make_solution }, }, projecttemplates = { { function(this) return _MAKE.getmakefilename(this, true) end, _TEMPLATES.make_cpp, function(this) return this.language == "C" or this.language == "C++" end }, { function(this) return _MAKE.getmakefilename(this, true) end, _TEMPLATES.make_csharp, function(this) return this.language == "C#" end }, }, } -- _VS = { } _VS.vs2002 = { "VCCLCompilerTool", "VCCustomBuildTool", "VCLinkerTool", "VCMIDLTool", "VCPostBuildEventTool", "VCPreBuildEventTool", "VCPreLinkEventTool", "VCResourceCompilerTool", "VCWebServiceProxyGeneratorTool", "VCWebDeploymentTool" } _VS.vs2003 = { "VCCLCompilerTool", "VCCustomBuildTool", "VCLinkerTool", "VCMIDLTool", "VCPostBuildEventTool", "VCPreBuildEventTool", "VCPreLinkEventTool", "VCResourceCompilerTool", "VCWebServiceProxyGeneratorTool", "VCXMLDataGeneratorTool", "VCWebDeploymentTool", "VCManagedWrapperGeneratorTool", "VCAuxiliaryManagedWrapperGeneratorTool" } _VS.vs2005 = { "VCPreBuildEventTool", "VCCustomBuildTool", "VCXMLDataGeneratorTool", "VCWebServiceProxyGeneratorTool", "VCMIDLTool", "VCCLCompilerTool", "VCManagedResourceCompilerTool", "VCResourceCompilerTool", "VCPreLinkEventTool", "VCLinkerTool", "VCALinkTool", "VCManifestTool", "VCXDCMakeTool", "VCBscMakeTool", "VCFxCopTool", "VCAppVerifierTool", "VCWebDeploymentTool", "VCPostBuildEventTool" } _VS.vs2008 = _VS.vs2005 function _VS.onclean(solutions, projects, targets) for _,name in ipairs(solutions) do os.remove(name .. ".suo") os.remove(name .. ".ncb") end for _,name in ipairs(projects) do os.remove(name .. ".csproj.user") os.remove(name .. ".csproj.webinfo") local files = os.matchfiles(name .. ".vcproj.*.user", name .. ".csproj.*.user") for _, fname in ipairs(files) do os.remove(fname) end end for _,name in ipairs(targets) do os.remove(name .. ".pdb") os.remove(name .. ".idb") os.remove(name .. ".ilk") os.remove(name .. ".vshost.exe") os.remove(name .. ".exe.manifest") end end function _VS.arch(prj) if (prj.language == "C#") then if (_ACTION < "vs2005") then return ".NET" else return "Any CPU" end else return "Win32" end end function _VS.bool(value) if (_ACTION < "vs2005") then return iif(value, "TRUE", "FALSE") else return iif(value, "true", "false") end end function _VS.cfgtype(cfg) if (cfg.kind == "SharedLib") then return 2 elseif (cfg.kind == "StaticLib") then return 4 else return 1 end end local function output(indent, value) io.write(indent .. value .. "\r\n") end local function attrib(indent, name, value) io.write(indent .. "\t" .. name .. '="' .. value .. '"\r\n') end function _VS.files(prj, fname, state, nestlevel) local indent = string.rep("\t", nestlevel + 2) if (state == "GroupStart") then output(indent, "") elseif (state == "GroupEnd") then output(indent, "") else output(indent, "") if (not prj.flags.NoPCH and prj.pchsource == fname) then for _, cfgname in ipairs(prj.configurations) do output(indent, "\t") output(indent, "\t\t") output(indent, "\t") end end output(indent, "") end end function _VS.optimization(cfg) local result = 0 for _, value in ipairs(cfg.flags) do if (value == "Optimize") then result = 3 elseif (value == "OptimizeSize") then result = 1 elseif (value == "OptimizeSpeed") then result = 2 end end return result end function _VS.projectfile(prj) local extension if (prj.language == "C#") then extension = ".csproj" else extension = ".vcproj" end local fname = path.join(prj.location, prj.name) return fname..extension end function _VS.runtime(cfg) local debugbuild = (_VS.optimization(cfg) == 0) if (cfg.flags.StaticRuntime) then return iif(debugbuild, 1, 0) else return iif(debugbuild, 3, 2) end end function _VS.symbols(cfg) if (not cfg.flags.Symbols) then return 0 else -- Edit-and-continue does't work if optimizing or managed C++ if (cfg.flags.NoEditAndContinue or _VS.optimization(cfg) ~= 0 or cfg.flags.Managed) then return 3 else return 4 end end end function _VS.tool(prj) if (prj.language == "C#") then return "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC" else return "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942" end end newaction { trigger = "vs2002", shortname = "Visual Studio 2002", description = "Microsoft Visual Studio 2002", targetstyle = "windows", valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" }, valid_languages = { "C", "C++", "C#" }, solutiontemplates = { { ".sln", _TEMPLATES.vs2002_solution }, }, projecttemplates = { { ".vcproj", _TEMPLATES.vs200x_vcproj, function(this) return this.language ~= "C#" end }, { ".csproj", _TEMPLATES.vs2002_csproj, function(this) return this.language == "C#" end }, { ".csproj.user", _TEMPLATES.vs2002_csproj_user, function(this) return this.language == "C#" end }, }, onclean = _VS.onclean, } newaction { trigger = "vs2003", shortname = "Visual Studio 2003", description = "Microsoft Visual Studio 2003", targetstyle = "windows", valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" }, valid_languages = { "C", "C++", "C#" }, solutiontemplates = { { ".sln", _TEMPLATES.vs2003_solution }, }, projecttemplates = { { ".vcproj", _TEMPLATES.vs200x_vcproj, function(this) return this.language ~= "C#" end }, { ".csproj", _TEMPLATES.vs2002_csproj, function(this) return this.language == "C#" end }, { ".csproj.user", _TEMPLATES.vs2002_csproj_user, function(this) return this.language == "C#" end }, }, onclean = _VS.onclean, } newaction { trigger = "vs2005", shortname = "Visual Studio 2005", description = "Microsoft Visual Studio 2005 (SharpDevelop, MonoDevelop)", targetstyle = "windows", valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" }, valid_languages = { "C", "C++", "C#" }, solutiontemplates = { { ".sln", _TEMPLATES.vs2005_solution }, }, projecttemplates = { { ".vcproj", _TEMPLATES.vs200x_vcproj, function(this) return this.language ~= "C#" end }, { ".csproj", _TEMPLATES.vs2005_csproj, function(this) return this.language == "C#" end }, { ".csproj.user", _TEMPLATES.vs2005_csproj_user, function(this) return this.language == "C#" end }, }, onclean = _VS.onclean, } newaction { trigger = "vs2008", shortname = "Visual Studio 2008", description = "Microsoft Visual Studio 2008", targetstyle = "windows", valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib" }, valid_languages = { "C", "C++", "C#" }, solutiontemplates = { { ".sln", _TEMPLATES.vs2005_solution }, }, projecttemplates = { { ".vcproj", _TEMPLATES.vs200x_vcproj, function(this) return this.language ~= "C#" end }, { ".csproj", _TEMPLATES.vs2005_csproj, function(this) return this.language == "C#" end }, { ".csproj.user", _TEMPLATES.vs2005_csproj_user, function(this) return this.language == "C#" end }, }, onclean = _VS.onclean, } $Lua: Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio $ $Authors: R. Ierusalimschy, L. H. de Figueiredo & W. Celes $ $URL: www.lua.org $ no calling environmentno valueYg"@r"@r"@c"@c"@g"@c"@?*@*@*@+@+@+@N+@V+@Sl%s:%d: bad argument #%d (%s)nmethodcalling '%s' on bad self (%s)?bad argument #%d to '%s' (%s)%s expected, got %sstack overflow (%s)value expectedinvalid option '%s'_LOADEDname conflict for module '%s' cannot %s %s: %s=stdin@%sropenrbreopenreadPANIC: unprotected error in call to Lua API (%s) createresumerunningstatuswrapyield0CJ@7CI@>CiK@FCH@MC*K@RCNK@suspendednormaldead>CCCCassertcollectgarbagedofileerrorgcinfogetfenvgetmetatableloadfileloadloadstringnextpcallprintrawequalrawgetrawsetselectsetfenvsetmetatabletonumbertostringtypeunpackxpcallCE@CA@CD@C2>@CoA@C?@C>@CC@CkD@CvC@(C[B@-CmF@3C<@9C@@BC@@IC1A@PCE@WC4@@_C>@lCG=@uC G@~C(B@CTE@CF@'tostring' must return a string to 'print'base out of range__metatablenil or table expectedcannot change a protected metatablelevel must be non-negativeinvalid levelfno function environment for tail call at level %d'setfenv' cannot change environment of given objectstoprestartcollectcountstepsetpausesetstepmulCCCCCCC:too many nested functionsreader function must return a string=(load)assertion failed!%stoo many results to unpackindex out of range__tostringtruefalsenil%s: %pboolean or proxy expectedcoroutine expectedtoo many arguments to resumecannot resume %s coroutinetoo many results to resumeLua function expected_GLua 5.1_VERSIONipairspairskv__modenewproxycoroutinecontrol structure too longfunction or expression too complexconstant table overflowcode size overflowS@S@S@S@T@T@T@T@T@T@T@T@U@ U@jU@jU@jU@jU@jU@(U@KU@3V@8V@3V@3V@NV@NV@NV@NV@@V@Y@^Y@Y@Y@,Y@bY@xY@~Y@Y@Z@Z@Z@Z@Z@Z@Z@Z@Z@Z@Z@Z@s\@\@\@\@\@\@\@\@\@\@\@]@"]@[@[@]@]@]@]@]@]@]@]@]@]@]@]@]@h]@y]@debuggetfenvgethookgetinfogetlocalgetregistrygetmetatablegetupvaluesetfenvsethooksetlocalsetmetatablesetupvaluetraceback@Cg@FC;`@NCf@VCDa@^CBc@gC_@sC_@Cd@CO`@Ce@Cc@C_@Cd@Ch@hnil or table expected'setfenv' cannot change environment of given objectflnSu>%sfunction or level expectedinvalid optionsourceshort_srclinedefinedlastlinedefinedwhatcurrentlinenupsnamenamewhatactivelinesfunclevel out of rangecallreturnlinecounttail returnLCQCXC]CcCexternal hooklua_debug> cont =(debug command) stack traceback: ... Snl%s:%d: in function '%s' in main chunk ? in function <%s:%d>(*temporary)o@o@p@p@r@p@p@r@r@4p@r@r@r@r@r@r@r@r@r@Rp@p@r@r@r@r@r@p@p@Cq@p@p@Zp@Xq@r@q@q@?localglobalfieldupvaluemethods@s@s@s@Os@s@3s@s@s@s@s@ps@tail=(tail call)=[C]CmainLua%s:%d: %sattempt to compare two %s valuesattempt to compare %s with %sattempt to %s %s '%s' (a %s value)attempt to %s a %s valueperform arithmetic onconcatenatenot enough memoryerror in error handlingstack overflowcallnC stack overflowcannot resume non-suspended coroutineattempt to yield across metamethod/C-call boundary@@@B@@@e@@@@@@@@@@@@@packagetableioosstringmathdebugCK@CX@CV&AC@C@CAC@Cj@closeflushinputlinesopenoutputpopenreadtmpfiletypewriteC_@C@Cޞ@CW@C@C@Cg@C@C͝@C@C@CCseeksetvbuf__gc__tostringC_@Cڥ@C6@C@HCФ@MCH@C@UC@ZC@%s: %s%sFILE*closed filefileattempt to use a closed filecannot close standard file__closefile (closed)file (%p)rstandard %s file is closedwtoo many argumentsinvalid option%lfinvalid formatfile is already closed%.14gsetcurend C C C@nofullline C C C__indexiostdinstdoutstderrandbreakdoelseelseifendfalseforfunctionifinlocalnilnotorrepeatreturnthentrueuntilwhile.....==>=<=~=@!CD!CJ!CM!CR!CY!C]!Cc!Cg!Cp!Cs!Cv!C|!C!C!C!C!C!C!C!C!C!C!C!C!C!C!C!C!C!C!Cchar(%d)%c%s:%d: %s%s near '%s'lexical element too longchunk has too many linesEe+-malformed numberunfinished long stringunfinished long commentnesting of [[...]] is deprecatedinvalid long string delimiterunfinished stringescape sequence too large.absacosasinatan2atanceilcoshcosdegexpfloorfmodfrexpldexplog10logmaxminmodfpowradrandomrandomseedsinhsinsqrttanhtan#C@#C@#Cз@#CN@#C$@#C@#CR@#C(@#CN@#C$@#C@#Cٸ@#C@#C׺@#C@#Cй@#Cm@#C @#C@#C@#Cv@#Cѻ@#Cۼ@#C@#CԶ@$CS@$C@ $C|@9RFߑ?9RFߑ?interval is emptywrong number of argumentsF?mathpihugemodmemory allocation error: block too bigmodulerequire%Ck@%C@C@@I@@loadlibseeall%C@%C,@system error %d _LOADLIBLOADLIB: %s%sopeninit\.'package.%s' must be a string?r no file '%s'error loading module '%s' from file '%s': %spath_luaopen_%scpath no module '%s' in file '%s'preload'package.preload' must be a table no field package.preload['%s']_LOADEDloop or previous error loading module '%s'loaders'package.loaders' must be a tablemodule '%s' not found:%sname conflict for module '%s'_NAME_M_PACKAGEf'module' not called from a Lua function__index;;;;unable to get ModuleFileName!__gcpackage.\?.lua;!\lua\?.lua;!\lua\?\init.lua;!\?.lua;!\?\init.luaLUA_PATH.\?.dll;!\?.dll;!\loadall.dllLUA_CPATH\ ; ? ! -configloaded%(null)%p... "]`qT`Pql1@+Ce@+C@+CC@+C@+C@+C@,C$@,C @%s: %sunable to generate a unique filenamezDfield '%s' missing in date table%c*tsecminhourdaymonthyearwdayydayisdstallcollatectypemonetarynumeric-C -C(-C.-C7-C,Cos '%s' expectedmain function has more than %d %sfunction at line %d has more than %d %s'%s' expected (to close '%s' at line %d)local variablestoo many local variablesupvalueschunk has too many syntax levelsno loop to break(for index)(for limit)(for step)(for generator)(for state)(for control)'=' or 'in' expected@@@@@@@'@@@@@@@o@@@@@d@selfarg or '...' expectedconstant table overflowcannot use '...' outside a vararg functionitems in a constructorambiguous syntax (function call x new statement)function arguments expectedunexpected symbolsyntax errorvariables in assignmentnot enough memorybytechardumpfindformatgfindgmatchgsublenlowermatchrepreversesubupper@0C@E0Cm@J0C@O0CAT0C A[0C Aa0C Ah0C Am0C@q0C,@w0CA}0C@@0C@0C@0C@string slice too longinvalid valueunable to dump given functionmalformed pattern (ends with '%%')malformed pattern (missing ']')@^A8@\@^A^A^A^A^A^A^A@^A^A^A@^A^A@^A@^AA'A^ATAinvalid pattern captureunbalanced patternmissing '[' after '%%f' in patterninvalid capture indextoo many capturesunfinished capture^$*+?.([%-'string.gfind' was renamed to 'string.gmatch'string/function/table expectedinvalid replacement value (a %s)-+ #0invalid format (repeated flags)invalid format (width or precision too long)\r\000invalid option '%%%c' to 'format'string__indexYinvalid key to 'next'table overflowYtable index is niltable index is NaNconcatforeachforeachigetnmaxninsertremovesetnsort 4Cn"A'4CA/4CA84C A=4C AB4C AI4C!AP4C AU4C%A'setn' is obsoletewrong number of arguments to 'insert'invalid value (%s) at index %d in table for 'concat'invalid order function for sortingtablenilbooleanuserdatanumberstringtablefunctionthreadprotoupval`5Cd5Cl5Cu5C|5C5C5Cl5C5C5C5C__index__newindex__gc__mode__eq__add__sub__mul__div__mod__pow__unm__len__lt__le__concat__call5C5C5C6C 6C6C6C6C"6C(6C.6C46C:6C@6CE6CJ6CS6C%s: %s in precompiled chunkunexpected endbad integercode too deepbad constantbad codebinary stringbad header=?%.14gindexloop in gettableloop in settablem3A3A3At3A3A3A3A3Astring length overflow5A5A5A5A5A5A6Aget length of'for' initial value must be a number'for' limit must be a number'for' step must be a number7A7A7A7A7A8A[8A8A8A(9A9A9AJ:A:A;A;A;AAy>A>AX?AC@A@A@A?AA+BABABAxCA(DADADAEA-LIBGCCW32-EH-2-SJLJ-GTHR-MINGW32w32_sharedptr->size == sizeof(W32_EH_SHARED)%s:%u: failed assertion `%s' ../../gcc/gcc/config/i386/w32-shared-ptr.cGetAtomNameA (atom, s, sizeof(s)) != 0TPZHRP(ZRP[R8TDTPTdTtTTTTTTTTT U$U8UHU\UtUUUUUUUUUVVV(V4V@VLVXVdVpVxVVVVVVVVVVVVVVVW WWW$W0W8W@WHWPW\WdWpWxWWWWWWWWWWWWWXX X(X0X8X@XLXXXdXpX|XXXXXXXXXXXXXYY Y,Y8YDYPY\YhYtY|YYYYYYY8TDTPTdTtTTTTTTTTT U$U8UHU\UtUUUUUUUUUVVV(V4V@VLVXVdVpVxVVVVVVVVVVVVVVVW WWW$W0W8W@WHWPW\WdWpWxWWWWWWWWWWWWWXX X(X0X8X@XLXXXdXpX|XXXXXXXXXXXXXYY Y,Y8YDYPY\YhYtY|YYYYYYYAddAtomA5CopyFileA<CreateDirectoryAExitProcessFindAtomAFindCloseFindFirstFileAFindNextFileAFormatMessageAFreeLibraryGetAtomNameAGetCurrentDirectoryACGetLastErrorMGetModuleFileNameAjGetProcAddress LoadLibraryAtRemoveDirectoryASetCurrentDirectoryASetUnhandledExceptionFilterO_stat'__getmainargs0__mb_cur_max<__p__environ>__p__fmodeP__set_app_typey_cexit_errno_filbuf_iob_isctype^_onexitf_pcloseg_pctypej_popen_setjmp_setmodeabortacosasinatanatan2atexit"ceil#clearerr$clock%cos&cosh(difftime*exit+exp-fclose0fflush3fgets6floor7fmod8fopen9fprintf:fputc;fputs>fread?free@freopenAfrexpBfscanfCfseekEftellGfwriteKgetenvOgmtimekldexpmlocaleconvnlocaltimeologplog10qlongjmprmallocvmemchrwmemcmpxmemcpy{mktime|modf~powputsrandreallocremoverenamesetlocalesetvbufsignalsinsinhsprintfsqrtsrandstrcatstrchrstrcmpstrcollstrcpystrcspnstrerrorstrftimestrncatstrncpystrpbrkstrrchrstrstrstrtodstrtoulsystemtantanhtimetmpfiletmpnamtolowertoupperungetcPPPPPPPPPPPPPPPPPPPKERNEL32.dllPmsvcrt.dll(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(P(Pmsvcrt.dllode-0.11.1/compile0000755000076400007640000000717311206343411010653 00000000000000#! /bin/sh # Wrapper for compilers which do not understand `-c -o'. scriptversion=2005-05-14.22 # Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. # Written by Tom Tromey . # # 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, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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. # This file is maintained in Automake, please report # bugs to or send patches to # . 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 . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; esac ofile= cfile= eat= 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 -e 's|^.*/||' -e '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 mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then 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-end: "$" # End: ode-0.11.1/autogen.sh0000755000076400007640000000311511021651155011270 00000000000000#!/bin/sh # The version nr detection is not working. # It fails if there is a '-' char in the version nr e.g. # We should not use it until fixed. - Bram ## The reason this uses sed instead of "grep --only-matches" ## is because MinGW's grep is an old version and does not contain that flag. #automake_version=`automake --version | grep --regexp='[+0-9].[+0-9].[+0-9]' | sed -n 's/[* ()A-Za-z]//g;p'` #automake_mayor=${automake_version%.*.*} #automake_minor=${automake_version%.*} #automake_minor=${automake_minor##*.} #automake_revision=${automake_version##*.} #echo "AutoMake Version: $automake_mayor.$automake_minor.$automake_revision" # #if [ $automake_mayor -eq 1 ]; then # if [ $automake_minor -lt 8 ]; then # echo "Automake must be 1.8.2 or higher, please upgrade" # exit # else # if [ $automake_minor -eq 8 ] && [ $automake_revision -lt 2 ]; then # echo "Automake must be 1.8.2 or higher, please upgrade" # exit # fi # fi #fi echo "Please make sure that you use automake 1.10 or later" echo "Warnings about underquoted definitions are harmless" echo "Running aclocal" aclocal -I . || exit 1 # on Mac libtoolize is called glibtoolize LIBTOOLIZE=libtoolize if [ `uname -s` = Darwin ]; then LIBTOOLIZE=glibtoolize fi echo "Running $LIBTOOLIZE" $LIBTOOLIZE --copy --force --automake || 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) #./configure $* echo "Now you are ready to run ./configure" ode-0.11.1/depcomp0000755000076400007640000004271311206343422010653 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2007-03-29.01 # Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007 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, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, 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. # Originally written by Alexandre Oliva . 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 outputing dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac 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" # 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 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 -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## 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). ## - 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 -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## 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. tr ' ' ' ' < "$tmpdepfile" | ## 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. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -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 -eq 0; then : else 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 ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> $depfile echo >> $depfile # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> $depfile else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; 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. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` 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 -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Intel's C compiler understands `-MD -MF file'. However on # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want: # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using \ : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else 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. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` 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 -eq 0; then : else 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,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" # Add `dependent.h:' lines. sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile" else echo "#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. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then # With Tru64 cc, shared objects can also be used to make a # static library. This mechanism is used in libtool 1.4 series to # handle both shared and static libraries in a single compilation. # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. # # With libtool 1.5 this exception was removed, and libtool now # 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.libs/$base.lo.d # libtool 1.4 tmpdepfile2=$dir$base.o.d # libtool 1.5 tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.o.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d tmpdepfile4=$dir$base.d "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #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 $1 != '--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:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. 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 $1 != '--mode=compile'; do shift done shift fi # X makedepend shift cleared=no for arg in "$@"; do case $cleared in no) set ""; shift cleared=yes ;; esac 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. -*|$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" cat < "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. 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 $1 != '--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, regardless of -o, # because we must use -o when running libtool. "$@" || exit $? IFS=" " for arg do case "$arg" in "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; 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-end: "$" # End: ode-0.11.1/ode/0000777000076400007640000000000011206343457010132 500000000000000ode-0.11.1/ode/doc/0000777000076400007640000000000011206343341010667 500000000000000ode-0.11.1/ode/doc/pix/0000777000076400007640000000000011206343341011467 500000000000000ode-0.11.1/ode/doc/pix/ball-and-socket-bad.jpg0000644000076400007640000002165107320713017015601 00000000000000JFIFcCreated by Paint Shop Pro CREATOR: XV Version 3.10a Rev: 12/29/94 Quality = 75, Smoothing = 0 C    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222," }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?Qv(7b1@ .)qKn(;b1NSF(Qn(;b1NSF(Qn(;b1NSF(Qn(;b1NSF(Qn)1ObSF(Qn(;b1NbSIv(;b1N.(Qn(;b1OSF(R1ObSF(Qn(;bSF(Qf(?b1ObSF(Rb1NbSF(Qf(?SF(Qf(;b1NPqF)أQ~(7b\P1F)Qv(7b1@ .)أQv)q@ P1F)Q~(3b1@ P1F)Q~(3b1@ P1F)7P1F*9.9[R}c@F*jgbP>4F+!n7F]1?S@xSNr4dUPqI~(.(?b1N.(;b1ObR1ObR1ObSKf(?b1ObSF(Qf(I1@T(?b1ObSF(< ghHp€-K,p.&QgiI5k1Bs=>qws|߼l'd^7!6m>fT;>;Inz$XUUF$#TT]+vf=<Uܟ"V3}lYc`oƭQs3>kYmW`j.0nAϏ#(Ck:ԔUZʹBz m-ֹ1O&(qKv(7b1@ PqF)R❊\P1F)R⟊1@ Q~(3b\Px&(3b1@ P1F)G1RbQ~(3bl!y*sy _}FG#q\mA$\ s<ksWZR,?T9yoInCehqUK n$;WKi%y)}MmaZ~qztAFEtVzpO88AVdB1` ƭGV;j45 Ʃ\|$o}2#d=D̬ +WH!=aX9xo+}E\ɻp~jtILRqF)Q~(7bGeK;QܚLQϸ!"27AYW9_:qrt{m¦Tмr>I]␕R` xog>#esIMrR1Xj]/R(2tje5f+2LRY_?CNj!&(G\Sъf(I1@mI1@mI6ԛh@&* ȱ㿵TaG$+Yi۵}ZSj+yfǩZǂ{zWLjdZz.wҭ, WD4pά&URS5tCO\ "j_'گiD4#ڗO/E}GoWLAT:, y\%;l|0%8vVʹS%@B3^=j77nfiҽcxsMovAa7u'r$^FړmkI/x]q}DBx-r q=phA& 2zʲ u9R2 4qB5} "<+{XZԮf8DHQSY&jFj5DC5DHffYYK4G/u?YˇOrED ;=gN+qʳ’q]7,#rrmoB.QUA0__zHX7\ \d7(yFR( #i++~"k6D%zH9뻯T_5buțzgڽzo ťq9iYd?f'Ks$JѥOkͣk36!q^,ʰ5=v=m'![v?{/M`<)teou٩6z${5DMg5#5DHfYKi&o ?&2Wzy)/9HN#O5r kP}&}kgETWVkp8U*&9qYW#n9+&9*rT43Z9*S }AqP~jCX~yq$ӻJ=ICOe-+|LZJd2RI^JI)3IY^NrhF8ː>|2e{$G7B@kfj?$'מj|Ak('8^kK^ w czuvx+=ORm%v+ Uf²+(*2AB68}:{GeϱSƽQVEJSռYHSIINuS3~cNQo-XT E/6Kext./d3MطEԷgQuh >:m@,-*yҩ\$d~U_eHnC?wt||#^J=9UoD4~%ĦY\RkF+rUdLegqK,k" iz h"W=uEJvQ&z`=q1(IVyn1Xp{aZv^]] ^ꨔm5P5;Tʷt)1ۖfIf5Xx` Iz?O5E pF#t 1\%cÑC>kt}5(UPIRm3bW3 +cy xc]N)УF=oLeM4ӮPL\G Z"?4y5ZJF1`FrUڬ j9+*75j9*o6˩2PkZd}dU F3zrjY_5RV"C:3\R?]elnkO-6pmPs:Ƌ8Sٔ~їs5+i*u9Xa|L"e>]֓@{T*GwG %)"Ƹ3rknVE&nzt,jrꏦčֵO%$\'nZnf2;zrkoƗ&]?H>8UGsQVr4 Xix[۹7Ԑ{(\K"Rb W\hkSSy7(?J(LuפlXZNJq_ FQ׿H?&J+RP3W.X[ަLwWZom%XCn K[o51ݴ!~$?^?X,rcӷW5mz=gwzسybe}iOQ%36RJ.aRnvxX̾Z G{bC>[or^Ew/PZý:4piV0Dy6'^ 7EiY"&ǩku 1^^鶺[." Â>1-E.Fk=ku%NC KL&[Rgs9QoEK(-G%ca[Ө%Ե}{Om׷ ,A^gJTḊ@I봏ʱuMnz(ns',~tv:UmsƦu[iwwsִ`m ӑfK6iOymm*GO I|7x-.ٟLq?{fHC+ (((({g(=6./fʿ;=Wv 2#4oVQw:ėQ^!b|guW3R+t5LfmVzF1fjYe/Ufg#OɻH",U$jFJ@C+VmpDb5Xg5jY m~!%u0ϲ]鷨<᦭jb ppY]R^+j^1㢰9ct{m, XORԞWQ'= m3T=`$_SX!Ya\Xmᗢ)%[XҢW$k,o`{Rw8+xnº.~ܱ߮_. ?qq}zK4?u^Lff8gyrLnִd;Hsc}Idp~.i"đ 0aLz6/18f?O?@EPEPEPEPEP [f?9$uku{9d\7^E|1״="1ݗ͏?-B>,ٔxٕx?B>5X_Ɠ`|o} *Uz{g)Od\0:y֯_Ћ2-Qǝ:VnaGHv"u\s6gV,?她?.^hn#I|7XN 3jW$ZKp%^Ӵzmm itQƽ¾-n59GZSmd& αIJ]iF2Ԏg.`H#Լ'7:|>at7ƞ 0"$1~º7]ONn)QSeAr?> ״K1- @xA!#G?7^WִBvk[EbHU WK _O+|(_žĖP&|?+}gGSC4g1=C_z~8r?a zTsDث Hi;Z'[xt #/iu95{" :}DvT|@0@U`S]_Ǘ-UfTJB +A6y t6l'E쉟U<3p}RyFs^wZ1Oy@(Hp.j!]*GZ\z m>VËkI?2ʽ f.gCW(m_]cn$`3ٵWKsuk?Z(-~خ>թO'<ּ<9.fݔ#I_q (5m.}#T}ER^"'2:.$DGs\™FMGgPm]}ÿ䥴w ; ?+Rڬ.a@7m&ڛm&NCkj׸6u =GJڵq?qi6צ&j?#V  M֍PEPEP CD5E"%2ӤGkvd'qT|+>( >ttVynE {xm-㷷c1QFA 1q ڪ ( ( ( ( ( :EP4Û:S u%[+xq<@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ode-0.11.1/ode/doc/pix/body.jpg0000644000076400007640000003543507320713017013057 00000000000000JFIFcCreated by Paint Shop Pro CREATOR: XV Version 3.10a Rev: 12/29/94 Quality = 75, Smoothing = 0 C    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222," }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (k#6d:NP+85%syt%?u7nMtuR+ 54QEIQEQEQEQEQEQEQEQEQEQHX H=ih(((((((((((((((((((cc`-qכ|JuKSqWg"|I{4//]mp/(?w=FEk]jԽ9GŠ(T(((((((((I̴"~;jj1@n*cr"F`{^w˙,ѥv2#w("Z).SVT$gQTov62@=G\iٝFTaER,(((((((((((((((((+ŵOڄ;w[d>ox{v67rGM+d*O .n'5%N􂻡)+>ӣN[ pQ\G5IY3f涮3)js~(C肊(((((((((ơ?j[_*%\ƹq8otUAORq$q"ES]Bđ6˘T় v :*z/7k}qVhϣQE ( (G^ه>& J^ڗ.#ݜcwJΣJUɶR3ޡnRȌ PE,;;+t.V#V& (Q@Q@Q@Q@Q@Q@Q@Q@Q@OPl|˅YrkԼ_}{6pסtT gzsW#ndQEQEQEQEQEm 3F,x˻,m@R{zo\֧1!#_s%+ii\v  ]1 i/ݵ8T[eshQ=G}+WFRJΊKڢ}>3s/w#'t6\Q`ߥxݧb3$lx>fCynw*\ kQ\%ٗN\9ZAWdR +c*9hJU9-.ӯệǨ?^ksWP~R |oY!*;v48o]rk75 wmjLQW:.G \0RrHRDPZ9n f#8boZ=GXj\uqSpU毯@w>xforZӴ ?2RGAx%$~)x&;{w)a,x񞘯s};D[M2 HBA>OgQ2WzS{_PO)ڲ%q&x=-/<C)?JF_H?lu]_ڊ|qjNMtBc"c#@UFE&EPEPEPLVmoUjyOҟDEOwoLw}ތ} QHZ5+z iqh)X1#vrii cVѬF2]5xmu(cSjvU\N"dI*N"ib+I9JWHrQW|/2O~Ys^aC:9Z'6`Gz>{fH$ AH5ZધMJ'RjJfܬuJVBEQ֣Xj۫jubĒri›:NOC&cU\j[bU$54k6f·e*$W!8q7TjϨ6y0* ((~=k8V=&C['eo+fs,rKVԪ7Bu6آeέ6Hna#;[qY|Q })F0Vz԰Ԑ;z fIWUuY!}(0q9Tf]YVgL&:k7KSJqC\$yDbTLY1Ds^\ Uܖ3F$O𑃿$wG."1t1xG^:m3a@9?ƽ%MW!]Gg6N㿱j+ ..|p?`t;}w<sV͉ȕP+ ( ( ( (8+,}JBG2ֳAk Eފ(5*fbC+{#hE)8_ k6.Ѻ(]dZ=xeI\4BY ,$,VˁI_za8^O^KmFYE&, +'$*LGXEoj_+ =;ηWKSXZ۶ 9zn|Rgۊ5u]dj.6֯ o'Cd =?*5 Ql54mbe ^H#=3$^}zΤGf=F|.|3Z{StYZǩkhS-ȋ/599LJՍJc>̣&'tMD 6Lctyq}kgHGR{}=_L4Q?e1px :Ţ*prkBEr\hD[cFw#O?k&ξ9Qһ:{ySIIQE"B(((S遤tc?(좱A 8f7q7v/5]|k/ķs_OQfw*FӔUٳi@QPY #}X."4RS(IRK 3:Ke<eG]jZΜ-c;{$BKnn>IWF8 M#x:׵趮:wM,*jCRH 8 ԂIe+'%Sƒ7+ @sZ"1Xq$ϩ^q#Q :NnTTUjt8A +2I%7c&I8gWGOm{k K6=__HE͊;'8KÚ]O[W^ cdL9>WCekK HG ARQYF 'N`ȩ N MSHQA皂πsTAn3#Ο]vMTa'.⌙a;ǭyZj0_D2X?wZ1rpzW1؋&h˨ޟQWHظ-2+a!Piy=ŸTF?+_8ιj]^<ޗ=cd𝂑 KЊި-1B(3 ( ( ( (0cK?VFTN+[X,ި;ţ˟$WIqF3PQiרm7Sgƙd-Ku,P܂(W=$ғlIE^Cr 1 ds-=$Bx{ս/ZxK{}8!)=?hj%E]65Qf폙u= W2"G.7TzluKnx/ރڥtiUg)UZO*}}+iHw`{~(.ޤР`rM\iizvHUeSHje{%4k6/Z&8AXr.m \5ZXXtL Uƙ)l%6[vVMʞT6!Ұm|Cie SE:IFu[-.3[|F:u @@+k6qWѯs1x{BRّxVݶ_sn;FAꦩiӵZZ4on&caRztVRU'*r΀\kк\̀o?LCs/f[u*OLjDc*z1H`|HHt4LL7Lqڪ:b[R]{/3UfnP6[?ax-t[z?tڔ_LQˎ港 [yy&qҝL߉Lo="ϖ®iugc42FҭmLg}ɫ2r 1uKs a\;JmH̎9x7Bx\_[LNy#8WDh7Шv*D|Njk.{YVZT69=ҴR"ܞn=Qubi$'֥H@*zƌuDP"r2վjpnA2GZ¬.a^U "Y?n5oxMUom@Ls޺on{tG@#W9IןYyuݠH+Š((((M "=JWY޴UxT8fKv{w4@+˟$w`dhk c3\Jq@>¬M:[[Iq)c,z}ZK!)+Wh3u=G..ە &99hl,Wid|]IJW%TUS_PBk2r[* n1*U%ӥZLjaibyO x[C ڍmcS/3MKwc$s$ӄZ\]Ϭra"=gzK"u fRWB M_`q׹6 Lm=ivZLԋQȃ=i+4 InO(0:>tVs\A=OaZKp[̌X+̯-fs1>]c{V;Y;W?ʷ$j2# =λ🺶V#?ӴۍgQK+n "&oN-lqĞ?YV<5 [z|;IA0kVŶOw,]^F/EgTh)&EfΨ+\(_N y -=V't8qkqw)"FQpiqdyuiOفq) x CPkܣUN*hj|Js&?J҉qɬY0J : Ek89|%;gŶv㔆!q(SDS¼)XQԚEyݟ~Wc/ZjYJՕΛm% cʼP<_=&eȗՏ^Œ=Xk|wr}?aj=n 8b+9ݝf$ԗy@UU(uF6Wg6Wf>sESZڕ͏NJ͂K۰\5Fk *E㬹Xy4i3I &Biv S 4600{tշ]POXP-L kѼ1hl|1@F@My8;:<֢+Š((((؟Ji6鲨sp0wD p>׃ԻmG =TzXRżA#%id<נYanZHiõkEpswՅQ@(((((Ksʊȥ]Xd0<k^MS}*R7>z-ekG؊'̷oCG]zZΜ-wFw9[KfS Xk@IB))$mpAu?2n zdnў̤ymh4_>vK$WMm|Gpi`J=#]n ;6,<~icPcBjYfNܾZmDZҬkdӴW=E#AV"o4φ?* 4] Y(M#?ܩIȫ(,@7gn(;hii00cSI!6CHMC5P8ӽTmZ;_&k*Mn4je{Iݰ8>JP}ۅ_m%vL*y BJRMiZx3]jgd] NujglxSjciGmN( N sCkco*;]A<'8Ͻzi]F#*QEQEQEQEQEɤg@Td\hڕܲ$hӜ(#ϸc#V.>[At$SST+5),W׺͐Sit$Stnhf5R=j\mX4V%CT[Ssq#-[ Kt"y>W(%xپm֗6ׯxZʭEj(+G7RxSh}W}HUF Z''vyS (!EPEPEPEPEPEPEP?>jĘK,lƹiwhT^,Q *+UCLrkvK9tU}{׭Oru ֎KH־iuFgr'dHårLk~Q31\~'h6jh:)H]I$]OS #G3\o@?wkFX "(Ի*$Mݳi4rk.V J,+mU[';k~P&uqJ9*ʋS\1Us q:zg׷= Aĺҡ=*p?½NNVB#/*p*ǝSR_#|9lH95;r ]dqG kH*S9NSw)JNaETQEQEQEQEQEQEQEQEQEZf_ZG+>Y~uE4v<eպ }$~5$Y -|ak9xXa0?Pk:4륌 G+wE6_[w~ ˇoG= Pro?2'1z*M6gKNz^̱\\DVD=Nj\֖:OdoX`uΤ-m<ze6fm\kZ[K&8}~J :+Kdcw>=EDC4oRsŭUԗQEQEQEQEQEQEQEQEQEVOta]m\؎ڵ8Ÿ̤FѾcppAkF[,,C>!@͐lqCJO7ڔMoXob݇QaciJ ㍥wc4"g³d𧊼[2[>R7Whд"OӡIClֶa'jYY|+.O{'x`B~C=/El Sh7պƴ()՜&qJr(̐(((((((((((((((#P֙HMcٿ@ փXeGq}ߘWkEmNHlͩ*SY Gy&ua?5xkBk>?QK֮؇QZ.*UUEW9QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEode-0.11.1/ode/doc/pix/sf-graph2.jpg0000644000076400007640000006016610041621301013676 00000000000000JFIFHCREATOR: XV Version 3.10a Rev: 12/29/94 Quality = 90, Smoothing = 0 C     C   " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?((v>W4Gw-[RŶg;[DaDY-0N6c47UoxWS7EK( $*p+O,Kow_he׎9vQڤHVo-ʞ3ȻNq@XQ^/ڳy/k 櫣i se*ܸ!DC%U,R/~03PZߛԧH۪2ϼ)&  +*| j(o|qOaj^'yc/T$F$jB(B_?t$վE?k6T:RF!uMH.%5Uv8 +;Oxo[`ory7ixC{PvM8 ䷘ͅŠ?9/f$ks 4Aqm\ٍ!$H%f/@bG_?W?=?훱יfwl(m |Cgw|_2j^oD>de5^! 2@Q^ğh>[Z5׈omqXC"߻6YC < oM54 [iWlђ$HYX`((Kkw 5n/)֖/4V+Qyd+n|yåxFF,a7:7csa!x^"0ELJbn;m9dʢi/w4 S]<'x[l#xЯD3J2ĊepE|w?_fkšK$gxvhWA*H z~5|66xmyy.똼3Ӆܖ6h$7deHJv?17SÚPum4ǚ޻ϲ%A r9>'d-"/0Y7Jɸhx8&XOKv ",m$8#= 𽯁!rI`Hƥ!Fpa@/kkhu`,rѱBAc3~kO> xsGᕖ- vkHc1pL)(Im<]7/^xzw<ccp ܳ+ƢKY{R)R#A`_cY g>еk|Ea∴[pi^7߷OvאȈ Zpu?|,_P|,񇈵д~.{oy+V-bR;- (ُᖫM:M2LcfC}M08em'ד97||v׵MG:Y5_8DX#>l3(>O>M?sI29, 4:ِ)A~xWgkW\x>/9-˲2+GsAAvuLy]T_Xxg~O~4䚟>t0XLQ@(ab[s6OLt€OeO{ş 4oV~0-xY)a}{]VxwN3[NQki0rGvZv&Ə[Q#Sö xs×wdEo|0 deO((gxEg-+VvXjV-xXȥYW(bs(E ;#'>>mIuY%_4-q,)xٔ:*H 8q|-h*Lҽk9S̒((((^9|5ik} 0Y%3E DR) ˁU?bB 5C\L},e$n)ee$qֱ>-92+姱$A.; U"/WUS* 9A_5եzn+KRk&=9'7 `W! ~ }g>W([Aihf-M̨I0ʊ\dP'n5JYźODt\p,*@]:?bB 5Ch3^t=@ZωuL}Q{tRwdp(iq^=Ixf\“hweƛ<|V b qĪŃ_@kG,X?UuzoQZԴ:k8[|n,3hz_~*Uմ5RYv4mv3FT9DG,X?UtŃ_@k_i@Ń_@kZ~M5]KL,-:.nlKbX ue՚ f2 }_;N&x{K~}?}ƻ*(~}?}ƻ*(~}?}ƻ*(~}?}ƻ*(~}?}ƻ*(qu;#Vd}ӹ235xOf^@o#5Q@o#5Q@o#5Q@o#5Q@o#5Q@wh1ڵſM$Mm0$/G_N;?*xK5}ƏG_ʊ}ƏG_ʊ}ƏG_ʊ}ƏG_ʊ}ƏG_>!|)jvuy\JxQp9$$+`?ڎcËDkvKǘό+Lĕ,D89bޖ/S(Ajފʻ<8zJsz%w.ei_jzƟ4iTSoeI63@\?`L]v枀QEQE ?/bf-{_^5ӵX4R97#`B@`!Y|_\L},e6d GZϊ~:K<Ew(qVl! ;ǁ>#xSDٚL6qlYk7H䉐·yki?hZ֛> ZMgwo F%ͬ]0| hBwHH#HK^uk_d6݂Gq/,숑gwuUVfWi/ǿEӱumi`jQizգY ʛPWY1>UE18JDB8jQuzMW2]jI}j2\E"o;Y iBʲ+8`ᑊW)e)xn+?B^Kc|I^Il 7G2,P$1ʰ܈XDs#Hx?Gx_Xӿ5XxTe}94Ӭcw-ËA.^W<@_Gd/.5xs^ —Vz}E =P%:u|w-sZ״ h4[خWvLQ31~^>ռ7uxE7mt9m V .>Ο6ZO3[S1 x#LOUu!جDgKy?.ɖmX\2L!G7dlq RoO.VTiMc-pFIB f?lILɅۓmF>ҵHWzq^wnEY"S3[A HUIJ{Sxc@g÷Z~{Zn,7ױZ~ndb|$[HdX$+Di =35_ #V s¼"miUhOxK> ٽƽxGLM |d $"/1mY _t33]פx/&I5 2KtjPW{[0B~cP"n:*( ( ( ( (]KiI¨d~պ3,hQ%|1_y>n`2sV.z.vSJ_ɥa\?`L]vQEQE ?/bf-{?Ǐ6/ٯ&ā29 -Ax:=Z.k"9et^ȺdI!CeF x]򮲫JWX\Ulh0q]]?fe_~WH("Š2Mx{~(55/x77hkՌq8{k[_vgK5.6vʺ?@]M 1ҍ(]Y;<~&*JSwj*KSԿg[o;{ xOOKk`u 577R"E HҞVM{\6scZ$@>&hsJIx`H:x]FE.?W['U~zjI/=mSZK,ZEɐ6#BcHǹ$Yجj߳ Z'{fQm1 @j=ټ_/+p U׏x*+]o4dW׋Yz4[鷷y# {X!ekD{TkkW7~ZFMɵei'Y&ʏB*#^?ohp UUqmĩzW'tKwo5yћo6a]Vd?OѣrQYu_ԕFiZFFE.?WG#^?oh`o/k{KT]EidrJid*52XevGxN&x{Ku;V_|7tah4>jm>aOnw&AS`/4?k$]Z4cʂ$mm_w1%:( ( ( ( (97w0Y4ٻ%&gMb61 ;kXbP"F08;84H-m`X*k,2>QcJF+dV~_\KYIE(X Kc54+3[K€ ( (98ةf^^-a'5,h(((((8ة,ѫ+8ة,ѫ((((((8ة,k+8ة,k((((((8ة,k+8ة,k((#Sϻ)eFIu ]2 >0IUjOH|XG{&sq#2W.{apXݦ)vy}gέG>0.[cG.ls>\H%mԱ~nYmW&eU̪H#WeNO/ d}Q^IQ@O)?f&]qko2iuPEPEP1a'5,kŬ?#b={MQEQEQEQEQEy'o^#]yH8 >Ii+1ξ"WD{ VK}vQEqEPEPSJ_ɥa\?`L]vQEQEXxGMwK4zk8ةf^@Q@Q@Q@Q@Q@oxOf^^oxOf^@Q@Q@Q@Q@Q@oxOf^^oxOf^@Q@Q@Q@Q@W'⟇>)} ŵJ^kUTQ .HȭѩJ.R{%2V:dVrO7Ÿ"jvu[HnWiVTfYp5ڙ v7oڝ Yk-y9]^RA=SE484D᷈pI$NI$I$~cx4G?篬0t?# ?EMl#P]Hi\X嘎q +*թ^nY7'{SN(SAEVFEPEPEPSJ_ɥa\?`L]vV$:W~Oٻ݌g+(<>5 Ap֫!]6CIse'Y="Z٭, 7o)^ʼ9mLeEacc[84VGmk<;P4[d*N7sbYHmv}*Ih(0((((|)%/d밮?ŸR0mM. +:_|CǺփ&?iILndYaM 797e@+&֫9tӼUm+t GMITG][v0> ?eqCZifꐈ`DfI |J  gbxA7ټQiܷȟ:!!ќa@ŇwTGih4QEQEQEQEQEwThwThQEQEQEQEQEwTk5wTk5QEQEdź75=wR#͸p)m:B$j T艔M#Zg_66.Ա 3#wG.~U̾M_ K_ 4+-F$RMd:mK}% \ `z?v ,./?<]fMKVff;4fnK\U~6W̵JIM|+{i_;S1Zh¾o ~^2i%Ij6rm#Wj[`# KFVi]`V{ WbAf$rMkQ^v?5,Ў^~oS7OտhQExy'Tv,(RIoj5֛]U,ytIR)" TKcq+g+/ëk_麖4%̫$$DD9.͒(h5qS] ( ( ( ( (<^7 "^7 " ( ( ( ( ({㶵Yf$h,ǀk<CxRGNn.u`X磲kc$b> |R%oopO,lV0 g̑NGjT}·y:ShZz?jhڂdϗe$gXU ,vmk_!,glaD.Y`RdwŸ z7E6KM˙]ۤ2i/|3ۇ 5y%*[*Tqof{<%<at,u;m;|K>q+vGy.Ka# BtF>/՛L}mq? $ڬ4{YYwΊLm,yQ~vY9[_ g}2ω/m4#][L-2_kD9ur_QAkkvְ"0DaUTpwVYU_nJ^q_YuOf?2TًO? f|:tmvR- `bFIH`6NI:(*:K]j8X{:Q^_־EW!QEQEQEy'7|pпucW$h0dw[hVH# X~{5ݖjX/) *'Ӫ˲|'Rs> MDxr.6_3>~-7Zt~%]6uD!w7) 7(cg13r~oᰴ0t O7sbYH7sbYH3(((((}N;?*xK5}N;?*xK5((((( Kc54+3[K€ ( (98ةf^^-a'5,h((((>KcTm]K5B33N=yj_>T۟plFҢilbpV-JRMul*z>#G^7 ";77u.ڮ:]ۙd+=Ջ)f(;pwÞ 2Ğ+\ Xl`dI1cjB]$cwўC(Ԓ+|>/|<[j\/-d%A˝ ~> dР-Etd[ 7gMtk@^/FMY$BF@M<)3^࿇y`~-_cF I. F%8V0Mן|&rGǯp4/ \ v־-h7۱gf  SPrz}+,+ο{L wL\0 Æ>fIg#xbG[yO$+K'Z]^~/ß,úE hi%b7Ļscq8(RuT=tJ*Il(cXK}^Qc̹b2@f Ԋm?.V7i/VwR+ǚ7%?m?.{ፕx6hiq*Xʰ zk 0XVY>e]K 9[$$ZsbYHƯth6b;SyWom[NHtwIIufFp )`#\p<:fX(rQX:Տg|7C? @4zvK3:+oݽ6R l0rC)qu<.T]MCR˹Yc|m8 5?X.XԻR4|x~U8GJ>|OS5bh>=~" D pLO#sC0J Roe˖S*pK$OQ_>gEЅXާLi5gFb,rNfF pqIfQۏSz֏wOQ_>EU5_&a- 8co #V^<M3jt"c6cA/O_wTk5~ |C>'xG~$_iz͞]\\M~A3߶0I{ -~!g#]a_ L$8ic:+_؆ iuj-ϕf"glk';I*sLmx!?( jz~S,)dFVik-м-mkZ~ufn۸#8Y? Ck^O Io `5~? m!Ow$hpB 0W Ps(Eyɿ~5J Vr8SYexBhF:RdEb}>5G2?uk[Axs'|ަ69یP\_ KwiN+笌j3>W=ӯ巷YLmEHgd`צ¤7 TEKi}7VЭ`u)aGʲ\DTXS4niy9/)[E ox-|7s>e[\jlFP:)skԨPiԮ-XnORC(M^k||)%/d밮?ŸR0mM.  ( (98ةf^wC}ַ^-Э`vXfԡG+)l ^ g_~'x?Úb>-YVO2)e ri&G:Wp]ܷ[O ԢN3{0kuǽ|e2xBhFB)\2vfQ=3.;>'n?U*[եZZz";k]7d[m (4=FPo[h$7|C0 Gߍֿ.S?mεu>|oϿ._2?uhW]BT.s k?o\_]?/9U1<k:'hxnLÚ%VڂŊi.uT.T8v/z*OЙAW?½)8x/P-\JK\ꀆ]oeU%ʀ]O:%i/DqO4ԓͷ_z֕šWo4m>,w6E"dpʠGК+O:% Gߍֿ.#MZ އZk˚{ k?o\_Vb{Ii&8<fgW k[|=xL%2-ݬbn")*d+X=b ( (+k. BE$\`nQcd(*PEPYz,5'jga4A!FY,QFYUYs>ė>RHcȢR˔+-adeʐ?kxQ$WXR?m1n%yr :CU Q }'Oo"kxM6uZ\!/θ=cF?Yp!" ( (+k. BE$\`nQcd(*PEP\e8UVv_4ī ʙ,+*>oesE.A;p$k}c{H[tMS3Eq3EtH[ұH roO3+_V6>ޓxLM}TͺG4e[*k2H76 B ( (+k5[Bܬ`I$h]S$.jPEPX(/|?qaKij43il"Nn&616+wV{w}=JKon*I %gXL&@yß5k᷉P7̿hhظ/4.xë,ţݻ`־ owx_-Մ캽uDD$p <(((iֱj_)}[ҧ.WזWk 9 tmF+.;];Q֬E_i[۽E\M%Wae Q^?K`=:Sk AӐk(/j37"+lro7~58KR7û%J..4ki}.] \PHr\@LQ^_ BX{_:K /w b^2%HN$_W :f?nOar5G.Ƌ+ )2m ]NtB&4p85Df3HUn?ьʍ6h;~qxGWk#Qѭ!3;)yBc$-0u,WලĚ4[+KZv 71β:M&$i1cI t! |9q]MCGjJ b!w|WKZ]̺aựEbIs$G$󧷌!GSǞgF|0r|sg7f|SXxj s䬳aKA2Æf>BmzNjĺ [C{h-$sJȑUT(;|C 7v1n\@+cgG>nsyX0wms}_eu? &qsROr e*lQ\]xᏄƚ:$7Ҵ6I4XVr1e˟AUxP|Cu@溻[}  ef3*@ +u~_ <3Yxb\I-5Ly,l2Z"&dhǜ0|IJHsbVu h]3M}\1wm * 8W?}szn-nV]ZYc} 7(\(ȠŠiυ?_ag _ھ?._/ϓۿ;Lok5FHoaApƠ;UI@(ud_5ƺN5G$VEU+fDŽ:xޱqy|R|9w2MF X4QLa PQ_/㧋'<3O-rÖ t u1EtGlj |LOaӵIVP#2a Eyhχ>yFhbXxu-1 o#+K"( InkCE_ 5tn#[k(LB(AWw,HW~Z7Ŀ t_~-S.f9Ym,щQw!@aP~(W߉om-K-ĭgbr=aU \:(Wl=GƖo|yZ?4gI#ҚY!%7eM2Wk5_hmnk[[e ,7 mr* +#џ~/躊ئ-巙id؇{o\ F$y/2TGo~&y巂 B+pGd[dLՇM}Ex|gu2U[E-֝uj\Wܛ9Z? W?oߵ?y^GOwo͝Q^oSsSP񟉡bi[y$1{,H[3m|=&颞_Z`I)"d($#(;A-[v~ƹuoM%ڌ64FWY$RkL{6R 5ܩBgßM}{O q!bG( U~_ W'lj-^Jnon!Lo&DIAA@=B7k ,OCy>Ӵ 2y:Lb[X0'}f?2m◆{XE4e(UkyHsiV3zQ@Q@Q@Q@3mnsw2_h7k-zVeiA˰FRG=GӴ3:gmtyo%Ipm UI:bup̧qZ_ |EJ~`.f:Ϗt"t"Y\m",q (r0Ff+ M"]ɤYJ"LPŵ7yjvPDxMkj-%L0sh*Pò21UV` g[/%5{"+O ֖0GmQ >W_?߉wYi(F;h` VJʌѳJVcf!At?Z=bXڢ=o,V 76![(wG ḧxQ@#<OڻI~Gy&%,,1dD+?9أ+?[IQU]|B`E4pq2[rʀpWj (=/ϋu+{^HwZAaūK!n#*lyx8?7,Hn_h^IDy_X㵺”c1` % ?H|&м}|nlc9x(ccsŒC x4ZK71 X.d\ <|Xԯ--ښ-%W<*l* }E~{"_?AxFѼD]8mI%UBJɵ4䂍[}t I2k3;vI^uԿ ~*jfS7]k^"`چ 1}T2BbF_|Q@|cGƟ~6 Zխκlbf[eEWv1r‹ ~=|<7!.6uBa6wͬX2ne6CF۟(_xA~bIh>5=v{K$G-@X0So.6d$?=Α?o ~6sDt"u.'9i-eK*g)e_MP?iO4bÚg›+k{SL3hٹhcRйRmّxypqM?ioh 5kO-=4^D<~|ca V\W?g쿳<7wf}ݫ(#|&axgŸٺݏ{vooIYNUr_Z:?~*F4 |5çEtU<3ebC2[Š_-5G5 ƺ=ڏ#l+7ᛯ iW\xz;t)nӠka'ޕDgW|$ Km{L|AamOk_oSh%ݥ7d$Fd. b/>6_n|yYTIW,6:ܤ$# wO~?| W_.> 83[MjV󩺾y?u.Hɔ Xm~ j=#N>+. (Hc l||n8S#2k(~-ϣOυ.,Y9agwvk.&X`P8o82lQ@G|,:ڝ6 +m.coO1yVsQg_+»_x^%m[>*7V%F(Xb!7ǐQEQEQEQE $K9E@w$(p>l6kE[λY٬_2|]2u4g]Ϭw>߳]g]Ϭw>߳]g]Ϭw>߳]g]Ϭw>߳]g]Ϭw>߳]g]Ϭw>߳]g]Ϭw>߳]{ ZċRYmK(99tta2pA?75GT|H:}ff:}ff:}ff:}ff:}ff:}ff:}fft>+v_6<ês#qNv~2Ȼ- ? k7Ij i r:nFC*8du_I[81s'{=_ナ/dF/cƪ2|4OSQNl{˿iCHGvUPIb@k f\c\:D2nv QH~O0_{ƁnZ_ X /d]M58Ų[X#󋤟dO9Zܱ7WW=S[ItiOO5Ot7:[}i/t]My6YdDPGwm~̟{O ,&בC=SJ#c7pvȇ|'U{sPeNjIW2FE,,ȹSom|TE++ɔ2|(OrÞټG}n-NM$O]qhq|(oanClsOZYdX#*fe$_0k7}W Deˡؾgyk%-o]ZvYgVi<Sn%׊5?|F|auWK<4b|cQ _eN 7&.e_?7Nk?fOZճi >ۤ[4U))c%c 2HUWw ~%|"$6ӾMRBI%NH#hrmN,Koo֦'Kh0IEN-g-ˇu@>N!Do?j>ho}OLQ};Rskyi8TDue``A+|ii/ m Sl,M|Vڻ1D^YSOW ^_ҿO5!3DMSƿ"T|H((((((7~y9ICӌȹ]ۆOz.v1k:/G#J J/5XYA-u}]Rپ R%#w$v#g _ ?Y?: HOt%((#'.^^M+FO5].f ( ( ( ( ( ( (<T|H7D?k7/("?s+[Oh/𭾯i7-㻹R@f'8V#$u'?=|ewß9[OC5k/ ̺gd7w+]wc )&.HZJznr|x|Uod[EuO>MR4MFD7ztkiJr_٣~>x(Lu`ZÁÓ29(HVU>5w0UbIlFkxy ?/an2Iآ$qd꣊.*S4zyyykyܺW䨞}lE|-kV2lj\!Լ7`S4W3i~XEk񇌠񦷣O[Ť wro|Ewm$~R]DT/6'b&S_5//ZOSOG41;msn`%(|i7<oej(7D?k7/+g5OM(((((+to5˟"/0dB\px$ to5˟"/0dB\px$#:VQ|DQ[NZhH̛Cgwvrv=-U|!'1rݞ&?0tg&sVˢ_/%|]O|X;wNVtAĻ}I A55W;D&'շe$ :g^^=ibΙנWwW {ᾛ6Cm%5{ԿZ*Qyťw?! +Kҵ?xB=B6Bh[&;8f%yCvQ #'.^^M+FO5].f ( ( ( ( ( ( (<T|H7D?k7/("?s+{/~oѯ@t=c{^s$Uzr+r$uqNײm&֝7QyW?eQ|K+ _ZFNPK(ݏ~S>*_,,мO>t0~ѺwBMo].Oi_WW"j5OQEQEQEQETWi]O4#Eff<$R2?j7iu{JD LIˇnlc~[K99K5_}VyY>8(EF<%boKM[k?I`]\F@qUlv6f*Qx{o4[=#HNO.x :O$I$I$MC/ x+ZnGX@GPρ˶f9f8$ZfY֔pW-i'`0VYU+QE$ :g^^=ibΙנP^_ucGnd𾘺7QGX, רWM#÷ZpoGo$pmIrH B仪y@OGS*Oxg#gSmg7۵~+h;?6|+1f7USqwPG>.to_2|]2u4QEQEQEQEQEQEQE~&zEy"&c_}^@'_|9ca_O,Ue#E|Eo?XW]кÿxcMmKZ3o=d]ۑNJ{Ni~=qbpJ2ҿD}Ki\Z{ N]՟oO*^+kKoA6x3&ҵ 0.8$ 9ּ?<)o?vPh^o& ^XyUMo0'n1^~SZSTܜ[a} .{[vTurKgZAmh9[xTTOn-#d:L3S/|^3xGy-.\3$2UP'|sLJOqiZC=6SܭPq,yHG ̀[b A^6zW~]k (խ[8l"D l[OYJm%%+_ ^[o_i:iGÐGmItMpV?*u2\} Us4o j闳J]2X{h"F.0dp1Co?Zf#ngq#G-v0s/2'1 ׼o?X|SZ̷ӛ^Um`&3$3 e>RH(yV'|{A}oxC"&Prel]CDZH%_4#_k~("Կ5X|{&6hmɉ$W;@W~?k?Lj΢(g5OMDMSƿ" ( ( ( (1|gԵCm[k{Sؖ@)iz*a!Az \}_gOD{E-}8qx*~ҦݷK08FIL}E$6y]s$ݶOfx'|&_#|:,,\]]Kv UG@$=Lϻ{ȠIu O]2Bp=If=z9aNT+Qg93Ep`p5WŻ՗N_ʿW( (>}|4gLX+g _ ?Y?: +2;T\Ė:޻y6+mafn%+{7D;bj0o /ۖ,w8ΗY8`';܈<'};jϹ.>ӳ{nq2ɳxp1Wf VJΥ8UU t+٣Y7~K"6`T$ ܓ*2bdeGhUм= oW>^ wOxBed["}u- He@cd,)Bjoi]_ i\x<4t}~st]Nh'xouwį:fcᛏ\^^6>E >Gmooo*H îVwEP/~|@JE> VJ_WW"j5OQEQEQExǏS2x>5okm;W*lM61 n:IzumH:Ds>LYF< *>sE2Hc%{ŽyO uch˿֣Et_7Uj?f= /w%QEQ@Q@>_@س,u/,Kz|%g/o< y@&$qn+g@%>dU+;ֈXvwqJtX.>{a6"6wy.t(((((((DMSƿ"T|H(((((((7D?k7/+g5OM((Wi(ּuxd͒m-M83|ۃT(+%շ#Vz~-IulOK/<+'t8.d`W#?{ OE|AWv,Ho$Iw1X"g߳ Q$W~ǿ%sҶN2zS^?Qyv^9mt_Oe~> _YcD5oQE|EPEPEPϿ/,Kzy$ :g^@|ViMڦgkZ׆d nob)^O%B, @W^ xu GY?P+H`. G! `#c.X2/wE kak]jW,^8"_x/S3CsELi:tGWZ$,oVVl {Ed| pKY&#'.^@Q@Q@Q@Q@Q@Q@Q@o?ȉo>_WW"j5OQEQEQEQEQEQEQE~&zEy"&c_}^@W?hMwI&V` c0;>elu|Ư[Wv#c)zO]Ng˯  ]Ǐ,G1b3>xݷ (>?v ,./?<]fMKVff;4fnK\UO~X\__\lxR̚!.w4hܖԶskoS Zcc K@+p((((zŝ3Ic@?|4gLX(>!6>ijzsw ժ i,{y] Y|_.bUqOxgƿ3E%si+I“)l!w>W `-%<O-n7P״hdHSJb2s#B͟p_'X?+g·fh損/-¶0H덣=d| pKY&#'.^@Q@Q@Q@Q@Q@Q@Q@o?ȉo>_WW"j5OQEQEQEQEQEQEQE~&z}WSmk43HFY $א|1VxQM_!#bUAf<?sj:C [+yM0aUl2$U+2{, F;ɮ˦ǕǪT).z+yv^}vWGVFud 6ҋ'띹iPPLJi j嶖yU`mǧ𿄴oi1o&nwPv!TbI$ֵm,Ub69OGQ_;~ھ`7ꚼΑ[Yʑ&v`6G!9|m⋸7M*HѤ`GP6; ,Nrk)oV=9}E5J=8G敮}E| vrFrCSb2~o]𷀴/ĺ>Iһ/1•1jbf*2->V9LS2Y0mF{$֖Q=ibΙנW_@س,u.1xnö?nlWm/5d?opF#$;~nzWQ@|UyImH۳:g]X6c7g'9(2>wƸ˥׬ד| pKY(((((((7D?k7/+g5OM((((((|QZL[vI8]]V!Tq5pIB Dq\쑭^+84-|I n.6A1>.j vSɪ0LfAe#!O ጿ~_]7㵞X\x`gJtrܕ*UҒOgR3\<:VK1?gO-xw?6FW /Eږx@E>{yJ6s.UԺ5yáZyvGcy\Hr3M⧈$>^i9>v%0l Ă̐ ~$WQG2tah%ep<eq>K)TbvܥvEdW^Gܗ[#v n|_,59I(L|,Tp=z/g,<߭/0Tw"խ7mxE׵=*6G^P9('1ȯ3kMMkk230XH&a89qzGQ?I}k:liΎ(gahMʭ}+ji_yo[y%;Vy#9s{9j܌ ۓ4;iL*Z}n_4oҭt ^_[KgV@F1LZWsǗK?]g37%à v- .~7m@2q>Dp8Nݣ:Ȩ&yboNR⬷sy@xV查\mr-un 40Xt`97?>%Ěb;M̛%2.8P~nAe8gW)R7y4ªtW):O3Ĵ֑Pͻ~xWs9>Ѭ"~$Qk]٥ć$d37^`ڊ륗(W~gϳ\[*o˙+B(g _ ?Y?: HOt% ( (2>wƸ˥׬ד| pKY(((((((7D?k7/+g5OM([~-Yg,@lVK$r(< CEaV* f_ۅbpҕFF._g_>jŽ`&8v*?i|ExI]I}=Kg5o@d^Yz< >MHX~ujp[0K4t>wihм(g)RrJfvrFxsk~f`+cnz*u˭&Sk:&$Teb£nte<XbF]j2~Gx4pDs,ppc4fC-uϋ~&&L&=3Bm$. s*I8֯dJVQK_S(qgIsSB$;wy6x[!vf׵j5tth%C؆|F=wJ# +;Evݚ\HrII3uN `ԩ%ݞv;3O}Ѳ2- _Z($QC HkwUTpzmy"&c_}^^V6n(b (U.pJRݽoD%*!/+*qFCJnL}%u`jUzV~'t?3= |+JrB˷3rMWdEZk5C)zO*xiI>&AK׾ N+tߨ<-HV^AmW޴eoW嘩.Gj$ט}_ZSC#rBW³|Sԧ*wnGROwo3#3HOt%zŝ3Ic@0 ( (2>wƸ˥׬ד| pKY((+[φ3vLj4&J^ @` N0W5JirRͺ+ni6Ws[H]c ĨH8;]c*ЂA ./飰_//nE1#'y ^|_{=7>O˟^Z% >kYf$hY $na-nj4i".$9 qe$ xbM%8۞89?GxĚbK%S$(y`~n htCMcc.H%K*q+umea⼚ٵQʕ88%Ld GB1Y.n𗂴YկBLM.q-/9g<R6`]O+O#O%[qC̻ ס?ռ-;-R2\D ƫwq eI4R7`A׍_8jFwQ5g~.u04~ϙrwI]>no]2aooxtmZ̸]\,'_[^Oqqv;U1~vN43> xx4pƦm>)\07;)f>ORMv5X43j[;Dm#Fb85 58Ā_\Z98#шN:d %ŐT88Kø|e՟9R\rr"5;*LJh.ufIE+Z}##9&9mGWE|Y{$mpUfB1ϩ_>7wK;Kn&Ճ_I-vr ,I#p+tmk:UH P8gzWCjRȱ5sΕu+YVl:L}m"גst>i?hi CO$fIrBm*lѰT'?v1v FK:oI Msn0#6͸H2q?G}T=B|erʩa.95Mۯ,:C!6*_ͪ+ ҼǦhZL:]`VmBs؅PY'["V(d`<=_IgK/DeK2?B++8oY9UMSϛ{.X43qdXHGU٥]=rG⯄G;X]gN"3at<[:+T7_8K+S_f2kRV]ߵޘ.}G^[Af^O '?tI8$nsK-kRPqmu(njNZ1?~Xfw{P,I, C ԮZ1/ʗdSUGxeo_7)x+U5I>u{P+YY}R n^9c 3 nm S ?vQ$כWws|OԿ>=wQ¼ ?vl3]ڏ.:)Wim؈/#M\SZVa}liaL88bK;8 CI8WC /$:7#.R4f0,t:~~7AM71v+]kĹ쏆8wLmڱ9s|}V)ܩAG)%° z(anF|omA-?GF)hM2.}iy+BUGX?hNbp{9-`͙灞=sapko43WS+Cu;f:nʈ/#gaw*\sNxwƸ˥\>,x.C9敻$q.OTIM||7⧌՟I K1 +ƙfr&XA;cӏ{jqy«jsĩ9|jଶjm߳Q [i$־~#8C.`̑8GqkFmrgI"( O6%9<1fpHaMyW2 qѿfmW~nQ>D/'oݞ:>`5׆elg^q ( \T_4Wi~(z#DMӄ{E?CηIiYmIy]h\HrI9HY'8+Կi߆uj:Z[YJ>H7f]7^*ݫV.kx1>/lĶ;d?ƺ??Ԍ|9浟5ʢוK.#1b9w~M7jz~g/E9F ex FZ-NtKx -t9 5<}3g3 Nxwu *{lfcZZ/9R;~Fw2[er"yu!2gTDN1'7JnB+3Q>]e 8U Y6_9UYxtOWVt<)7wyMv9rW?yM%̮O`O`o ~B04>^ky^W.+;1Q_Ig爴^g!Qs(ҨQ$a sZZ:ƽK2_XiH8 ϋ&|TUbG*5{ w; W ;E.x)5]=V )P) I8`O`d/j+^ͳ8pONç~OlOcO]?ᏼA=wƩ? -[?'Ck3|;)49.]+O- `mp=NT͟?\9\"2?]G"2?]]+*->ز\+}Z;o;ۻno[oScd*A=yLPYYvC`];Ac*GuxtOWV B. 8Lomvl/HxY6Ldo>i~:o_ɧM;\M-˥D`e3DI;SEzEx?φ^|=aklK/Fu:[9"`k|>Ky$PcVi((((?C,<7e%亸d͙癲ğIg (((W5/X+ tGˆG#gkxdUb x¼5]C_<7kzbYi!hMo> Z<u[<1,ȯ-Ω(D ,̡nb2ϸ <`MWL|-P%ͥC MṮQ̀Zwc!&e$&w(((aML4>˦iYˆ4cP2I'Т((+9]]bxmMvz 0ۚILbC0 `@^5r_Qzkg-8}`Vc@ |q s@okzd?^hZ""E\ī'Svfn@&5_vZ_ XesakOpk%ʝnXKc%qPEPEPEPEPEPEPEPEPEpE^<9s_kiuYIw1"4"Xe_k~*kRҼQcRAKy-c'k1߲2scEap$ʅc+G<i>)AuKlKYFcۡ._0yK1-r׾1x+W}֧hQj'#)M%-BTڀ=Šmxg#Woھ˯og~o7x_&}S+`[i-]OȅcZ'3wŠkmOxm/76nfX A-xgڴ}{c.ﰥѮda+HSVuʩaPEEπdž]<1e-F|%0@Σ0Z6rv2Y!U@%HK;oھ}'$Ucwq u0T]BIn2A( ?]GR5{+m{X̥"G'ƹz_&fя2ϓo.>S>_\|SJW=M]VZqtIo$:y& y"O'uږ}M uR{.5K{Lܛ%BUl>>wυ|Qh/Ӿj^Lz/WRsoy$REЭW1CQ5 v0ZڔV";{(Du eG E[`;(]CĖu+CtQ<=6uQyӔ7Iy\,Jm&2sZ7D@zxJg4_f I 'bvkiXİAmo8cPQ`*p<]sH_ԼOck}z\ a$dHAkxnk4}PobH}%5=C>WۀdTs'Q@?]?=xuesEtN]7YT%O,ZKxH2 UxO|F|3w{>a;wj7csc=7Z(w574 Ğ ,~eu}[YR+ <['Ea"V:ᯈ~,uy{D.l%Q`Q@_ /IZXkըnǕ]\.ܷd e&g*z<1eiAz!Sf>XvSI (Ѣk::e}܋ukK."R#8p2Gվ*xzU׃u3݌[{ vfHgX̌LbG-pP͞Gth^%]Mu?ںdE@7Ω#Įs]9POVMfOiw\\I}@5:Wl/1$sF#e AV(((((((ode-0.11.1/ode/doc/pix/amotor.jpg0000644000076400007640000003323107403321525013414 00000000000000JFIFcCreated by Paint Shop Pro CREATOR: XV Version 3.10a Rev: 12/29/94 Quality = 75, Smoothing = 0 C    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222," }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?\Q~(3bPqF)أQv)q@ P1F)Q~(3b1@ P1F)Q~(3b1@ P1F)Q~(3bLPqF)أQ~(3b1@ P1F)أQ~(3b1@ bP1F).(;b1ObSF(Qf)qNSKf(?b1ObSF(Qf(?b1ObSF(Qf(?bSF(Qf(?b1O&(/Pcyd684Sf(?b Q~(3b1@ &).(?b\SF(Qf(?b1ObSF(Qf(?b1ObSF(Qf(?b1ObSF(ILP1F)Q~(3b[yA&W ` 1(ճ]aQ>z+EF?ySVObnFѫFPTkNkbd-j(##dQpG#\6U, PvVL P~G͚<~> {_T ![`Hlv`q;7ŗo/cjb5Q!vznh=қx/:=Gj7`vf$z>ͦڒGhI$s1drl[NCo}6x9 sZxjT-mlKy 2 6r=9[ TZ$[4"+xwrN@ii$"(\4\rhJo\ZqO$*tqT. RHM sEy,|QGKt̒2yZh*z)B(=(żGm[Nӵ; Hyg{>+4Jo5(cל0oo F{w!a7l;bSF(Qf(?bLT(?bC&Dyd]}OjմӒ$x)۸)6)d#c@Tp)P؂RHv (ei4J(~`7p:ַoѬ?H`q6YcYR;YFIAnQbSF(Qf(?b# ҥf8[4ḞA!N}\ XApG5 ?֥`(PQEQEQEU[%] (޾ƭQ@ѹG]:n+z.S õc !IoC8Q@G1O qKv)q@ P1Kv)q@ P1F)Q~(3buXԅʝG9)۲vW/T6ڕwv !q8ӸQ~( 1RbPkScG[ o-Covp?ݵ7_zde?1Z.WV\F?+W>kSZ(I1^$xQf(?b1O Kdx P~ixqҹ.ъcy%,GzT`S]z37@$C/UN̤QE!Q@Q@Q@U]CQt,%p,$xO~ӶM0ȉG-Ϯ7ŻPaAiѦ3=P9d-|[}麮"Rb&*3b1@[tmbJ%Xr6V'w76qzg%OmC^zս7S]4IE&F3b|K#v1Z8Fs;a.S?uwW2y$)e*' :5xgMCdwrDhE{bR1ObjIVRˈ&0YXUY/[Q-Bx|K}.+|*pHaMwOo:7G C^'JmwxN:jHntϴ@ }xa= zi|u-SP𽗃|;[-ד\jS1|2+ұKizel`a7ĺo~ng޲l/C ֶ*6>)IE^L Bz?3LrrrOcaRXr)o~wNz/8WL]IJ(!/W<_+ڹ3>1i#[H}n_ߝr g_/>^c3M>ukl0U*]Y/?D%sU]+X~ܱkF=BH22 a@^&{FE-"`F!B+qԞ(~"=os{zDCx5ƳAZ!&13_V{%r;WJV#b/Zޅm?Km@7R7 $k|7OXF%+/%2:麽vZnentxgy"Lt uzޙmnf8N$J'OTq^[аeaTմeR5k-HbAX/[vWq5$y}+S5O}1 jz\qN]i,kkIYrI&$VIi!doM5 wQLCD=[t[ xD%d?3[pkھkCϹ|-z?$uJ?¸BldEKw1Ǡ?~#x~ r{mFY׹EHZ=͞ }Nwai&gb,I+h%ƱS8^c#E*X`]P̉jCkrWZk+_8ZBV!qOzeʟx/L.??΢{=q+K+5$%!'zXP%'lKy"~8u?+TBIofp}%t{uWYZkip[ĻR8jT6<?N.o`~fxyr=F_בZ.U"v~/?P؟X 6QO;XWz.4Ɛ(9}+k]&?CNT#-I]UdztY<䭶0:~zn R)jU5y1+cGSUuFP7Z/[NITRy~vrTr:D[NV%mskb:;zW|L5˴ʭ#rͅ'18XD3_?$_ʸӱN)+EOK}|b|6%֝0]2ps|>SϨj^-XK =o"bY/ͱWyHs$;/Cn?u|mDU ǞBF-oDڕ 2zQAwpj6$e+ }S~^ok=G5U@О@F/;%L 7y7(8>8 TQEQEQEQE-PqF)PqI}bQZ( ( (8ga`F'edWE%{[oxU\dk/c?5RW=UH׎Jn9+j%[JʎJ դz̎J43E#z=XGh ($Ĩ}k- f >>aVmjf;W.n?ުO2FTt䦺$*ӝf)G\b= ;i ,TrO ",nX< y5K4T ֻyZji{ϳ99J+~C-K!{>b:;zTir]5Y[ާփ: kft`գ߹O)!).~F9flOꜯ^Eܝkh咽N鿽|W%{3zC(%3#2*^TSO<߆<]-zM99k0$,f<4g9Y6mEߖ/~>mns󊞊((((((((((((Z@m1>HWʑI++T:~}dTIF"⒮G%dFr)+kG%[JʎJC5#G%e%[JGe$hfrtIen$%hʰP=K}_`K+WaտjVZXN:@+>mnUck*v}Ke[H.'suy=w lN}>u~>`r?>Vnu2JL7탃c]t\d_G̣Z/v¿eor[؊>7[V-jk>>Չt2oe_Q~ϪZBpǵ,&ilSyLslaTJ{.4.ܑ4LqY[61N mg?^Hux9N{pG:O y\c$ᅅΟ[DGyv8[?qѼ?^}ZIo &c lWq +5,mу0iU\,(Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@r({mnWWE \K^د?iRv޹޾' 4MxŲg_7>l 1i:OxLRU䫾 fw-{m?-?4gzƱ㒰5G%C}% fP2@ Lgown%̬XYBз7!6V42ǁX$ٟhÖZ")Vv3V_t{$~-P. V9[8ہw=EX[i|.S]CICOc]pp ,Q"j0W=U #I$I%TJc])FxVO>.UΟ$feiNōTr{:umVo _٘72vxԤVt8Rq/槛ƺw_YBIa%27l8^sxz߇m gcA j(((((((Mwp;V@L *zmn:H4rT(W*Fs< smjl+̀M'԰}OjѢhY}mo!bGPs(7]nɀH7s@(V] ԭDmV@7 1^pO\KXngcl/n-,-IL_y׼C-Vd G@OWUt.|YtmF3ChS*1_)n}摍fŵT0My系X42~^O|k]J' \ׄA [։죈6A9=q;k Y9TRs}l;Mk%AzumJKy?p_Xp drWr(TIVrnϱb9+vM4rC)HVI)d(pRBI*֋j^$6?=ϯo |<ֶ^jec,eLuZ,aRvMt•bl4_GJ횪'2Y$* 9>Ҽ]{_SicV`=OqKu5k ռ:;i2*gJ06wKߋd\Is^ I`\k )7a08@^ĽN-c4E 7֯=!5~6n&$L;0׬/J7L r;7ш\|2 #{iGE{Mԛ|ޛ^Gp8eȫ&tmȟ ??CWb§/C_k ][դHYcd$vb<&o ;LWIJ+U͏#?<ڳ5 'CFUe*z+ϫtJMwxHo;C"9g9K,PFA-\zRT \ƃzŮt]>F?hȯg;H^ [ |z?LM𶗤qȆ+CflrX$yq/OG dez(1x5CRAmKT8#JPn.IjčKε{xź~q[izuw~Fx.w1.nz> c)iR۰ Q{:[՞.-R@#5u[;HmRX-M,,p$LS]5s_" fi!L%PI<nӮ[y׬r.zqjɝ.q^ߩ~jm X珶ʟPz+E;Ga4{AA#yd:ԯ O@=^ykwK*1B}}tz'}V>Aڵ+XRQՉ]?[ nf8B.c`qZV<"~-d! c;v2sUxBZZ}o%Rql;W9~eԗ6O&wIAIzO"oSƾU>:YyRǏL|n<:Z\c-!rsyʣu}U^eO6̒jzGd}~ .-v{ꢿS[F9ՎK lsz_5-kvZ]ч=z&Jf%¿~=FZ\+t:rzeQ^Q@Q@%=,c4q%A;;v>|ᄊ=q+k;^֭<=]j+[ۮHS{N$[R*wKg35;74h75a\bdyF vUQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEW-W~ "?AcߦI;K 6OFkjVKU[+6Hqyd[ƾ%/[yZM6X; Ҁ=wbS߈t ᱛ]Iu 讥T'#׌;Dm4kh5kսE"k@N8@qImh5ڗUHT[K2 gԢj8}.SGb/guq qFbN\lsR*F 2FA+a?䏀,|qy]ND !19''v;hX0|>#&M<-[Mg #pF+ES1|3ڎcY>Z Qu~ki7)ʲ;21aUn>Aqೠ>rz/g7ws6~:x 1Qkii'I@Σ$dIYsޕ\)U|QyhZ%Μ{rrs^Ku Y5WXٻ 9ԛh@mI(IPxKM1O8Q@-ulz!qN?X[2@woMBO$v]O3֪SF(cYx)s=ҷ \wG1RbT)1RbPxI1@ \UkE,gt+V#@I UƷ+`Q<ʢ$+n74*3RSk>q%݌rh'N+*4v72uYW׽ai=0$wctW ի/jx}jbjpڮ}*WHCN}R\ ^M/W6 dmwTAݍ+y>VK}ܡOd^X6ㆋO]ßWws$4;kXoq\ּ]uv 4<O FI?ytֽ+oԟܸZ0QHѶF+mI~|m^*:͵~o^*:ݴ6ԛh@mKM6ԛh@I1 5k?pijkҺ_ GC_?|B>-)T]E.AWQ4\ל'~^;R|H=zrR AY+fQ199?ZoZ>O'ZX 4Z&jia}DM0ҰjW(=ОOJS0R⚳ UGU=G֧qH$8Eok .#I?Z\uEXKMDxKLP{Dqס>\[k;E /]* 2 _jhe(Xڒ o_'bɯW4C0,LTTWCF4rU{!`}T㒭%s43ӼcXGxdWWa.aWh y|rUeJ/t;e}hXc.T4 ?`kc[K WCꭊ]s$($kʴΊnLfMV^CmsgR$l{GjRǰ>ꜯWD2PNR~VwbhEVe)yşt9uM7ٓ3)g`:p+TV6WOiҡ{\߿U:*q0PJ3iY+iW*Sڻm?[fud70گt.ѶpFU:wt~;mK^S,Ĺr3ZRUfGQP]Cy Cՠ$P}A.(u;AFoQJ~j%WD!ѥ+-zo77r5,KB;A^R>Gqy5ޱ12aq+N^k;@~{OR-wž'7$.z#ExzO|O=Kmr<QEy| һ CrAZq3ҥ?Y x 㝉}i+K!SxT^J*ڽ~S IEKHjLi*zT/%M{ixiuqM|,|XnzmS'&ꭥJF8ż8빻ɯ{ZQn]ٛ1ZvGWB\'AhZF7Hc+Fw\A s~jshc} [˗ҵXf d 8^N3g5ԝ=[\7⼿}_6-qW8ęfXX5 .+8aMlg?Nf7VQPl+e$V)ZF@Xn>C(ȥMnS% uFoڧ_μsm#Nh,?L;jp]k%-^M3XX#9emďkLjukˤc4wMﴋ=̐HF Cz޺Jڲ[=W?mtqr/>Ockr?}oWμN[oQՇNagil2F2Ij]d HLjq^k}i}is Uk3G#]ۮcn]G_|/mw`{$~ Wu76;k_ 6","t(ҵ(J"k[ϙ RLpJk7Yuc,P-aFMUq{%3Ee?4׷/%*\9 2: |'I;נ~#_X5omdU&#>ǡb5z#V|E\xsVX#TOJ#Vhk;4uc5rEw/ZL^g{=DMg55gTLԌ 5 .PZiԑ@k ZV-p數k¼ h׾)(Ɏ6a8Q6Ec7H(QEQEQEQE^#ݴSD ?Zouћ- wPk-٦um|?*᯼9 c,k늆#(ai=H0[iOWWC븥&)QՐ{Ac{G?OLW{Z{;sipsSzVrw9g.J}vs6V.Ku>klB\ގUq}붪VDcY%X[5 ,m W74Я2[9m쨫^-g,7rF9=2@?CT׍%B" M5H%xtdbi>V17 ץj>5d-t+>Nm:$u1+/tݔRބ~lʗv$`9N[ɭgPGC;x{L]y@ }F+"Y]c4M#mQ)q^UuC5ݵD?p?xԵ o|k`~,rē@?4o?6˸sIq^E6آy)5yZ]vhh>;yYZY¨Ac|BL֝5x|/@|G>BGq/eOMrnvGz =q?UOX>xvk$I[b,l/$ͱJ!ե a3RbFzMVn-'qԊ|so]&1qHjyX }2"O?*Εikg䀶Ozجۻ((@QEQEQEQ_5/ #^[Kfeo.>N8})ExW}cO/|g}iuskıirn=,3q"⯈t/ ȪGu4c.0A<+uOk7^2þm7Kɮ.<Àʪ}H#~\e{?k M/Έ.4<H$ƀ>Ikc۫Hs?'+Wq}[fk[{#";8@aCK^U9!4p+ur,=kh(((̼s+˫X/2(#w8&FYFⱩbEE h}U^ "rFèa)cI$Qk79>j БGqF(ʼ9;ԢkkE9(;c^oNjw?*(FQ@(((` cm;@JjM%^=q k|(nddWРc]_-}27Z|' ڎa/OG}m0?@+Z>Ǘ[wwY(m- !TQ@Q@Q@Q@Q@Q@y=|y|K|M9aԒ8&B <.0rb+᮹j#ּaybƞxM %!~oFYjSihv& XP8>Ey߄|`=;׬=KIӵ_v6׶W,t8#&<rt  \ߘwBWTpA oE j#B8/ᯅu i:.Y#\ʀg s( ( ( ( ( ( ( ( ( ( (9_~uu[KP2;U'mRE @JgGQ^51RկgL\*zԾ]u-sFKOjb$)o廊+7%5/b|$ɳg~ձ?z=g-VЮ%RMfh^.Tѵkk׋7z~h:G;=̺riXJc :^o;8|MF&w, ~Xa`{%Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@y3@Xm&4ZFڤJoGDGkIVXK[]*A,MUXKfa b#KFmjMmѶFmj\Q"Fڗmh-mqI#Fړmh=bFmj]h=m6Ѷ"Fڗm&m&ڗm&(=bFmjMmFړmImIb%jLQ&66ѶAL;XTӧi6O> >6r:Q09liD|D)|\MP{R`=(CȫGG@@G#x/GoήmlJrEPE6x2=3}\?ռ jtz=ýJя\1-D>OCY:skhXiJ5ݢ p1szW|`5o5H~#՜jp?LkH]Bj77S4{yX>wn\ڔ_޶ 0LW1/:We?W[jVEt8W 34M]EA扦jזYH#꧷AR6Z MV8qC ue+5/ ߠZ;s($T4Wʸ>Dk~LakMz ;$mMKC.Ȉfpsz!n fIh!IOLx|Y݀R gf6g䴑J'+ϗ*fU)jgQ56aяֺ@ imz(b>~*mFJwB RbbLQZ(hXZ,yVE{Ud/[nѡ&O2:mk 5ەLGd“5|Id]?Ҭr2}7 8Inm9bd{i6ԸM.MM.M1RmmI 'u&]ZK8ޤf3/GkmO?\s(208$,We$m2CQbџgeI*rV\rU(I*IYi%YI*ZM$ 'f$a$h }J%z•)^L4Z(ugh@9$QT#N3kE̟څM\!\kX@Mk8$ TP3~ͷsd_}^!/x~7'WkG֓W@y$rU ՄzhQ$ %f#T3Q% %ea%h DI+1$ %K@j–JԊMw+k Y()^ޢYܓ^-+իɧ288JKՙ?IWYx3&~G|R2#}+񝬸ּÉi{OAcS_4~t?/b>8= iljQ.sNȯ=&e+&Wœ,c#=HtBVG{ejPnํXxd;՚/ |_E%#[H0 S/ĝ%A"(* %@PVWj[dD&A˙|=BW$,ǹyuk>+^r,Up* uh!J|T1Lul4Rt\)L)T"c)*c:R54{ МթRퟌwn>ht;庽n7~n-^IyrfV]Gc^t&rj0ai# ( /,18ֻZ׬צ(̑|G@-MFex"Eա~BF\B=sIjQy#z/A#Դ2=NUz^5$ϘkVZvO".zDVA#VVeb@Cp¯RFF5-)&gN=8>9Hl5|?yH_Id- M裩+x[.꺄M-Ӫtr*֋sZJ#TF<G[%Ґې@,{nsCdP4:1as bp,> +xr:dp+rbұ>D:~w(~5c=&0KCNRb V#ͻ' |%m洼Q+cְ?.4{#ܿF>`nǷi;ƺ+_i`~}4z5o sIrLpI>;qڥΟ_[q?1:FvgEuOnOu8UiW?[|ׇbG@pR/311Z]\ u{t S U( cLh bPygƍk(ؒ?N.TW5/< َc5nVcKSeioZk$[G袻 <7ڑj]?kJK$&A`SkThp w»((Eş^[x;kIeh m$g\gڼ9$28#Ҿsimikv-]vGWjn[hC$ﵟoPqQtz!4zqY֖ӭf鰹S:ݛ6$0uJZpΒ Nk7hEWhfCT/۩GFLHKP(Fd6y* 9F, <1q/LuZFCT[ /N&HZ>FjOEM&7n3(!o \L3G ?)[? 9[ա|~k~ %Ƞ }B r=WUH+m*CzzezaL3*'^d5f6ATwtP222>bfCbWI s.#G3T&д~#@%|²́"<ۂJKh.?F,z$rϛW.Q` K y|ԞOv6vx^= Gnʇ e z%P=<=zpzCp,,*cUw҇j_۟]J?Y;t hW1;=~ '3);*kfgY K^^*0ʽC7_gn< W;w%o ~zZ" QEbQRO9uB]Mcj+JG29oç(((kHU 2 b_x;AɓO7?N+vWzɸvKόW |f~}E|yi/ncYBPuIu/enwʾ(BƮȬ;hW-b(NqTEϙEZ)U#+߶_%=X; >T;-ASkM[ɷ$dpᤷ혃ėL9?;z>MK[HV8Ttϩ"cFT`NDf^x{Hɹv=X&5yJ&i훰yk<ᶧM Q^?ZaqΪ:E{Rk:YA)=>wFɃζnphr0e$ЃZ~%֬p g:+9y6w? (_o.$I̋l!_kcb$]b҅]7 x%U?Č+.Giw CEbJr8hhn` ^:|ċv4W1iI%c=Sfmu;[&GT[Ne$o/W|a7kCV%ĕ \S0%zpz$ ) awP\E]7p9]z@]mMf|A4&?V~Wo` j-E.*Ν5xu5;(~c8PSE ( ( (3={FLCUլ, E7d~t7Z+E:u2kt=HRk6|i`_g͏?9KXIx* Ψqy!GG\5xw^ e\=q]AxNU^ֵpZ;s#qXH߬~i8ݳ9{Wi5k^Oe&[\CJw!Fe'x#ۊ>):4j[꺉7öF}PQ6b@o/9H^Gu&qD XcwǭVSS}ΞaŜp{UQ@Q@Q@Q@Q@Q@l,W6?XW~.rR-Ȯۿ;oE1*º~dw}`ߠ~}?tIrW8J ]I?}Gm6^vIJjpzEX585Y J C}dIKUmԻϙGUڟW/m^=.o>+$w$uL<᾽ek'&M[yD'oѶxO8灇^% z:3Oky$a_z5TP /qfw!-JN$7l546MW \JHT{{ PP+m yxƜ,ʐ۷g]UQEQEQEQEQEQEQEQE?`¼5zƍ&}BOJXB%2=3WLޝ賅d_5d5CSV$ioI+J9sU9l585W NLE\5(juAuO7PUi'WV7< өx8vғ2 _|7q2&ŸX4߷qj,CW0:Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@moSmռSzb]'IɉdckO$'욄?e5;?:-¨$Czc־,oAM2VAϭaK&+n&+1 >c?oI+J9E:5ˆoCwM~-g;gzS !wT3G96?Atz!-5dn_q)XK7VL PsUp,n{rpouV,|{Z([ϓ ?S7#ؼ3P^8&:,-S_t"ʿ|_n%Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@RN೚-qv+r5*Ҵtk7p/lX?ᦉ5^DfG8VN.u+_͛/oOӯ^(F~(ZÚNwizn]$f4,m+Ƈ&jdyt$'@n>?h-? Mo,7aEkyo{e嬢kyG"rH#"SxSݝ/vCh;vW-|"[6gjy]??}&et#4TEMݽ+k7N}fZlΊ &k=.>}$U1V,maok I <;,ER((((((((((((((((((h_+ bkG/&z{Wo["ƣ>$<&Is"N S(YcI 6;h!bCP 4_c=ύ$Os 3\:/{gޏ:>%[*s<N?3_MZ[]KxPrD ( qJ|3|umφV`%-2T}2`zm/XzкKvҋ~}VF#ǥq 双fNyf&aX#`y>O\epXYh+x# DQo : iIH=w} @ 2Pj,(u`t#"(((((((((((((((((((((((((((((((((((((((((((((((((((((((ode-0.11.1/ode/doc/pix/contact.jpg0000644000076400007640000003012007320713017013537 00000000000000JFIFcCreated by Paint Shop Pro CREATOR: XV Version 3.10a Rev: 12/29/94 Quality = 75, Smoothing = 0 C    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222," }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?,Qv(7b1@ .)qF(1F)qF(1F)qF(1F)أQv(7b1@ bPqU|-}JSրN ~)sN%)hK(PrENGZ1M=EIn(;SF(Qn(;b1K1@bPbRPbSF(Qn(q? ۝NȓHP8 ϹnQGӼY,Yż݉6 2ӯ|b=/b-EѤ=SVy>$e3V0Ē)wPķ;Y<{sXiw:|6;p6]Y4iJi篕o:׭\=Ie$S+LW-|I<=Bigy S#uLRSQaoSPDWV  zYZEjuxˈyq)Ms'־ptf1ް6]>mm 1yk)"´}ӹ'ứQ2׷CJ5\w ST㸒!uV%]]Ć(bv)(Jn()i(xOKlB7b1@ bPqF)أQ\QLRb1@ bPqF)أQv(7b1@ bPbR_ݦz\klu%Ie@ϵrZh:G|3}/_xSr[HTn V6W^.cmvr)8-#NαҬ7n@;dO~:>L_1lyY-~>됴[aWL.3ϝ;WZjZUG ͺHWUm.mYv$2xx,Sibȷ/|?.ŲmF? ̙-f?"[_BEija f8;t_(08$z+Ojv._5+kZop1gz;a b$"َ1-~*DUG/z*kkX ڧǘǽK9iS&!1( Za\ҭ2l)Eӱ+C??J隮M6B4ma;A'V1\zjS[dX?]Ьl⒛$:`RbiԱʿZ1KE&(-QuQv(7bLPbQn(;PqF)أQEQEQEQEQEQEQEs;_Gns 'dDpC1G¼#Nzoib4=`GOq\^#NGkJϳt:esx`vuڊi*JB) 9)-FSQev5ee'LT}5ZD ?gy?LV~?ФoY8ˆcqO~{SqR@?xOPh((((((((((((((4M!F2h<w{)j'cU{(pIP+HRs[ֱ}\rww(iJ?ol}Maŀ+ +Tvs^8񅿁=sk-~ry]-yǠäd2?-Dokt#v./ln<o 1 2kV<BnKsȄGסk}~6^h&wKӖ[#3F9Y 2CHpzu$g}[K NvT7pZ/e,.歪Y5LKoۖ?.@==)WD.}K٭ԛePXy=j6Τɨ g2*'al {~Go%qTBwԮAB𪺾/;h$s{s_=O rI;I'r t7"( qm%_p}+lAhLނ*)tRR촙ҥmo@˲=Ҥ(=GWi!Tu}gNtuV+KH`;9V;O@m&k2 |ujCNu{ȥ2cӯun<@tvB8B)Mķ85&I9O$ezzcY ?/:N Op6>w|Mz-.t=bx1eb\Eq~#5|𮯨jy}@zm)9(zUņoku}%&׹BԁQEQEQEQEQEQE;m᫄_9O?5)tuAa"?Zeicc 0ҹ!C4%PYi`I_Sĕiګph%Q;R'Vml9oʘRܓkm&cOV8J>V1rߗAq&iՎjDu-c%3uC0<kxdp2$8Cۣ֮C^f*?tKb{/nUnEe=>MH_^}I^$话1jO 5vz UY&c?NG~xsz=WZZISt*7x3)*@MJZԎX#ըpTMwHi$eDPY&6UՍ i>0M2Einy=3ӂ9|-ПšWmNKt (a$sǦ: `Vτ.ugⶸ]Z5B1%O{AEy9gZ[izeܻ`8s?Z/:Vu_PԴ\ȬvmI$蘒67yޭi*@ dd@z k-uZ펥yhkk¤$}+8ϋjkV-…ݱ*9<k#ÿ mmSu[裚L1KL=0zUk -/]FMu]j@#8#rr}ϩ4JlhwiwA289;b:(<g\bbhS`:Q>]Ba\79_1$9>c^ESҬӴ{Ig%3|㊹EQEQEQEQEQEQEU N:5fp;qYD9$h&O&++iY6N1WUw{ka("#+~#OzNc˛`tL}ve(N|_4ܩSҥєw_܂Lg}: ;7$u9#(H`ObW; s dߺj&2Ak ׄ lOL7Q;4XL.f 5CPԠ}mn8geǿh&mX72)9V׍ ۃVߋwk}0M .Pⶭn[_ͩL9V%>uBRW%ºty+ᤸa v$g+=*h>)awzYѰ˦i۠p,fi B("H^VkTy_t_@;'D+AkiݏSԟsW땱6ܡr?.κ+K[m:H;<+'*rHM ߰EUȥYSrzԴMy 袊(((((((((((lLm_ fd>ޕ nJi-uOVWߟojI\'#_Il5qEraZG4#WT`B_-U@PȮT.Ss$CFccJiJvte8#E(XZF YaEв>kmc7?ku]K C,V ?h:nkTHEReRmqGPYIl G@1Yv}5\Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@s><$GvV?-3K?7fUiw-rں5 [DRzrQ=]33O0񞎼6N mDl jfl˫ZKm=GGS1U`-!2h7i[G˟Ǡk3~zZˍ9Kc-2OS=C?Zf/>rLz~5Nyo_.?OS_9fgOקk|NmT2 &rCiec񬅅QB+aZ9J}]bĺo%KxRuUT$ФҾF!-->Y 2t`pGWK>Y s<7_6 ~֟G=9Z36Hj]fL*';5q^DC0~U߁-i{,Jt-VFR`|Gq]w) =A},glbV)HcZ;aOqi M8],N6vEMRLV)t2__vrGef-gbzZ _3Fc ]߯?mku.^,mS)aEPEPEPEPEPEPEP\˭?ᶹues5pBȮ]YӴ s(X<6f7yc Fr:׻h:řJ^*+1BG"?  hb^ΥM[Am]Z*gx:vb=)h1vOFiV^ss:M#E 1QA]Od |5-7M1ya~5k*0u*4쎶U8~[==+NGbY1}gTE-ۉx'qj&ԦLX`?E|iͳjZR5KtS٥=喏'٭KF2O1d>?GO኷ ,5T;v]<-KQ^QXzl\y]I3*;1 vh:M$J)6Ulm*MUGB8#PjVIa4*h;s ʌz-"!Q#)]0Jμф7=Ne:?/M~ ~*>(ԢQ*"?| -{lӷH?ƓaKvpy208!7u3US!I, n:l1}WN`5kO9 >? տU]qh ?⫪ꜯ]K'23oj_U3-sw,6?{Ulrzګ ?O{n4nxONTiv&hͽ 2^Q{/fqg,†OJ6Bg{ 6BřUzz8&x{PӮfy{frAG)US˭#~)5bxM. HvgEk',!mZ[xeQRF 3ؚ|x7f&-F+a-؉w x֋wU#)"-gs dWvI֓>@ԥմ䶏@v19n;v?M --c{du(.Hp8j/[O8{d4M3_n=Gt+k٢'5^.еoͤo@Ƒ }8>H$x$U%S8qj iZvxS'#Q=p1z(((((((((c|gGf] k>)+s|_g|O-s]0z"v)+")*RV։oYQIW"ziiy-k7qVtZ_&):d2֝,.wZ@e&Z \5V[Y!}ӨS-V4."zw5BV˜Wb{,m`%좱oN:T2XI$5RG$z#z+c#꤯OꜯRWrI+dldrzqứ7W8mi idqc+*A+(((((((((((( o_M-,JΜ:}qk|CO2|2p1>?׽d&цXdETdЬ|z)+/ebןfx9P>#$hՊJv)+Dk%[*)*rU#N7Qfj7@h& ݍL9E&޵tN?ةnOaT]?&HdUdz|U$zLHRGNWlc%z,$U)dldrF_kWgۼ7eԞ{G>%uLv^.hBO9YJvG3:K1$Gzsb([AER(((((((((((((]{w!{.a.aG(NxG'nN~ڨ%{̱G/u:C[¯FKG'r9+(oFTdu8eaqI] kG%Z.9*rU&#MtϜ?5ֶgU$zLNI)=SJ6I*S|Es=ē}Cvu:Ao+* '^oR] ,V{nZ=];ðrpoa=nW<_bUQB@`KEŠ((((((((((((((((( ]s6e_* ,>oWj>ۘ8Io>ƽahgdXdDJx \9tmO_řUV tj[ՍXm*O8`?ʝv$ď5JI*$9'zWt^[YB9{('L,]VS9o ?ް:G?_z]vomE * -eE]_ sN[E|e~."岰>wnہƽD~xU\{]q%?pSǩTWoIiPiկ-涘Ѩ%<gGMiL\BOɜӑEwQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQExjYRy7Xdzڢmj]GII$^UTT_^qo - 񬑰V+Ik{;~uq8 ?#~+QmEk`Dy ^vdt!6^$+ʕ鲧i~$6<.=._{?ҧ2Ģ鿽vQ+z+GYִhӼWsr1\*m VρKw6+syXKnli$p~bHlEvMĺizTO:1Ӽ9?^m5/)xBϔyk׎o kZ:ߝI[j[ qѽF,C/[S A|w4[ [F{`{^*Ե?fb[ }+cm ƠJk;mEcN=#Jڽ@\ p ^?}PwmuwI)' ; Gt]WBIsnCf Өcf)1RbPxQf)1RbPxQb&(Qn(?b\SKf(?b\SF(S$8W28QzUg\~ {UI\ӎڍE廂ۛɪ3j(z4jQq9mJ(ԜqݕNjϓK eXD_ T)0^M/ZQu*- `}xeH#ڳQ # ƿhU5iHJ8o}ܩ¤~tENR>ԾO]RT\ ^O/W_'ڋ5{}\ MM_hh&&<ٍf[j qڻ8\^ZKNdGsV>y$S 黹Mv]K1I']T9Ԗv= bF+3Q &*LQ#1F(:6{Vcxr٬$"X )vu@n.=h5 QI._ݔu Mq) >-k[I' .fuA+vFH~AW>G2[+$G#)hb"_i wj0"&i]Gn4g*11ӧz֝dF)pduf8Yf^[/&Fh$sQJs/R,ζEӵ)K(gUg\lUEP0p:-G(3κh%3ֹ)UE4tmIWA1RbPxI6{hILPx&1@&(GLT(ILPx&)1@ ?_vָyi ٜǥwخW6?g?w/_f j( ( /)Dנ ٩K=!+|4cFicz+E1Z5F VF*}AfՔzEce0nkp.5Քz _iX`{7G :5hv܃ΟCPъm[.(9aCMTx䓇j(?K s &9T٩I]f7(FoVQ69*rT43F7Qf՘h zYa4Q=gՄz_GN:{QҤ΁5EőꤏOꤏR/%մ&uD`ze7m1dI)P"_ͮh ֻi8D@ H{ط:|ŨhF'2BaN EIֲT+k2U>FJȮs%;m| Tּ:TbU#]Js:Dg2! {t2\m9SΡ [8 :zN*FtQҰukrHv @&2KԞl d^-˙GCy~E1os])1\׎+eiqr{1ZVkZ!yʴT vъmKnhm{[VS\̏8 h䃫Ǚ3#nxYhڵ6s-c̈́c TtZGckn"L6|[LK/i\FrC8?Jg5|b<70iK5]3N8wy \ܟ VfsLFkkš64K׋yz`z[hN_+ob3oz?ҦCرHz+<|D>0\[Ommk(4Tsqvw60iub}F+hȤE6Kre;\}IHkByC / KY5bŒQE&(-:LREͺ][I(R@eulR[>dl}}|Woo^WrTQEڴ_e/#GqQ#kjW:ƥ*O;E+3ָɺX%*?e$4[JV#%ZJˎJT4rUz̎JT43I$)%fa$h $z4 3N=I+eQh4[J,drR6e(f9kMrr5o C#T15AoI+*S[:/j"O `3pRS^ߢ?&H!ϼt!3D!q6yމ6wX޷#hΉZUe/[,tA#4G)`ݭ]y<7a T9bs5mӛqf[ɮ|7Q_ xwf+_F=?\~0H9؞䜟N-Etz͢+*A=빯Mb}Q& Q_GxwXXTfEúv5袊Ģ2JV6БJ+bO~M8{ƀ*TVvИn32 aP|:n2If?O?:zfX!--w~T<%$#8#1^ݭc81+{)JiAȶv8.;JIV#Mf|&~+Z9A5JVbIVRJi$xr_[\jI]7_J,d3J$ 2wʑNoU8[i{9UA+% _}^osW>Jc!5$Q`(JVKeM'Htu:'Q]$qmV,` CuV71ʎ:V D%~cI` G?B{>7ZpOB OZηƋ63\r2P)x810*Z tȇ@1*EP*Pk3%QxԀ@J H:vw?ʼgtq\Fp}^Cy-Yumwe'Uj- dYޟQSwzIl4I"a44T/Vv-QH((((Z("vydC?.^b-?Ŏhn/XGVczVȥ 1|Mҷi.L8~WGX6{}^Sx N_O眼΀9-GS発vR_k[:/ʟU`fP?Uj)5p:KOc u ?º =R&ecUt9;I=sJ|5/3klL7A2sףx[V6M:UYF~ysԣ+h4ΒbRp?o*Ou϶[02~=A?^\w%;)ح)QQ&Ϣ+ĐȒ#td`Ai厥}Y]K~$E,qjѤОh=P.-Yaqe<9 7~qzhѮS!7ß^q<[<8Ի@Mv~$D{|TU$Q+ws*Eyqge)ǕnsI;6fKI˥yw{5y[ߠ-If3%չyu{X_jzAetF AOZWtQaNa#扡62۞;!?}GZޱkl[J`$dE ~Y5{}c`~g^] PX$WKC6c0ʆ@7~uF_ka5Z%‹|זRyyS}^k>.>[ĸ)qܓCWjJ*E@Y(ZۀxWJk_/E_@ -njk1Y娤ުI?idܹa6coi9&+Ƴb{yO2sN2~?ĨɮLH႑ҼVF|J|9B˦K'FB dgZ-p$D!ɶ mwoj.R{ٖ`>2vǠUEs'ZjZ ddj>*Ӵ%N=M|Oz[[!BP=qzemWwglw$3n9;Ծ%klruq|v}5xw@5qs4Χ$p}Ԁ` %Q M0/i:+3J簯!8BEƐ mK,ٖ^Jk|׸[6#^v`3^^Q~>.H*^\U\v ((((((+ƷcdN~\EҺ(2Aׁ]eVnLt'ԯCWWҷ:dEs?i`1@ R❊\PqF)Q~)q@ p7ݢ$LnBddd{ijt6D%EӛmXMpp|>V>Vtg{ǩZ̋oˡ+>){Urg_o y_|Fob?e?aַ֝rWRܺ-T7YLmo* xWeFݖ̈:WIcUIz:ckҼaHm.6*q1^:ў+x{V9ǣ]zsN\Ϲ,Ҿ-i "mI TѥgM*[ˉ5˻-<A eeđ+ki-k&/q?y_m\^MP>0? 髚N *FQEQEQEQEQEQEcjuqlc-[ |<,I`!ߺʽRX$Vh90GM{XjlI}0dMW_&^?:qKyyWvB1U@ U;E5gŤ'gyz#c߷~9뛝gR+ aOʰ*//vKƭm=KwpF-+Tϔ$k,/ٔz§𗂼7^wiu LE dcqH}>=.7챵(sָ(e.&~N]PuByS?4Ƞj麟)|n?~j^4ų4CZ/[Zt"/sb1Z ҵm@^N,h cKKVǸ>✁wJg(䉢wEbr3<-s .s9"b~uxYB΍;#HeOιW4`i ?#@ <x{G,a9V).T~Cᇌz=v5yڣ3HG=5\]]q4gbOCY4K6 gm$7SPexWԃ#\y<~^>knk~L}FF?_Z m #" άp ^wxV@{+I G}+w@+۸~u 1ACzoJͶQE!Q@Q@Q@Q@Q@Q@Q@Q@Q@[Ba9?\mi'+vPZv΋$EgdBA; Zϙ&qR)Ûw<~C$Q#w4s%CW})k+𯄯4X gH2w @ݑ؞PGZwkhrv?Ejc_WG̖#%;3ajޙo-mTM2V{[ʞUU='ԟJ;SMpygg⷟Z$KVpz!5q;4םgIn%bo _,lћ$RAZ݆EA3$j C@^ ,4 BYC̶ƒC {EO% q_PQEW7O C!{I}뤢>yu FẈH+Wi͖?Ҿ|=kA`9WjZ]֕tmÐGFs[iGtl?OkxV`XlQ5tca[} bTŬI{טY鷚]}=wΑw۩I9@uQEQEQEQEQEQEQEQEQEQEQEQEr|G]Q_m[Ϛ*'?@kX^5;0;zg^xCk#ѭ.} >0{V/ ii׾ 5k+ĸYdyWo@ w^"..$#RvIrFڍ忈~Ǯzl̞c>_[ GouSSHeEElՁ$q赥y~ /^BD-vW/99fڕvޛtu76 y^D.AlfPJ2:גᯊ@֗w ;BʾZ8z~ii+ʶvۉ8E xOoz4Rr]j6]q^/c\$Jd&zkj>!5;Rv``vndXJ0MEPExq* '`#]Ίai]A3ci<篡/.OD\g_%h#t[ũHuY  NFc'{_mv⏆]{ -JY$8@@wG\niW4 R:x~Rn%MF]?F^6/x~hRF1@[qWQ.?NmyY'!*G׃Zo,}#\`SMuPp B8"HtT\ ((((((((((((((((((xVvMWW񹂜9Es4m_³xyG`VF :ʳV:LJ3^O>fpyq"7`uǠƊby Ir\=jB@Ϩ*5}6\5Tҁu۩K~9#:A^ErV /ܴ~!y.3*vqs'":WQEQEQ\Ɲ:OYiZREq#e @r קWÝR}[R쎂sʆ' h?%㯆-o-~#A$N^>S{hs5pq=@@Wu mWJMm{g*z2VQEQEQEQEQE|Yz>Y;Fi ̫> cO S-ԡ4%__$xC_4QEQEQES]Ddu 0T+]wa>>% A{7 FÚ H?Mu?h?> N7&!,>e6?: F z ?_ťe\~XQxI Mxůymis]῍<f+;voaIkuv +Hds^G*F"q-+d/4 zur.e#M4Ki(#ߑ Fce]\$ ʍ*Z0Gjp3/$_3dgq}QEQEQ^{_\i߱řmhdmXK!(*&B4RWN9*>QE}EQEQEQEWc_ V!+7gOˀY\20qʞßjG;?~".<'L~.4G&g\AeiL/|8m5JWkRimdm( 2nݸ=~2|n|HӢPH;2l,7&HɮΙbLYj%$Pna`vk]L'ӭ-]u ~f'Zuމ_^]XZq4*Db2X[Hy'XcYd(gduZM M[Wk>A1DmMçŨLdHUeqHu=ͽ6R,\j'$ܒMKEQEQEWT1qL/1?jqh((+ʾ"~?% hvN\^dg#ȋtʑzָOsud41-W#+3ׂ_ڧ!\jIQ9`H'JgWߴoTI ("906̉h $۶MǍ. `-y9&fK^$L0$xC7O~[ϱXH thѥo(Wq ˜<EtF/u"^~=~;WO<7p ֝Y_*X}I4UT99},/>(kVt 7$tcs2EÏYoO>y8#/1I'f'w4Q_=I1>+Nk6xɢ!zl ߆ =<1٩ڀy\9f3I$^/h%<궑_6卮VVN5DҾ xK0xW_,e$k嗟i>*d.X=O  ֿb 麅αYkKa+&g\E=sGyB|nt[mscp5}2Hi^ۨxPmMGFF(%s_Y~?W?k=Nl:3r3!{UQEQE'd?H#tJ yqDd~5Gm~=cBk5Wom۱ۉ(((($I  5YxdmmGeA6zoK?Nl@K׽^.m]mPb]wAsx+y9\Nπ|v"jTԭ0 ̠UW)[ Ÿ!mMsf=̽"ڒB=W F_$6~ L%мAgL!mȘIOdS\Ӵ'"b2[i#{ݏ 3ͳ$Wq+Ku-zhTY$ Q$*?? kUkDI QE<)hSA 5qmg)dB ~i5o owcyex->`b&l)!'o(((($I  5YxdmmGeA6zoK?Nl@K^Aeux~dV1[Vџ?GO|״x+:G/ i&/c4mV;KЎv Ҷk?.ĻM|:ycw] GpcH$gĞ!׈-K[:un>e5XŞῈ<#xOdfu-.Hm{}-$UF88u{e.F-id; A\K~4մOXi A46nr諸ZO+K1[xK'O?azHxP?!  Z(ʯ‚X}wkO[CC{&om##~EQEQEQ_=I1>+Nk6xɢ!zl ߆ =<1٩ڀy\9f3I$]=W߰/'ÿҹ+OgQT!V^v7rs2Ίyjn((+O3F-KI5;zrW !LYSRUc} [O?azݔCE"0eaN*` d,n~/Xs} 5{dd`<)h((Oğ_^sYŞ7M{_`W6m1=t&N/#6YI$袊Dw^?W5}ExWS1y{C_'DtĜ-3WxHZj֋3@~Q 28d#k((OO3F-KI5;zrW޷ xL[KST_(𧍮NOݱn@\D"+V A f_߲ƽcSm9kR wC}_?kKٮEո p7I8 tEQEQEğ>!C_½Aa~պg~}^%u'HճmsO}-dY :~9*A?TQEQEWV'|AAaFcQ=U 9+ [+Nk6xɢ!zl ߆ =<1٩ڀy\9f3I$]=QE &j+ o>&,/|3M7-ywGyE|ˤFfn+=mR>-)klo[P8W<?-3^KXݰȷ_ A8ꥇzw Qgo kln퇺?ېgEQEğ>!C_½AaVOp|;5}Rz5Qa}K]A AcDEQ!rʼn$;?>񎡯_|fR՟X4.- əd ( WEQE}QEbx7 jZMf9؃XÐ@"/:gߊZڧE׽_@EQEQEQ_'EQX3f7Z}kyGv V0W]6q'~ &<; ÖӃ.O*Gg}g QxI]O겆H%Pr@Q$v_"+V A($|K _lCBGZzB|6m1=t&N/#6YI$袊((`_4OssW4QEQEQEWQEQX3f7Z}kyGv V0hw_>XX_/ mNI#`1l%u8 4/m-V[xja%ъ+矉?|CZ¯Zba|q *ͥ>w7̀=o|$n iJB %G'/,yyI$]=QEQEW߰/'ÿҹ(((+((:ִ]N$ͿIfLv_  K c|nGC[}.ح5Tsx}EQEQEW߰/'ÿҹ(((O۫ ieo>|mwr}^Ίɘ1[ϛpO*Kp?_Ρa_}oMy˦Jpf$=xBI_Ъ>+o~/eE[ou-CU[O@<.HRj?tc6*xFԖy٭fF() ֶc&-.\GȕUvI`au[ӵ.%\<Ā# :[~Sfߠ{FF/k8}GY'OǓu{y1K\ [|D<Մҥ[",oblxǺ_Ý]W+8 [8Zk%b5I h:}ֹ#h$Y.[~܁09ſ/Og޿PEoܒ-Dl0*;?2{&n~] }be,#!B1u$\ۅ2oB(M?<=/6~!gh )DoQEQEQ_?~hJ毠h(+S?<+sOk~mq쨣,{*Oa_l_MF#>c]i. st%e~_O/~pkwW"Iﵹՙ# 0p\hΊ>+AӾ7-+mRn_jZ]lP634F*CY1%q>=}Տo'^dP7WPb(|Ɣt=9+ xtOu:v3<*"IPa'h|i"C7(tϠichF g_oCWgM]:CM2!s]k0t8B3(['P> kkɼ;L=>]1dQ #5V/~j wj:l7V.̒=/㴘KFqҾ̱6Nv^{5Oc0oTœ0|/wl_h\Ү˾h'ˆ-#Ϫ?$O|Qxsд4K yH~i؟AwQ_'EQEQEV7<waFbaW Ƶ La?SUY(n[Lclo[Hxw"?^hKLXy4_r@s_ x6__ rik 3ZgͶ?qf_5zr::`d|Ǔ_nxOƞsN'ܼ.# (+M{\ QEs8_zCj-9Cjin]n<O#־}]/f{YqLYY+͔(U↥6Qm_ݜ޷dC#GY]2`r Ys!&XiVxu{y v̨v ?#/Tsc9uxCBKW;t;{%MPko'º&?6?{[-i$WuIШ1da;FM~W⿍? Oxo@(޽S4K<_ZY˂H.#5~Dk;⇇efvsjſؖI@~+|c72->ZL2:5~iK’,ˬ$݉*#Rrz17ڋEMb~ 'm}Jնo+6eP[#)4Gg4mk:-a=qj , `rZϏ`'k{ǷiƦ1~_0'-EG⏎:xcD炮]yKKo!E`l:i/_O_Yi|3 PF쮮K|/N_>u}6m^;*ʆ$|S.-\ĦKwV "TOZ{\{?gCxg@IH"9w[r`Ìkoj4hnmSK4Ia$fFߛqkxK?sX^D|%cdȂ68n|b u_~^--.`&;9Řd`9?oW޹g+OY7W^Yn< /ʪ2M{QEQEQEQEQEQEQEQEQEQEQEQEode-0.11.1/ode/doc/pix/universal.jpg0000644000076400007640000003177507454127423014145 00000000000000JFIF,,C  !"$"$C," }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?Qjv)q@ ǵS{R1O1F)R❊1@ bf=?b {P1F)f(?b1ObSF={Qf(?b ǵڌSǵ?b P1F)Q~)1Lb{SF(Rb P1F)f)1O 1Kv)q@ RR RQ`3bf(?b1O1F)֕|ڛI1ܮ*Gs_kO40ZC"OxnYtWR-ZYx@rЁ2ybÿ~&_xĺfޫ}¥Ƨp#)9 ;z# P1F)Q~(01OxQf(?b Rv>'@|7 7ω,E0ϕf!co/w>Ώ^ Z{pcQw">b_|=ᛛS\ܾsuq I gh+oV|"֧]w{sdi9glIb1@ 1F(f}? -F8c&!AV}w@+/]Qm5{#$9}6]OoM3ѠhdHGkxmmb$ h0`;(gu|0]W:-0CiprI~O 麝wA&d*<zF(Qf(?b 1F)(I1@*>4舘#Wb-P[xcfl^h;5J|i},~kx~|'rzq3ݷF5&Z?2#~'UףN:w!F*LQbF*LQ|A;VvCGJn, P)kV+׺{}۫y!?FR?sbT:M>yÛ4YhXn`?GFᖒ~{Q%O.FEZ¶ׁ]% #J\>% Sz$QH,\qO%1RbWЈb&)(I1HF*LRb#1F))1RbRkG'|;.4Җz|$${ʸN82[SF(9?ZJe*5ӎfic !)ޘRS1Lup4NR1LutM1Qp(:c F:a^±'7m]xRLznPqՌU |[ })1R(I6X^#n}[{hN 99 +&MKUfzu &rD2x%m WK'bi?j`l[b5Z_z?B҈=WƾNUY<}vx?3DuK gIOZ}TSU<asU[/*< j7idi N okp_\XYOYhr45E VvwFX扚 x4]ėu=XW9ZhS<fh~g {Ekze51Ikg]j-GHh絵3ȔF7un ʵJ~i}G%JV3"+]acKeXT`(8 x5~u6FXnݍ8Zw2J!G#uRKcI7ՙNJWM9=u>ډWejn?Ui|yž/q=US8nx|gRv>M_TxυLdQl:0}x>x6F/mcؚBQ-;mV#j՘ڹ~6Q=gf6hj)+66*j)+.7QIPqY2)*oPެE!H>՝Ոޡ; U!pe\wůj,86FIB߉\bg\I4Sq?Z3We/65Ҝ}TnL> %e\jEd-a[?:+u/Ex>%<)/X1\^\[OM<F+f<;'߽sdxf?pWdcՉi},Rk:Fb2eHpEK62GCns f?G~??{\o ofٻi4SFF#Cް#jѾ:!je߇h-Wuzk<]J"KjBPܴgFf6ެEڬFF6C@^JS b7ެ%K@j[IP0i5|DM[],a|뵻~UE'"As+7ݘS]Qn>9Sc՟xkC VAsïч#S[5'jAtd)~e;±x1ܫa<1-?@x5M:\ZD?Ѻ7kǺeѬ8`B?#TfxՋZ xxF$PծUfdP3R>2qe^8J4=PW`PN8rz]j7WfOuA>7T@PuMuDZuMuEuKEu+.BjB\ RRHZZ-HZCm&(x'HʹP1KuTwV][ C+BTPn/<18ҮO?f|nd{WŶKkE'8?NΨ//$AT=⹪a=V+Fb6r%߅.ǟNKBJB|;{=kOS 5U:{L6ѪoV#jcj6H:5C@^UW3LoLC(T jE5B'SZZ.k ^{{UM#_\#.-:p:dƃV0u h,&Ku)]^^J`y/[K[m@ &:[^!Ӵbj64`RG(݈=x5y2& 05~Qtg ]DףxSS UNq4SRVgPO ɧ W*p$_ZWP^7} AZ_W7^OS4AFK3nM PVGr!avО~gx%_}|_3ΩKg+B2DVGUSћ۷r+;:Si2ӧ^&z,%B+L9)=ɬӱwu 0'F}>7T@uA>MMԀbԅ KRn KRSKQp&-M-QJ}/EWtQ@Q@Q@Q@U4 V+8.LZ<_Ɵbm~[خX>Gѳ:ƕhwWtYW="ƪZ֓kV-eyn*ws\pєcާFYi#wKWO$}W67UYjvsܯXM{jН=iܒ6ݢ%cU<7<h s24$BB)cV+f ^5R3C62}8>Ц'*6Vvva(Q߈C~nRy a|sm^Z+"t7˟0[8n (:Kg{k>g8^;c]F}#x_? |+jLJ#wZ,ҤN!1&Jͻ!UH#QK@҇qّwdm7H+ %̅$3榻 W¼3ǎ( (o g`n%rx FNIs_9+-տ^e3ż=;N-Rc+ɕyG |k|oᘛdI<tw9M-s80Y5`c?k;khc$qơUpsarj٪ ^؛>kg S>yx . K 7{1돦+:O KOs_MP8/u佞[H,Ǘ (aG(T/"EI#"pIDW«3Ithd1mMN1W^$Pt;xLd?PF+ͣV>[Yw-$rT=ߕOtZL@*y?N>\Z-ޣ0Z4-[6 W?.#kp5>OS~(xO<;z5mM֢u>=v]ci?o?Ȧs;Xq\1nuVoEa}^G !@6A44?}갓#40,}VK7Ѿ}XFcu7}o@Po@ o7o 7o  }eEWtQ@Q@Q@Q@Q@WėvPpy9Lv6v+r-񕞐d w~7cukV ʪ΀r>^7.xD ]=װ=G.#K+R?q܋PgY4 ƯO{'odEfs^n ?:ψ_XW<)4ZFei;Pdwfc1I&k2ZX&{+Q^Ђ(9jzs}+ġV)Њ*'t \dKZC̃,-ᗈYtm[cXDxaNx]wӇ (Ar#gaY*]u9>h*lHQ^MX7VA#IX.hɤ_.p~S~`O[x^wW2s}/R}~" ѿި}?ؤ:w(XFz:yT[(XItK]-o;QThٞƎd47Ѿh[?Kw ok~Rz$˸X}V9GnNh?v-d 9v&IM7R?K9?<@uSc(`((((^ܺI!$qfv B.Rf]:-4YKD~?#8O/׼Sxo6n){ݲ5m[ܟ^\6װHdᯂ SZrn5F> A>R1=ߛ]ص.]<#sǿ5Kۻv}esdl/__B"H(%$XAUzNʲe7 =w%Q^(((((( :jo`<LP xpt4+V_+tM4}-S)EчM&}-*Hi:PY`Nf:iدU(,_ KATPbSqQ@((((((((|w+?3X=f,u7RBv8܊жԴɬft1̬ƭWu+N7ĭ_Zn/-uVe-nϘ9PQWџ~0o5} PVk*Csl.T,9,Sk0vǝ }ea}yokEiEO_3|__Fn=Kvlk%GhPh''v fGi_z(߉S:4kM#k=BK)WR۾cC Տ|OsGO,^b[M2IͨA^( K(xfި_M@-̿\*8۟0op@96-,k MǶ?鬷:G&Xd9{4PS~h :j/e]ih젹zX7ýSG?Wvri %kxI;32(((((((((((((((((((((((((((((((((((((((((((ode-0.11.1/ode/doc/pix/joints.jpg0000644000076400007640000002067507320713017013430 00000000000000JFIFcCreated by Paint Shop Pro CREATOR: XV Version 3.10a Rev: 12/29/94 Quality = 75, Smoothing = 0 C    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222qR" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?j]hj F sYj3et^mXPAwkƊi@;0SN:-JQf]B8%;/Մ{C}ELq{elQFYi;`G=9^ݔ*}+QQleWFʱ_e&ʱ}~E{fnb{! >'I?,LE՛F+ $]lV6Rl_m.ڛe.m.ڛm(jm( *m( lQ!Fʟe( lQ+eOMce&m&ڱeAmOmA>Mk/5cm4AeMeAeO]8J]_e.ʜ%.ce]WFʱce] +eXF`(6U(6U(Mce&m>(r"c<+Py_]KM| >29V08 KZўgRW1c li^%⅂( aȷxw3+rWt&}- ʁeu= ӵk6 mu,'" 7 e}%^1KfUSLgcAԱnG&BJ=J{ )svAP;;ϋNMk+wr\YG1=z~O6t] %bY!)vT)v +˫h@<Zxm~ĖA 9=+㼞Uy+~J^cjW}WVCGϔ#gL6~|Im;@~/_q]'ʺAϵGfF AEoI F>wDy]g}8?ʝur1H(e ЎOi+wQ8mU`=xjJR;l|#>>,e.ʛe2Y!-)JJ*T'죥5 >2+㢝ЮSGe.ʨpПH.&UOኸi=VXFʉ(Ib(1a=yl8%Yaw+/q[¬*|,MX6Ѳleh"6Ul )6Ul )6V~z!t/y>^]RFEkXRЛHLr*V8v[~ğTdg9bXkE}XjM(n.x5Y\KZRoLD-H6m+}wY:tbH\:ڶOe.ʛh')0~&u!M^Li\eE$Ȝ(.}lRt9Rr|ǧ5"#!OJ_)}+zQO !RW)/*Puv?OʧJʭ*:ey_&>6%S^ף 9FVϗGTo.gˣˠ (<ge(Mke&eY)HR+lVvRl (( BV&n_(E [`d_W[F+Oh$k0*?_0?F*~: {֭Nk^5$3Ю[T?z~pEˮ~d_W$X8;Ufi,V@f@bzm+: os:IF$܇rZm_I{i^篙ᏸjǃ N-"l& {r?NjFOX0s+P:]kj>hH50ƚ:Y%j>GW(G`h].WZ^-Lm _K\+X2l=bkI#" UQ ޙjPuWr|ǣ~ҫ*O!+}##מIf5u-tkzuarռs=hϘn5>#g;GQ 2cR g8<c_^#[ !Yaюq\FTZ\AlE;Eu M_ \H ܧ}V\S7ɯ>݌A];{z 'I'\{I.="ijFnBe8qXWO͵ j\َO赜ޅ#t?h|2 9T"QgWWv{Wh6"qkMtQO QWkl|oÀBQ* 4ox؏zGy3Edv5=+ d%jA\ʻضk/f;Jyumak%ԋ(2OUlP>>o' Gh_zѻ 7=h4?wݿ½ZwS=t2'5$*aǧ'v}o_j.uH>7-Gs ֗P˩Xpc޽x$~OkMBnA?wsCf9I#=U\֣YmMo;+$" aۋ*Te,=\׉xZ}w>grMa9 ߶kЯ~ڿߤyPЌ\γIk5۳ '?zK);|٤ ߹^|6@o}|t23_zEoKvq.jFu>Igy$0΀v75ŌV-dmJ/V%'D/Ȭ" ^. SL7@ո?[NJk)W滊!%D0ު-V7\п$7MB}9a$s˝Eߔ:k_xf2FO,Ï#-4fo-K32K1rM #f*ao\EܹiM ھ@#eҬh HH*H#n:(.OxEfD\*ТI%ދ,M5pĺP2ʬڲnnNl&;cJȳ2<C*zt(:r~nW/3$I=IZ&5 ɵN&* 6&Z dYQurZg>jMqT&elMq]ÈwCvGWXOR^Gk& ~Vre#֙*8^zlqQhQF:Y}Mp2G~U󷋣7.q,u77v*9`@sxTWCG) wn `-^jhgA Ͻ\7X1KWc1JJ[d3/r+bE͜E(㨐ZndXVGV,39բ$+|aӮ6sZh׸B}k|:LV ~[3|O{"Z;K#yXi%ǪE\&\gr 5 ~YI-5&7P!8^OpM]^0 .1<O> Oowbr}\*AOhRp}u(z( דly8#?Y>.t[Z`?GMurɻ;_SI73nٹS*2FOZͶpKC *Zu WLK)4)Pٖ&U ޵l 0`m=R]֫b=8Q4[QTa?igttZh ڡx=(|O\ɈH~XԒYWqTc#O.m$6pGcSВYP?*KM~d|đeW.I%ޡ72I)oQa7+j[ZmΊ(QEQEQEQEQEW3xH5%U$>]5³ѼhMZ5`!9c>PEPEP )е=^k2ij x _OҭY|0lKVm+2m1ҭr:1kN8bv"*)PEPEP|f-5,>\U`Ҽ_QjzUkkvH׊u,֭5NL(M]M^-:WGs&u:|kRYΞ2Ltȝ$]ßϯ^.Faf8`SN_k2y6v0}@(d5h^W|mm (*+* h?b^n"?t:q{\n|d)2UyĦ+)rOPr?Q^[LJ.rVaF,52CdVosJ $qJGӚD4'Π7q-l%NȒ;琤? AZxzEӭ]fbO'jZқp?`S5M:αcаP? RQ׮Jghddk}ŰIz'̍\kg6cKbzMίJ7 0םz}LŘA־U T@*;ho-dAT3)?zӚ$y~ЯZOKY#9>α,p-#?7_kάMJYj9'j>ۍjJ{]?>?PkҾ_HP #J7gT9z_umr8-n6r+_ hQ{DVF7`bb(#F)-aERv+9I̞}> (5:[KԢQ%?o5}hl#&. ϓR& 9{w >k8r6!W5aw[.o xvy 2Oc!9 Z]sǬ4j+aBeOohQy@ױz/_O[[@la#omV_67Rߣ ۳ǁwe CG^,Q̅%$CXdV-+ܖH$8*Ƈ~=KsWEh4ZdHd^R5^|4l+f@ߨ3&Oo6?:f0}PmU7_f3gF#Lүnl][Ee?@:.Zң܅?qq)?u|M:UVr># };E7,YU޲cRk oz#OgǗO%@y\֨޸%it?4˅_Rp󩜭4z&`q)NG`KkhN4@1]@s\4QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQtyXAV+X#XAETPEPEPY 쭥V` EQEQEQEQEQEQEQEQEQEQEQEQER2R4P|_k{hbS1fθי|)xOm)W`21z瞝9ޟw** ; X.f ,7]WЮ I`i!咟^ExĶkպAe@ߪ[Z[lu06uߥ}QL(Bƒ)ꬹJM jC'f@:k>p~LM:G9s? 鯼):V⪢U `0ahQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ode-0.11.1/ode/doc/pix/hinge.jpg0000644000076400007640000002446407320713017013214 00000000000000JFIFcCreated by Paint Shop Pro CREATOR: XV Version 3.10a Rev: 12/29/94 Quality = 75, Smoothing = 0 C    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222," }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?LQv)q@ PqF)إ3b1@ .)أQ~(3b1@ P1Kv(7b\P1F)Q~(3b1@ P1F)أQ~(3b1@ P1I~(3b1@ Q~(3bLPqI~(3bLPQn(;bSF(R1ObR1ObSF(Qf)qObSF(Qf(?bLT(?b1ObSF(ILP1F)Q~)1@ P1F)3b1@ &)Q~)1@SF(;bSF(Qf(?bSF(Qf(I1@ P1F)Q~(3b_ |Dc_i`YfE *۹0#8뎢P1F+;XF n [D0LP1F)Q~(G1RbQ~(31F(е+o x:NQ}TʎS!$99f</j$w.$WZnfLqI]4iMjY*CȪ0AQѮ.n텤q+I `1V u[}^srI98VͿGRԵ]UR&i/jF ٵMB_t* yNdvs5xL1{UOw6X\O#kMMUnqXf*EKT5#ע\/OFk0AEpXeZő[7OrJ.̴vRUƒ_7ة(ILPxQP1Ks,p*w~* ʭhRWҸK2oTp\v`FmVή"R*}jj1\ڔ@!jlR❘4yU6(`CRyU>(`WjOu{(DQS|A+?ٙgpґF: 5ƞC0xQZҢMƷ򲱆' j}S^ՠjWM 쮻7j5'_Β)j^#6vQEn (?gIЫC_sIc ^ 9F^Q"kG>?ViQE@QE%./xc2^^-_tm7~nU |a-/ɒߢ!Yuxd0 WQ ܟ2vBvѐ*iNm֭^aT]1LtbcFb0E1{TM91f:՘rcZc!5Uf{W(85<;Zĵ.imu{0;\ X$**k>#z\9Jȡ)AȥOE 'Kg9vP9$ߙ JeR8"-2M,Om5:v/ԣy;&{•a cK^/k]ېa>kr8q ue=2Wm\Z)Fk[MȏKKf(TTUw>j!Ai1F)qE&+? !]c*Zb= .nׯ%gi %W wj֩v7R = w]5g,攝+Z? ۳<־m'Yyˏ ;o4o;]»_ ^kHkv3[SAogYE0H{XKf+1hAX3. cf(v;XV3\^ i^l.v9Z(Toq zE٪I&ns}?cxNȒd!Z'WGI^uoE̶qP2~]Ļ$ȅ4 ?3swn$$a$]劸Ҷ5݀bn=]nu[[7ԨϗrU.[d֍}"QcOs5i$oWbOZFޕ 5Xuֽ?C\@W۱qZV $nUhLG+ k~BdսwY'Hw`)Ri Lr-Q=6#1T2P* i/<]\Aø,?͚9;w=;ߏcȶy 璠y*]F:jRd@B=Msמ!% y)-YX37v=_D,ѳ <@:R)e-J;r vZ}ؿYF q}$++$5 0IP@. \F FHʟʲ#Ov>Ai`,L7yK\de%ՄZԴ3Q$_BuEWF )@p54j^ԯmq]Yj[X=$@ sӁ`vv=q#{kVt0+I]lwmj/\qsұx\D[n2?==y漯<˧VUi*VrRzak-eF4l3ɒr:ߝW׾"A힥;ǘ!N#+M47:I_grET&i&MIMG!=1N&3 !z6MǽGw1{~cI9e15WB/%1JsP<ǒy)\<]]l<~PyXJEs%v >k?TI4z%@$[|*3ݽ ȣcEFf7I˟OjӢ(!Ar[/+VZdc'nW9/!smE+ X[1KVZGFKVRZG !h Dެ$Մ4ZIEdj_ޯ=xhg-p$zVdWUcYRZoEnagWZ pl5{ce]55QN 4j0iA҃\#P \N; xm$UOO:UJA\TKܠ!=Sm5aGI灏^{ -nϩ}(` 6~#c[Z,`g9^ \ېE_}Rd$^2O[cNӾn;\H0x6Qg\A*j[&MIIi4 A4h&?EJMVl"&j lmVjrmI[ Py*Xe;zV{IT<]3,7%@R3T ԮP;һT#ڽKݯ9N0kݫ;hl; )a?56lH,}s]) cV~s{µ*QEQE]?3h`ЌJ.nQGɪ&IY:=s43AW %NR2QWZOu>A^Wh hlf5+Vο@kVs.p}kC0WXX.g9 2X ?j[X݆HkOf^ňIYbuxەu9j@k?Ū[a PDv+*zd1?/0<p5|;rm O-ׄuk\`;Edt;?s??$⶞/7LtH8lҨkr6_PPgVũQJ岂B|%7}B+Uڨxd16*mZM6}qi=>(WԓTfffwY jIeTf =@=bg? JanoKKAϟ2G}=0O7d_D~Qj?bԮokRXٕpG?} ov CZ(Š((5: SF}:-Co!3֝NMZY5f$!̉}ưN P??6@u >F?Ű5. Ѻ0$gjQL3{]|i'o@;l|T=rWN Ci&-}ҡ*זGCkյ"Y$qƄpZ^m0^Xw Fu{f+MӮn=3 :=>#NHJ-ePh~5pK-KQ!vi}R2X~?*ٱ&em Ï❋~?J(11ăcPKkHdY5~7dޙZՈ#3)xk zn r Sv3Y.ݥ&gֻ;~h-5ؿފ@R4-JoQ'zEQEQEQEQEQEQEU;+O]YA7'W(Rs l?#OhɎKKA<{[N˨ĭd xdװ=9w#oSZPEPEPEs~/·kiAr"X$d~b y⺶ te# Tzwbȫ+|PwEw+oVݜW@ﬡ,]JXW^|5YOax*G v#]t{]l2+f]GWk%[V8m`n_!|-|C{z$,)I 06=믋zL#]`O-F69BDs5[X5= MFTN 7Wi~ uu|qyKvnJAڣ?\~2>#.qjwk $e@%QO!>k'{\yc"l좷uχ, Jk+CIa?%wQEQE|]|AVYkҴ m"!2:m-+W~/a |ܤar>Sk/3K[sq5ÆwsY C&_^) rm{@sksAyoq> HLc 1ZзWe,+X[ʊ=y vqzo3\%[=I(]sFzVfBukGz%򅽎ʎ9?:ki{xᝧAqjcϵ-x+Y.}[QYBS3廌#z3CobX?(ONf"uI%Xm╁T&@C7|1G5[J5ŭdY|ǡ;kjQk/V%4}7~(FBZ /`*F:lƞ\jmeIuPEPEPEP~)m{vf[iw["Ce r ]?ßxA.|C8[Ix&o"`I6/HYB`/\u ;E_4lr6*|׈HZEQԌ8${/"FkQxF봲OJg>$[AIaTXfTb2 ۩}kM\.G-}|k@(jKRz_eu{Ui>ڠF J<W7GL*ʲoS޺G9?}VDۄo0Kco3k,Kg=#USЮ`%H $[EvW]woV3m}_L-%ܥno]ڠ%s9>=3ΉwP[a7vU&؂5>1xº5,Qw/ }1?9OaG L Dq#x^Mz]Q@Q@Q@Q@Q@Q@Q@Q@Q@ύ<'?\mX2ܥl|kgHҭ4M"KB,QrpR{@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ύ<'?\mX2ܥl|kgHҭ4M"KB,QrpR{@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ode-0.11.1/ode/doc/Doxyfile0000644000076400007640000014631610426662563012341 00000000000000# Doxyfile 1.4.6-NO # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a 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 #--------------------------------------------------------------------------- # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = "Open Dynamics Engine" # 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 = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # 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 = ../../docs # 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 cause performance problems for the file system. 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. # The default language is English, other supported languages are: # Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, # Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, # Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, # Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, # Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # This tag can be used to specify the encoding used in the generated output. # The encoding is not always determined by the language that is chosen, # but also whether or not the output is meant for Windows or non-Windows users. # In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES # forces the Windows encoding (this is the default for the Windows binary), # whereas setting the tag to NO uses a Unix-style encoding (the default for # all platforms other than Windows). USE_WINDOWS_ENCODING = YES # If the BRIEF_MEMBER_DESC tag is set to YES (the default) 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. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) 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. 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" "the" ABBREVIATE_BRIEF = # 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. 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. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then 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. FULL_PATH_NAMES = NO # If the FULL_PATH_NAMES tag is set to YES then 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. 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 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. 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 # comments will behave just like the Qt-style comments (thus requiring an # explicit @brief command for a brief description. JAVADOC_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 behaviour. # 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 behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the DETAILS_AT_TOP tag is set to YES then Doxygen # will output the detailed description near the top, like JavaDoc. # If set to NO, the detailed description appears after the member # documentation. DETAILS_AT_TOP = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. 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. 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. TAB_SIZE = 3 # This tag can be used to specify a number of aliases that acts # 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 = # 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. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for Java. # For instance, namespaces will be presented as packages, qualified scopes # will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # 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); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # 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. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) 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. SUBGROUPING = YES #--------------------------------------------------------------------------- # 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 and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. 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. 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 (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) 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. 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 (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. 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 (the default) these declarations will be included in the # documentation. 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 (the default) these blocks will be appended to the # function's detailed documentation block. 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 (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. 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. CASE_SENSE_NAMES = NO # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) 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. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = 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 default), 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. SORT_BY_SCOPE_NAME = 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. 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. 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. 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. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of 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 initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. 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. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # 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 , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED 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. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR 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. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. 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) 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 stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be 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. INPUT = . ../../include/ode ../../include/drawstuff # If the value of the INPUT tag contains directories, you can use the # FILE_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 the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py FILE_PATTERNS = *.h *.c *.cpp *.dox # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # 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. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. 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 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. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = pix # 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 , where # is the value of the INPUT_FILTER tag, and 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. 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 # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # 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 also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES (the default) # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES (the default) # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = 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. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) 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. 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. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) 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 one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. 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. If left blank `html' will be used as the default path. HTML_OUTPUT = . # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. 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 the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, 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. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, 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. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, 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). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, 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. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # If the GENERATE_TREEVIEW tag 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 (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # 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. TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. 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. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. 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. 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, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. 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. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). 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. PDF_HYPERLINKS = NO # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = NO # 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. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # 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 very pretty with # other RTF readers or editors. 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. If left blank `rtf' will be used as the default path. 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. 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 other # programs which support those fields. # Note: wordpad (write) and others do not support links. 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. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages 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. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) 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 is NO. 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. 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. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. 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. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see 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. 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. 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. 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. 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. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. 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 (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # 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. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. 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. 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. 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 # 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. PREDEFINED = # 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. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all 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. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. 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. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a 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. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. 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. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # 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. 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, 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) HAVE_DOT = NO # If the CLASS_GRAPH and HAVE_DOT tags are 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 # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are 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. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies 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. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # 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. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT tags are 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. CALL_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are 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. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH 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. 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). DOTFILE_DIRS = # The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_WIDTH = 1024 # The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_HEIGHT = 1024 # 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 a graph may be further truncated if the graph's # image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH # and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), # the graph is not depth-constrained. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, which results in a white background. # 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). 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. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO ode-0.11.1/ode/doc/main.dox0000644000076400007640000000153210442304356012250 00000000000000/** @mainpage Open Dynamics Engine API Reference
This document is © Russell Smith and the ODE Project
The Open Dynamics Engine (ODE) is a free, industrial quality library for simulating articulated rigid body dynamics. ODE is being developed by Russell Smith with help from several contributors. This document describes the library API. For a more general introduction to ODE, please see the Online Handbook.

Important: this document is not yet complete!

We are still working on getting the full API documentated. In the meantime, please refer to the Online Handbook */ ode-0.11.1/ode/Makefile.in0000644000076400007640000003520111206343412012103 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in TODO ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ode/src/config.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-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 uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = src demo DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ 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@ 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@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODE_PRECISION = @ODE_PRECISION@ ODE_RELEASE = @ODE_RELEASE@ 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_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ 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@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ 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 $(am__append_1) EXTRA_DIST = doc 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'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign ode/Makefile .PRECIOUS: 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 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. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; 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; \ (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" $(RECURSIVE_CLEAN_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ 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 || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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 \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-exec-am: install-html: install-html-recursive install-info: install-info-recursive install-man: install-pdf: install-pdf-recursive install-ps: install-ps-recursive 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: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ ctags ctags-recursive 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-recursive \ uninstall uninstall-am # 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: ode-0.11.1/ode/TODO0000644000076400007640000006027707762665761010573 00000000000000 @@@'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. ode-0.11.1/ode/demo/0000777000076400007640000000000011206343457011056 500000000000000ode-0.11.1/ode/demo/bunny_geom.h0000644000076400007640000007372211136407006013311 00000000000000// 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} }; ode-0.11.1/ode/demo/demo_motor.cpp0000644000076400007640000001556711206342116013647 00000000000000/************************************************************************* * * * 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 #include #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 *data, 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; } ode-0.11.1/ode/demo/convex_bunny_geom.h0000644000076400007640000003335411075740455014702 00000000000000const 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, }; ode-0.11.1/ode/demo/demo_step.cpp0000644000076400007640000001323611206342116013451 00000000000000/************************************************************************* * * * 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 #include #include #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 # include # include # include # include #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; static dWorld dyn_world; static dBody dyn_bodies[N_BODIES]; static dReal bodies_sides[N_BODIES][3]; static dSpaceID coll_space_id; static dJointID plane2d_joint_ids[N_BODIES]; static dJointGroup coll_contacts; 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 *data, 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 (dyn_world.id(), 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 (dyn_bodies[0], 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; */ /* dyn_bodies[b].addForce (f0 * cos (p*angle), f0 * sin (q*angle), 0); */ /* } */ /* dyn_bodies[0].addTorque (0, 0, 0.1); */ const int n = 10; for (int i = 0; i < n; i ++) { dSpaceCollide (coll_space_id, 0, &cb_near_collision); dyn_world.step (dReal(TIME_STEP/n)); coll_contacts.empty (); } } # if 1 /* [ */ { // @@@ hack Plane2D constraint error reduction here: for (int b = 0; b < N_BODIES; b ++) { const dReal *rot = dBodyGetAngularVel (dyn_bodies[b].id()); const dReal *quat_ptr; dReal quat[4], quat_len; quat_ptr = dBodyGetQuaternion (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 (dyn_bodies[b].id(), quat); dBodySetAngularVel (dyn_bodies[b].id(), 0, 0, rot[2]); } } # endif /* ] */ # if 0 /* [ */ { // @@@ friction for (int b = 0; b < N_BODIES; b ++) { const dReal *vel = dBodyGetLinearVel (dyn_bodies[b].id()), *rot = dBodyGetAngularVel (dyn_bodies[b].id()); dReal s = 1.00; dReal t = 0.99; dBodySetLinearVel (dyn_bodies[b].id(), s*vel[0],s*vel[1],s*vel[2]); dBodySetAngularVel (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 (dyn_bodies[b].getPosition(), dyn_bodies[b].getRotation(), bodies_sides[b]); #else dsDrawBox (dyn_bodies[b].getPosition(), dyn_bodies[b].getRotation(), bodies_sides[b]); #endif } } } extern int main /******************/ ( int argc, char **argv ) { int b; dsFunctions drawstuff_functions; dInitODE2(0); // 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 (dyn_world.id (), err_reduct); dWorldSetCFM (dyn_world.id (), cf_mixing); dyn_world.setGravity (0, 0.0, -1.0); 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(); bodies_sides[b][0] = dReal( 5 * (0.2 + 0.7*drand48()) / sqrt((double)N_BODIES) ); bodies_sides[b][1] = dReal( 5 * (0.2 + 0.7*drand48()) / sqrt((double)N_BODIES) ); bodies_sides[b][2] = z; dyn_bodies[b].create (dyn_world); dyn_bodies[b].setPosition (x, y, z/2); dyn_bodies[b].setData ((void*) (size_t)b); dBodySetLinearVel (dyn_bodies[b].id (), dReal( 3 * (drand48 () - 0.5) ), dReal( 3 * (drand48 () - 0.5) ), 0); dMass m; m.setBox (1, bodies_sides[b][0],bodies_sides[b][1],bodies_sides[b][2]); m.adjust (REAL(0.1) * bodies_sides[b][0] * bodies_sides[b][1]); dyn_bodies[b].setMass (&m); plane2d_joint_ids[b] = dJointCreatePlane2D (dyn_world.id (), 0); dJointAttach (plane2d_joint_ids[b], dyn_bodies[b].id (), 0); } dJointSetPlane2DXParam (plane2d_joint_ids[0], dParamFMax, 10); dJointSetPlane2DYParam (plane2d_joint_ids[0], dParamFMax, 10); // collision geoms and joints dCreatePlane (coll_space_id, 1, 0, 0, 0); dCreatePlane (coll_space_id, -1, 0, 0, -STAGE_SIZE); dCreatePlane (coll_space_id, 0, 1, 0, 0); dCreatePlane (coll_space_id, 0, -1, 0, -STAGE_SIZE); for (b = 0; b < N_BODIES; b ++) { dGeomID coll_box_id; coll_box_id = dCreateBox (coll_space_id, bodies_sides[b][0], bodies_sides[b][1], bodies_sides[b][2]); dGeomSetBody (coll_box_id, dyn_bodies[b].id ()); } 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); } dCloseODE(); return 0; } ode-0.11.1/ode/demo/demo_crash.cpp0000644000076400007640000004456311206342116013605 00000000000000/************************************************************************* * * * 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 #include #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 // select the method you want to test here (only uncomment *one* line) #define QUICKSTEP 1 //#define STEPFAST 1 // 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 //#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 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 *data, 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 -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]); dJointSetHinge2Axis1 (joint[joints],0,0,1); dJointSetHinge2Axis2 (joint[joints],1,0,0); 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]); dJointSetHinge2Axis1 (joint[joints],0,0,1); dJointSetHinge2Axis2 (joint[joints],1,0,0); 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 '+': dWorldSetAutoEnableDepthSF1 (world, dWorldGetAutoEnableDepthSF1 (world) + 1); break; case '-': dWorldSetAutoEnableDepthSF1 (world, dWorldGetAutoEnableDepthSF1 (world) - 1); break; case 'r': case 'R': resetSimulation(); 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); #if defined(QUICKSTEP) dWorldQuickStep (world,0.05); #elif defined(STEPFAST) dWorldStepFast1 (world,0.05,ITERS); #endif 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; resetSimulation(); // run simulation dsSimulationLoop (argc,argv,352,288,&fn); dJointGroupDestroy (contactgroup); dSpaceDestroy (space); dWorldDestroy (world); dCloseODE(); return 0; } ode-0.11.1/ode/demo/demo_jointPU.cpp0000644000076400007640000005075611166657111014107 00000000000000/************************************************************************* * * * 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 #include #include #include #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 *data, 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; igetParam (dParamVel3) - VEL_INC; joint->setParam (dParamVel3, vel); std::cout<<"Velocity = "<' : { dReal vel = joint->getParam (dParamVel3) + VEL_INC; joint->setParam (dParamVel3, vel); std::cout<<"Velocity = "<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 (joint); pr->setParam (dParamLoStop, -lLimit); pr->setParam (dParamHiStop, -lLimit); pr->setParam (dParamLoStop2, aLimit); pr->setParam (dParamHiStop2, -aLimit); } break; case dJointTypePU : { dPUJoint *pu = reinterpret_cast (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 (joint); std::cout<<"Position ="<getPosition() <<"\n"; } break; case dJointTypePU : { dPUJoint *pu = reinterpret_cast (joint); std::cout<<"Position ="<getPosition() <<"\n"; std::cout<<"Position Rate="<getPositionRate() <<"\n"; std::cout<<"Angle1 ="<getAngle1() <<"\n"; std::cout<<"Angle1 Rate="<getAngle1Rate() <<"\n"; std::cout<<"Angle2 ="<getAngle2() <<"\n"; std::cout<<"Angle2 Rate="<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 (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 (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 (dGeomTransformGetGeom (geom[AXIS1]), &radius, &length); dsSetColor (1,0,0); dsDrawCylinder (anchorPos, R, length, radius); } if ( dJointTypePU == type && geom[AXIS2] ) { //dPUJoint *pu = dynamic_cast (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 (dGeomTransformGetGeom (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+1 > argc || // Check if we have enough arguments argv[j] == '\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 (space, 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 (space, 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; dGeomID id; // Create the first axis of the universal joi9nt geom[AXIS1] = dCreateGeomTransform (space); //Rotation of 90deg around y 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]); id = geom[AXIS1]; dGeomTransformSetGeom (geom[AXIS1], dCreateCylinder (0, axDim[RADIUS], axDim[LENGTH]) ); // Create the second axis of the universal joint geom[AXIS2] = dCreateGeomTransform (space); //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]); id = geom[AXIS2]; dGeomTransformSetGeom (geom[AXIS2], dCreateCylinder (0, axDim[RADIUS], axDim[LENGTH]) ); // Create the anchor geom[ANCHOR] = dCreateBox (space, 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; } ode-0.11.1/ode/demo/demo_piston.cpp0000644000076400007640000005545611130714245014026 00000000000000/************************************************************************* * * * 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 #include #include #include #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 *data, 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; iattach (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 = "<' : { dReal vel = joint->getParam (dParamVel) + VEL_INC; joint->setParam (dParamVel, vel); std::cout<<"Velocity = "<getType() ) { case dJointTypeSlider : { dSliderJoint *sj = reinterpret_cast (joint); std::cout<<"Position ="<getPosition() <<"\n"; } break; case dJointTypePiston : { dPistonJoint *rj = reinterpret_cast (joint); std::cout<<"Position ="<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; igetType() == 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+1 > argc || // Check if we have enough arguments argv[j] == '\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; } ode-0.11.1/ode/demo/demo_slider.cpp0000644000076400007640000001232011206342116013751 00000000000000/************************************************************************* * * * 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 #include #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; } ode-0.11.1/ode/demo/demo_joints.cpp0000644000076400007640000007735711166671235014036 00000000000000/************************************************************************* * * * 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 #include #include #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 // 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); dJointSetHinge2Axis1 (joint,0,0,1); dJointSetHinge2Axis2 (joint,1,0,0); 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); dJointSetHinge2Axis1 (joint,0,0,1); dJointSetHinge2Axis2 (joint,1,0,0); 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*dDOT(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*dDOT(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*dDOT(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*dDOT(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 #include #include #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 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; ibody, 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; ibody, 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 *data, 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; idraw(); } } 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); dSpaceDestroy(space); dCloseODE(); } ode-0.11.1/ode/demo/demo_motion.cpp0000644000076400007640000003402111206342116013776 00000000000000/* This demo shows how to use dContactMotionN in a lifting platform. */ //#include // for usleep() #include #include #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 = dDOT(fdir1, vel); motion2 = dDOT(fdir2, vel); motionN = dDOT(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 = dDOT(mov2_vel, motiondir1); contact.surface.motion2 = inv * dDOT(mov2_vel, motiondir2); contact.surface.motionN = inv * dDOT(mov2_vel, contact.geom.normal); } static void nearCallback (void *data, 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) { size_t 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 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); } else if (type == dGeomTransformClass) { dGeomID g2 = dGeomTransformGetGeom (g); const dReal *pos2 = dGeomGetPosition (g2); const dReal *R2 = dGeomGetRotation (g2); dVector3 actual_pos; dMatrix3 actual_R; dMULTIPLY0_331 (actual_pos,R,pos2); actual_pos[0] += pos[0]; actual_pos[1] += pos[1]; actual_pos[2] += pos[2]; dMULTIPLY0_333 (actual_R,R,R2); drawGeom (g2,actual_pos,actual_R,0); } 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 #include #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 *data, 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= '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(0,0,5); top2->setAngularVel(0,0,5); 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(); } ode-0.11.1/ode/demo/basket_geom.h0000644000076400007640000005104110715446136013426 00000000000000 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,-4,0.100000f,-4,-4,0.100000f,4,0,0.100000f,4,-4,-0.100000f,4,4,-0.100000f,4,0,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,-4,4,-0.100000f,4,4,-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,-0.066000f,-1.940000f,2,-0.066000f,-2.060000f,2,-4,4,0.100000f,4,4,0.100000f,4,4,-0.100000f,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,0,0.100000f,-4,4,0.100000f,-4,4,-0.100000f,-4,0,0.100000f,-4,4,-0.100000f,-4,-4,-0.100000f,0.360000f,3.244444f,1.466974f,0.360000f,3.422222f,2.266974f,-0.360000f,3.422222f,2.266974f,-0.360000f,3.422222f,2.266974f,-0.360000f,3.244444f,1.466974f,0.360000f,3.244444f,1.466974f,4,-4,0.100000f,0.066000f,-2.060000f,0.100000f,-0.066000f,-2.060000f,0.100000f,-0.066000f,-2.060000f,0.100000f,-4,-4,0.100000f,4,-4,0.100000f,4,0,0.100000f,0.066000f,-1.940000f,0.100000f,4,-4,0.100000f,0.066000f,-1.940000f,0.100000f,0.066000f,-2.060000f,0.100000f,4,-4,0.100000f,-0.066000f,-1.940000f,0.100000f,0.066000f,-1.940000f,0.100000f,4,0,0.100000f,4,0,0.100000f,-4,0,0.100000f,-0.066000f,-1.940000f,0.100000f,-0.066000f,-2.060000f,0.100000f,-0.066000f,-1.940000f,0.100000f,-4,0,0.100000f,-4,0,0.100000f,-4,-4,0.100000f,-0.066000f,-2.060000f,0.100000f,0.066000f,-2.060000f,2,-0.066000f,-2.060000f,2,-0.066000f,-2.060000f,0.100000f,-0.066000f,-2.060000f,0.100000f,0.066000f,-2.060000f,0.100000f,0.066000f,-2.060000f,2,0.066000f,-1.940000f,1.950000f,0.066000f,-1.940000f,2,0.066000f,-2.060000f,2,0.066000f,-2.060000f,2,0.066000f,-2.060000f,0.100000f,0.066000f,-1.940000f,1.950000f,0.066000f,-2.060000f,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.052853f,-1.506390f,1.950000f,-0.052853f,-1.506390f,2,-0.066000f,-2.060000f,0.100000f,-0.066000f,-2.060000f,2,-0.066000f,-1.940000f,1.950000f,-0.066000f,-2.060000f,0.100000f,-0.066000f,-1.940000f,1.950000f,-0.066000f,-1.940000f,0.100000f,-0.066000f,-2.060000f,2,-0.066000f,-1.940000f,2,-0.066000f,-1.940000f,1.950000f,-0.066000f,-1.940000f,0.100000f,-0.066000f,-1.940000f,1.950000f,0.066000f,-1.940000f,1.950000f,-0.066000f,-1.940000f,0.100000f,0.066000f,-1.940000f,1.950000f,0.066000f,-1.940000f,0.100000f,-0.066000f,-1.940000f,1.950000f,-0.066000f,-1.840000f,1.950000f,0.066000f,-1.940000f,1.950000f,-0.066000f,-1.840000f,1.950000f,0.066000f,-1.840000f,1.950000f,0.066000f,-1.940000f,1.950000f,-0.066000f,-1.940000f,2,-0.066000f,-1.840000f,2,-0.066000f,-1.840000f,1.950000f,-0.066000f,-1.840000f,1.950000f,-0.066000f,-1.940000f,1.950000f,-0.066000f,-1.940000f,2,0.066000f,-1.940000f,2,0.066000f,-1.840000f,2,-0.066000f,-1.940000f,2,0.066000f,-1.840000f,2,-0.066000f,-1.840000f,2,-0.066000f,-1.940000f,2,0.066000f,-1.940000f,1.950000f,0.066000f,-1.840000f,1.950000f,0.066000f,-1.840000f,2,0.066000f,-1.940000f,1.950000f,0.066000f,-1.840000f,2,0.066000f,-1.940000f,2,-0.066000f,-1.840000f,2,-0.171600f,-1.740000f,2,-0.066000f,-1.840000f,1.950000f,-0.171600f,-1.740000f,2,-0.171600f,-1.740000f,1.950000f,-0.066000f,-1.840000f,1.950000f,0.066000f,-1.840000f,1.950000f,0.171600f,-1.740000f,1.950000f,0.171600f,-1.740000f,2,0.066000f,-1.840000f,1.950000f,0.171600f,-1.740000f,2,0.066000f,-1.840000f,2,-0.171600f,-1.740000f,2,-0.188760f,-1.640000f,2,-0.188760f,-1.640000f,1.950000f,-0.188760f,-1.640000f,1.950000f,-0.171600f,-1.740000f,1.950000f,-0.171600f,-1.740000f,2,0.171600f,-1.740000f,1.950000f,0.188760f,-1.640000f,1.950000f,0.188760f,-1.640000f,2,0.171600f,-1.740000f,1.950000f,0.188760f,-1.640000f,2,0.171600f,-1.740000f,2,-0.188760f,-1.640000f,2,-0.132132f,-1.540000f,2,-0.132132f,-1.540000f,1.950000f,-0.132132f,-1.540000f,1.950000f,-0.188760f,-1.640000f,1.950000f,-0.188760f,-1.640000f,2,0.188760f,-1.640000f,1.950000f,0.132132f,-1.540000f,1.950000f,0.132132f,-1.540000f,2,0.188760f,-1.640000f,1.950000f,0.132132f,-1.540000f,2,0.188760f,-1.640000f,2,-0.132132f,-1.540000f,2,-0.052853f,-1.506390f,2,-0.052853f,-1.506390f,1.950000f,-0.052853f,-1.506390f,1.950000f,-0.132132f,-1.540000f,1.950000f,-0.132132f,-1.540000f,2,0.132132f,-1.540000f,1.950000f,0.052853f,-1.506390f,1.950000f,0.052853f,-1.506390f,2,0.132132f,-1.540000f,1.950000f,0.052853f,-1.506390f,2,0.132132f,-1.540000f,2,0.188760f,-1.640000f,1.950000f,0.173397f,-1.642679f,1.950000f,0.121808f,-1.551577f,1.950000f,0.121808f,-1.551577f,1.950000f,0.132132f,-1.540000f,1.950000f,0.188760f,-1.640000f,1.950000f,0.171600f,-1.740000f,1.950000f,0.157950f,-1.732697f,1.950000f,0.173397f,-1.642679f,1.950000f,0.171600f,-1.740000f,1.950000f,0.173397f,-1.642679f,1.950000f,0.188760f,-1.640000f,1.950000f,0.171600f,-1.740000f,1.950000f,0.066000f,-1.840000f,1.950000f,0.060149f,-1.825311f,1.950000f,0.171600f,-1.740000f,1.950000f,0.060149f,-1.825311f,1.950000f,0.157950f,-1.732697f,1.950000f,-0.066000f,-1.840000f,1.950000f,-0.060149f,-1.825311f,1.950000f,0.066000f,-1.840000f,1.950000f,-0.060149f,-1.825311f,1.950000f,0.060149f,-1.825311f,1.950000f,0.066000f,-1.840000f,1.950000f,-0.171600f,-1.740000f,1.950000f,-0.157950f,-1.732697f,1.950000f,-0.060149f,-1.825311f,1.950000f,-0.171600f,-1.740000f,1.950000f,-0.060149f,-1.825311f,1.950000f,-0.066000f,-1.840000f,1.950000f,-0.173397f,-1.642679f,1.950000f,-0.157950f,-1.732697f,1.950000f,-0.171600f,-1.740000f,1.950000f,-0.171600f,-1.740000f,1.950000f,-0.188760f,-1.640000f,1.950000f,-0.173397f,-1.642679f,1.950000f,-0.121808f,-1.551577f,1.950000f,-0.173397f,-1.642679f,1.950000f,-0.188760f,-1.640000f,1.950000f,-0.188760f,-1.640000f,1.950000f,-0.132132f,-1.540000f,1.950000f,-0.121808f,-1.551577f,1.950000f,-0.052853f,-1.506390f,1.950000f,-0.049868f,-1.521079f,1.950000f,-0.121808f,-1.551577f,1.950000f,-0.052853f,-1.506390f,1.950000f,-0.121808f,-1.551577f,1.950000f,-0.132132f,-1.540000f,1.950000f,0.049868f,-1.521079f,1.950000f,-0.049868f,-1.521079f,1.950000f,-0.052853f,-1.506390f,1.950000f,-0.052853f,-1.506390f,1.950000f,0.052853f,-1.506390f,1.950000f,0.049868f,-1.521079f,1.950000f,0.052853f,-1.506390f,1.950000f,0.132132f,-1.540000f,1.950000f,0.121808f,-1.551577f,1.950000f,0.052853f,-1.506390f,1.950000f,0.121808f,-1.551577f,1.950000f,0.049868f,-1.521079f,1.950000f,-0.188760f,-1.640000f,2,-0.173397f,-1.642679f,2,-0.121808f,-1.551577f,2,-0.121808f,-1.551577f,2,-0.132132f,-1.540000f,2,-0.188760f,-1.640000f,2,-0.171600f,-1.740000f,2,-0.157950f,-1.732697f,2,-0.173397f,-1.642679f,2,-0.173397f,-1.642679f,2,-0.188760f,-1.640000f,2,-0.171600f,-1.740000f,2,-0.066000f,-1.840000f,2,-0.060149f,-1.825311f,2,-0.171600f,-1.740000f,2,-0.060149f,-1.825311f,2,-0.157950f,-1.732697f,2,-0.171600f,-1.740000f,2,0.066000f,-1.840000f,2,0.060149f,-1.825311f,2,-0.066000f,-1.840000f,2,0.060149f,-1.825311f,2,-0.060149f,-1.825311f,2,-0.066000f,-1.840000f,2,0.171600f,-1.740000f,2,0.157950f,-1.732697f,2,0.060149f,-1.825311f,2,0.171600f,-1.740000f,2,0.060149f,-1.825311f,2,0.066000f,-1.840000f,2,0.173397f,-1.642679f,2,0.157950f,-1.732697f,2,0.171600f,-1.740000f,2,0.171600f,-1.740000f,2,0.188760f,-1.640000f,2,0.173397f,-1.642679f,2,0.121808f,-1.551577f,2,0.173397f,-1.642679f,2,0.188760f,-1.640000f,2,0.188760f,-1.640000f,2,0.132132f,-1.540000f,2,0.121808f,-1.551577f,2,0.052853f,-1.506390f,2,0.049868f,-1.521079f,2,0.121808f,-1.551577f,2,0.052853f,-1.506390f,2,0.121808f,-1.551577f,2,0.132132f,-1.540000f,2,-0.049868f,-1.521079f,2,0.049868f,-1.521079f,2,0.052853f,-1.506390f,2,0.052853f,-1.506390f,2,-0.052853f,-1.506390f,2,-0.049868f,-1.521079f,2,-0.121808f,-1.551577f,2,-0.049868f,-1.521079f,2,-0.052853f,-1.506390f,2,-0.052853f,-1.506390f,2,-0.132132f,-1.540000f,2,-0.121808f,-1.551577f,2,-0.173397f,-1.642679f,2,-0.157950f,-1.732697f,2,-0.157950f,-1.732697f,1.950000f,-0.157950f,-1.732697f,1.950000f,-0.173397f,-1.642679f,1.950000f,-0.173397f,-1.642679f,2,-0.157950f,-1.732697f,2,-0.060149f,-1.825311f,2,-0.060149f,-1.825311f,1.950000f,-0.060149f,-1.825311f,1.950000f,-0.157950f,-1.732697f,1.950000f,-0.157950f,-1.732697f,2,-0.060149f,-1.825311f,2,0.060149f,-1.825311f,2,0.060149f,-1.825311f,1.950000f,0.060149f,-1.825311f,1.950000f,-0.060149f,-1.825311f,1.950000f,-0.060149f,-1.825311f,2,0.060149f,-1.825311f,1.950000f,0.060149f,-1.825311f,2,0.157950f,-1.732697f,2,0.157950f,-1.732697f,2,0.157950f,-1.732697f,1.950000f,0.060149f,-1.825311f,1.950000f,0.157950f,-1.732697f,2,0.173397f,-1.642679f,2,0.173397f,-1.642679f,1.950000f,0.173397f,-1.642679f,1.950000f,0.157950f,-1.732697f,1.950000f,0.157950f,-1.732697f,2,0.173397f,-1.642679f,2,0.121808f,-1.551577f,2,0.121808f,-1.551577f,1.950000f,0.121808f,-1.551577f,1.950000f,0.173397f,-1.642679f,1.950000f,0.173397f,-1.642679f,2,0.121808f,-1.551577f,2,0.049868f,-1.521079f,2,0.049868f,-1.521079f,1.950000f,0.049868f,-1.521079f,1.950000f,0.121808f,-1.551577f,1.950000f,0.121808f,-1.551577f,2,0.049868f,-1.521079f,2,-0.049868f,-1.521079f,2,-0.049868f,-1.521079f,1.950000f,-0.049868f,-1.521079f,1.950000f,0.049868f,-1.521079f,1.950000f,0.049868f,-1.521079f,2,-0.049868f,-1.521079f,2,-0.121808f,-1.551577f,2,-0.121808f,-1.551577f,1.950000f,-0.121808f,-1.551577f,1.950000f,-0.049868f,-1.521079f,1.950000f,-0.049868f,-1.521079f,2,-0.121808f,-1.551577f,2,-0.173397f,-1.642679f,2,-0.173397f,-1.642679f,1.950000f,-0.173397f,-1.642679f,1.950000f,-0.121808f,-1.551577f,1.950000f,-0.121808f,-1.551577f,2,-0.360000f,3.600000f,0.100000f,0.360000f,3.600000f,0.100000f,4,4,0.100000f,4,4,0.100000f,-4,4,0.100000f,-0.360000f,3.600000f,0.100000f,-0.360000f,0.400000f,0.100000f,-0.360000f,3.600000f,0.100000f,-4,4,0.100000f,-4,4,0.100000f,-4,0,0.100000f,-0.360000f,0.400000f,0.100000f,4,0,0.100000f,0.360000f,0.400000f,0.100000f,-0.360000f,0.400000f,0.100000f,-0.360000f,0.400000f,0.100000f,-4,0,0.100000f,4,0,0.100000f,4,4,0.100000f,0.360000f,3.600000f,0.100000f,4,0,0.100000f,0.360000f,3.600000f,0.100000f,0.360000f,0.400000f,0.100000f,4,0,0.100000f,0.360000f,2.888889f,1.023752f,0.360000f,3.066667f,1.166974f,-0.360000f,3.066667f,1.166974f,-0.360000f,3.066667f,1.166974f,-0.360000f,2.888889f,1.023752f,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.711111f,0.966974f,-0.360000f,2.533333f,0.939976f,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,2.355556f,0.939976f,-0.360000f,2.177778f,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,2,0.939976f,-0.360000f,1.822222f,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.644444f,0.939976f,-0.360000f,1.466667f,0.939976f,0.360000f,1.111111f,0.957571f,0.360000f,1.288889f,0.939976f,-0.360000f,1.288889f,0.939976f,-0.360000f,1.288889f,0.939976f,-0.360000f,1.111111f,0.957571f,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.933333f,1.009739f,-0.360000f,0.755556f,1.134246f,0.360000f,0.755556f,1.134246f,-0.360000f,0.755556f,1.134246f,0.360000f,0.577778f,1.372130f,-0.360000f,0.755556f,1.134246f,-0.360000f,0.577778f,1.372130f,0.360000f,0.577778f,1.372130f,-0.360000f,3.600000f,3.900000f,-0.360000f,3.422222f,2.266974f,0.360000f,3.422222f,2.266974f,-0.360000f,3.600000f,3.900000f,0.360000f,3.422222f,2.266974f,0.360000f,3.600000f,3.900000f,0.360000f,3.244444f,1.466974f,-0.360000f,3.244444f,1.466974f,0.360000f,3.066667f,1.166974f,-0.360000f,3.244444f,1.466974f,-0.360000f,3.066667f,1.166974f,0.360000f,3.066667f,1.166974f,0.360000f,2.888889f,1.023752f,-0.360000f,2.888889f,1.023752f,0.360000f,2.711111f,0.966974f,-0.360000f,2.888889f,1.023752f,-0.360000f,2.711111f,0.966974f,0.360000f,2.711111f,0.966974f,0.360000f,2.533333f,0.939976f,-0.360000f,2.533333f,0.939976f,-0.360000f,2.355556f,0.939976f,0.360000f,2.533333f,0.939976f,-0.360000f,2.355556f,0.939976f,0.360000f,2.355556f,0.939976f,0.360000f,2.177778f,0.939976f,-0.360000f,2.177778f,0.939976f,-0.360000f,2,0.939976f,0.360000f,2.177778f,0.939976f,-0.360000f,2,0.939976f,0.360000f,2,0.939976f,0.360000f,1.822222f,0.939976f,-0.360000f,1.822222f,0.939976f,-0.360000f,1.644444f,0.939976f,0.360000f,1.822222f,0.939976f,-0.360000f,1.644444f,0.939976f,0.360000f,1.644444f,0.939976f,0.360000f,1.466667f,0.939976f,-0.360000f,1.466667f,0.939976f,-0.360000f,1.288889f,0.939976f,0.360000f,1.466667f,0.939976f,-0.360000f,1.288889f,0.939976f,0.360000f,1.288889f,0.939976f,0.360000f,1.111111f,0.957571f,-0.360000f,1.111111f,0.957571f,0.360000f,0.933333f,1.009739f,-0.360000f,1.111111f,0.957571f,-0.360000f,0.933333f,1.009739f,0.360000f,0.933333f,1.009739f,0.360000f,0.400000f,1.743932f,0.360000f,0.577778f,1.372130f,-0.360000f,0.577778f,1.372130f,-0.360000f,0.577778f,1.372130f,-0.360000f,0.400000f,1.743932f,0.360000f,0.400000f,1.743932f, }; 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,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485, }; ode-0.11.1/ode/demo/demo_buggy.cpp0000644000076400007640000002234011206342116013607 00000000000000/************************************************************************* * * * 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 #include #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 // 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 *data, 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 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); /* printf ("%.10f %.10f %.10f %.10f\n", dJointGetHingeAngle (joint[1]), dJointGetHingeAngle (joint[2]), dJointGetHingeAngleRate (joint[1]), dJointGetHingeAngleRate (joint[2])); */ } 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 wheel hinge /* joint[0] = dJointCreateHinge2 (world,0); dJointAttach (joint[0],body[0],body[1]); const dReal *a = dBodyGetPosition (body[1]); dJointSetHinge2Anchor (joint[0],a[0],a[1],a[2]); dJointSetHinge2Axis1 (joint[0],0,0,1); dJointSetHinge2Axis2 (joint[0],0,1,0); */ // 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]); dJointSetHinge2Axis1 (joint[i],0,0,1); dJointSetHinge2Axis2 (joint[i],0,1,0); } // 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; } ode-0.11.1/ode/demo/demo_space.cpp0000644000076400007640000001462611206342116013575 00000000000000/************************************************************************* * * * 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 #include #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 size_t good_matrix[NUM][NUM]; // correct collision matrix static size_t test_matrix[NUM][NUM]; // testing collision matrix static size_t 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*)(size_t)(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 *data, dGeomID o1, dGeomID o2) { size_t i,j; i = (size_t) dGeomGetData (o1); j = (size_t) 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 pause) { 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 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; } ode-0.11.1/ode/demo/texturepath.h0000644000076400007640000000334610726047550013527 00000000000000/************************************************************************* * * * 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. * * * *************************************************************************/ // Sourceforge tests require the textures in the drawstuff folder #ifndef DRAWSTUFF_TEXTURE_PATH #define DRAWSTUFF_TEXTURE_PATH "../../drawstuff/textures" #endif ode-0.11.1/ode/demo/demo_kinematic.cpp0000644000076400007640000001151611130674141014443 00000000000000#include #include #include #include #include #include #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(1, 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 boxes; set 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 = 3; 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 *data, 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 2*M_PI) t = 0; dReal px = cos(t); dReal py = sin(t); dReal vx = -sin(t)/4; dReal vy = cos(t)/4; kbody->setPosition(px, py, .5); kbody->setLinearVel(vx, vy, 0); // 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(); } ode-0.11.1/ode/demo/demo_collision.cpp0000644000076400007640000012076311021624601014472 00000000000000/************************************************************************* * * * 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 #include #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 #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 *data, 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 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 (dDOT14(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 (dDOT14(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,dDISTANCE (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 (dDOT(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 (dDISTANCE (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 = dDISTANCE (contact.pos,dGeomGetPosition(sphere)); if (dFabs(k - r) > tol) FAILED(); // also check normal signs if (dDOT (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,dDISTANCE(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 (dDOT (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,dDISTANCE(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 (dDOT14(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 (dDOT (n,contact.normal) > 0) 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 (dDOT(contact.pos,n) - d) > tol) FAILED(); // also check normal signs if (dDOT (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(dDOT(u1,u1)); dReal d2 = dSqrt(dDOT(u2,u2)); dNormalize3 (u1); dNormalize3 (u2); if (dFabs(dDOT(u1,u2)) > 1e-6) dDebug (0,"bad u1/u2"); dCROSS (n,=,u1,u2); for (k=0; k<3; k++) tmp[k] = v2[k]-v1[k]; dReal d = -dDOT(n,p1); if (dFabs(dDOT(n,p1)+d) > 1e-8) dDebug (0,"bad n wrt p1"); if (dFabs(dDOT(n,p2)+d) > 1e-8) dDebug (0,"bad n wrt p2"); if (dFabs(dDOT(n,p3)+d) > 1e-8) dDebug (0,"bad n wrt p3"); dReal alpha = -(d+dDOT(n,v1))/dDOT(n,tmp); for (k=0; k<3; k++) tmp[k] = v1[k]+alpha*(v2[k]-v1[k]); if (dFabs(dDOT(n,tmp)+d) > 1e-6) 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 = dDOT(u1,tmp); dReal a2 = dDOT(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 = dDOT14(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 pause) { 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; ifailcount = 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; jnumber; if (ts[i]->test_fn() != 1) ts[i]->failcount++; } } // check for failures int total_fail_count=0; for (i=0; ifailcount; if (total_fail_count) break; } // print results for (i=0; inumber,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(100,test_dBoxTouchesBox); MAKE_TEST(101,test_dBoxBox); do_tests (argc,argv); dCloseODE(); return 0; } ode-0.11.1/ode/demo/demo_chain1.c0000644000076400007640000001156011206342116013277 00000000000000/************************************************************************* * * * 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 #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; 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 #include #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 dsDrawLine dsDrawLineD #define dsDrawTriangle dsDrawTriangleD #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 *data, 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= '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; cmd = locase (cmd); if (cmd == 'b' || cmd == 's' || cmd == 'c' || cmd == 'x' /* || 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 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*)(size_t)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') { dGeomID g2[GPB]; // encapsulated geometries dReal dpos[GPB][3]; // delta-positions for encapsulated geometries // start accumulating masses for the encapsulated geometries dMass m2; dMassSetZero (&m); // set random delta positions for (j=0; j= 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); } /* // cylinder option not yet implemented else if (type == dCylinderClass) { dReal radius,length; dGeomCylinderGetParams (g,&radius,&length); dsDrawCylinder (pos,R,length,radius); } */ else if (type == dGeomTransformClass) { dGeomID g2 = dGeomTransformGetGeom (g); const dReal *pos2 = dGeomGetPosition (g2); const dReal *R2 = dGeomGetRotation (g2); dVector3 actual_pos; dMatrix3 actual_R; dMULTIPLY0_331 (actual_pos,R,pos2); actual_pos[0] += pos[0]; actual_pos[1] += pos[1]; actual_pos[2] += pos[2]; dMULTIPLY0_333 (actual_R,R,R2); drawGeom (g2,actual_pos,actual_R,0); } 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 #include #ifdef _MSC_VER #pragma warning(disable:4244 4305) // for VC++, no precision loss complaints #endif //**************************************************************************** // 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); dCROSS (a1,=,b,c); dSetZero (B,12); dCROSSMAT (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(dDOT(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(dDOT(n2,n1) - dSqrt(dDOT(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(dDOT(n,p)) > tol) bad = 1; if (fabs(dDOT(n,q)) > tol) bad = 1; if (fabs(dDOT(p,q)) > tol) bad = 1; if (fabs(dDOT(p,p)-1) > tol) bad = 1; if (fabs(dDOT(q,q)-1) > tol) bad = 1; } printf ("\t%s\n", bad ? "FAILED" : "passed"); } //**************************************************************************** // test matrix functions #define MSIZE 21 #define MSIZE4 24 // MSIZE rounded up to 4 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() { dReal A[MSIZE4*MSIZE], B[MSIZE4*MSIZE], C[MSIZE4*MSIZE], 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"); } void testCholeskySolve() { dReal A[MSIZE4*MSIZE], L[MSIZE4*MSIZE], b[MSIZE],x[MSIZE],btest[MSIZE],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"); } void testInvertPDMatrix() { int i,j,ok; dReal A[MSIZE4*MSIZE], Ainv[MSIZE4*MSIZE], I[MSIZE4*MSIZE]; 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 tol ? "FAILED" : "passed"); } void testSolveLDLT() { dReal A[MSIZE4*MSIZE], L[MSIZE4*MSIZE], d[MSIZE], x[MSIZE], b[MSIZE], btest[MSIZE], 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"); } void testLDLTAddTL() { int i,j; dReal A[MSIZE4*MSIZE], L[MSIZE4*MSIZE], d[MSIZE], a[MSIZE], DL[MSIZE4*MSIZE], ATEST[MSIZE4*MSIZE], 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 tol ? "FAILED" : "passed"); } void testLDLTRemove() { int i,j,r,p[MSIZE]; dReal A[MSIZE4*MSIZE], L[MSIZE4*MSIZE], d[MSIZE], L2[MSIZE4*MSIZE], d2[MSIZE], DL2[MSIZE4*MSIZE], Atest1[MSIZE4*MSIZE], Atest2[MSIZE4*MSIZE], diff, maxdiff; HEADER; // make array of A row pointers dReal *Arows[MSIZE]; for (i=0; i= 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 tol ? "FAILED" : "passed"); } //**************************************************************************** // 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; imass += 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 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 "../src/array.h" #include "../src/array.cpp" // matrix header on the stack class dMatrixComparison { struct dMatInfo; dArray 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); if (strlen(mi->name) >= sizeof (mi->name)) dDebug (0,"name too long"); mat.push (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); 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; idata,mat[i]->size); dFree (mat[i],sizeof(dMatInfo)); } mat.setSize (0); afterfirst = 0; index = 0; } void dMatrixComparison::dump() { for (int i=0; iname,mat[i]->n,mat[i]->m); } //**************************************************************************** // unit test #include // 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" void dTestSolveLCP(); int main() { dInitODE(); testRandomNumberGenerator(); testInfinity(); testPad(); testCrossProduct(); testSetZero(); testNormalize3(); //testReorthonormalize(); ... not any more testPlaneSpace(); testMatrixMultiply(); testSmallMatrixMultiply(); testCholeskyFactorization(); testCholeskySolve(); testInvertPDMatrix(); testIsPositiveDefinite(); testFastLDLTFactorization(); testSolveLDLT(); testLDLTAddTL(); testLDLTRemove(); testMassFunctions(); testRtoQandQtoR(); testQuaternionMultiply(); testRotationFunctions(); dTestMatrixComparison(); dTestSolveLCP(); // dTestDataStructures(); dCloseODE(); return 0; } ode-0.11.1/ode/demo/demo_moving_convex.cpp0000644000076400007640000002550211206342116015356 00000000000000/************************************************************************* * * * 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 #include #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 *data, 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= '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; cmd = locase( cmd ); if ( cmd == 'v' || cmd == 'b' || cmd == 'c' || cmd == 's' ) { 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 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* )( size_t )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 == '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 ) ); 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 == 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 ) dWorldStepFast1( world,0.05, 5 ); 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 #ifdef HAVE_UNISTD_H #include #endif #include #include #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", o1,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 #include #include "texturepath.h" #include "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 #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 *data, 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= '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; cmd = locase (cmd); if (cmd == 'b' || cmd == 's' || cmd == 'c' || cmd == 'x' || cmd == 'm' || 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 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*)(size_t)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') { 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)); 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') { dGeomID g2[GPB]; // encapsulated geometries dReal dpos[GPB][3]; // delta-positions for encapsulated geometries // start accumulating masses for the encapsulated geometries dMass m2; dMassSetZero (&m); // set random delta positions for (j=0; j= 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 == dGeomTransformClass) { dGeomID g2 = dGeomTransformGetGeom (g); const dReal *pos2 = dGeomGetPosition (g2); const dReal *R2 = dGeomGetRotation (g2); dVector3 actual_pos; dMatrix3 actual_R; dMULTIPLY0_331 (actual_pos,R,pos2); actual_pos[0] += pos[0]; actual_pos[1] += pos[1]; actual_pos[2] += pos[2]; dMULTIPLY0_333 (actual_R,R,R2); drawGeom (g2,actual_pos,actual_R,0); } 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 #include #include #include #include "texturepath.h" #ifdef _MSC_VER #pragma warning(disable:4244 4305) // for VC++, no precision loss complaints #endif #ifndef M_PI #define M_PI (3.14159265358979323846) #endif //<---- 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, -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 Side 0 4,1,0,4,5, // positive Y Side 1 4,0,1,3,2, // positive Z Side 2 4,3,1,5,7, // negative X Side 3 4,2,3,7,6, // negative Y Side 4 4,5,4,6,7, // negative Z Side 5 }; //----> Convex Object #ifdef dDOUBLE #define dsDrawConvex dsDrawConvexD #define dsDrawBox dsDrawBoxD #endif dGeomID* geoms; dGeomID boxes[2]; dGeomID convex[2]; dSpaceID space; dWorldID world; dJointGroupID contactgroup; /* glRotate Matrix: ( xx(1-c)+c xy(1-c)-zs xz(1-c)+ys 0 ) | | | yx(1-c)+zs yy(1-c)+c yz(1-c)-xs 0 | | xz(1-c)-ys yz(1-c)+xs zz(1-c)+c 0 | | | ( 0 0 0 1 ) Where c = cos(angle), s = sine(angle), and ||( x,y,z )|| = 1 (if not, the GL will normalize this vector). */ dVector3 geom1pos={0.0,0.250,0.50}; dQuaternion geom1quat={1,0,0,0}; dQuaternion geom0quat={0.7071,0,0.7071,0}; bool DumpInfo=true; int drawmode = DS_WIREFRAME; #if 0 const dReal fixed_pos_0[]={0.703704,-0.748281,0.249495}; const dReal fixed_rot_0[]={0.996994,-0.001009,-0.077468,0.000000, -0.077468,-0.000117,-0.996995,0.000000, 0.000996, 1.000000,-0.000195,0.000000}; const dReal fixed_pos_1[]={0.894169,-0.372081,0.249432}; const dReal fixed_rot_1[]={-0.999461, 0.032777,0.001829,0.000000, -0.032777,-0.999463,0.000033,0.000000, 0.001829,-0.000027,0.999998,0.000000}; #else // for EDGE-EDGE test const dReal fixed_pos_0[]={0.0,0.0,0.25}; const dReal fixed_rot_0[]={ 1,0,0,0,0,1,0,0,0,0,1,0 }; const dReal fixed_pos_1[]={0.000000,0.450000,0.600000}; const dReal fixed_rot_1[]={0.708311,-0.705472,-0.000000,0.000000, 0.516939,0.519297,-0.679785,0.000000, 0.480067,0.481293,0.733034,0.000000}; #endif void start() { // adjust the starting viewpoint a bit float xyz[3],hpr[3]; dsGetViewpoint (xyz,hpr); hpr[0] += 7; dsSetViewpoint (xyz,hpr); convex[0]=dCreateConvex (space, planes, planecount, points, pointcount, polygons); convex[1]=dCreateConvex (space, planes, planecount, points, pointcount, polygons); boxes[0]=dCreateBox(space,0.5,0.5,0.5); boxes[1]=dCreateBox(space,0.5,0.5,0.5); geoms=convex; dMatrix3 m1 = { 1,0,0,0,0,1,0,0,0,0,1,0 }; dMatrix3 m2 = { 1,0,0,0,0,1,0,0,0,0,1,0 }; #if 0 dGeomSetPosition (convex[0], 0.0, 0.0, 0.25); dGeomSetPosition (convex[1], geom1pos[0], geom1pos[1], geom1pos[2]); dQtoR (geom0quat, m1); dGeomSetRotation (convex[0],m1); dQtoR (geom1quat, m2); dGeomSetRotation (convex[1],m2); dGeomSetPosition (boxes[0], 0.0, 0.0, 0.25); dGeomSetPosition (boxes[1], geom1pos[0], geom1pos[1], geom1pos[2]); dQtoR (geom0quat, m1); dGeomSetRotation (boxes[0],m1); dQtoR (geom1quat, m2); dGeomSetRotation (boxes[1],m2); #else dGeomSetPosition (convex[0], fixed_pos_0[0], fixed_pos_0[1], fixed_pos_0[2]); dGeomSetPosition (convex[1], fixed_pos_1[0], fixed_pos_1[1], fixed_pos_1[2]); dGeomSetRotation (convex[0],fixed_rot_0); dGeomSetRotation (convex[1],fixed_rot_1); dGeomSetPosition (boxes[0], fixed_pos_0[0], fixed_pos_0[1], fixed_pos_0[2]); dGeomSetPosition (boxes[1], fixed_pos_1[0], fixed_pos_1[1], fixed_pos_1[2]); dGeomSetRotation (boxes[0],fixed_rot_0); dGeomSetRotation (boxes[1],fixed_rot_1); #endif } int dCollideConvexConvex (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); int dCollideBoxBox (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); void simLoop (int pause) { int contactcount; const dReal ss[3] = {0.02,0.02,0.02}; dContactGeom contacts[8]; if(geoms==convex) contactcount = dCollideConvexConvex(geoms[0],geoms[1],8,contacts,sizeof(dContactGeom)); else contactcount = dCollideBoxBox(geoms[0],geoms[1],8,contacts,sizeof(dContactGeom)); //fprintf(stdout,"Contact Count %d\n",contactcount); const dReal* pos; const dReal* R; dsSetTexture (DS_WOOD); pos = dGeomGetPosition (geoms[0]); R = dGeomGetRotation (geoms[0]); dsSetColor (0.6f,0.6f,1); dsSetDrawMode(drawmode); dsDrawConvex(pos,R,planes, planecount, points, pointcount, polygons); dsSetDrawMode(DS_POLYFILL); pos = dGeomGetPosition (geoms[1]); R = dGeomGetRotation (geoms[1]); dsSetColor (0.4f,1,1); dsSetDrawMode(drawmode); dsDrawConvex(pos,R,planes, planecount, points, pointcount, polygons); dsSetDrawMode(DS_POLYFILL); /*if (show_contacts) */ dMatrix3 RI; dRSetIdentity (RI); dsSetColor (1.0f,0,0); for(int i=0;i\n"); } else { printf("BOX--------------------------------------------------------->\n"); } break; default: dsPrint ("received command %d (`%c')\n",cmd,cmd); } #if 0 dGeomSetPosition (geoms[1], geom1pos[0], geom1pos[1], geom1pos[2]); dQtoR (geom1quat, m); dGeomSetRotation(geoms[1],m); if(changed) { printf("POS: %f,%f,%f\n",geom1pos[0],geom1pos[1],geom1pos[2]); printf("ROT:\n%f,%f,%f,%f\n%f,%f,%f,%f\n%f,%f,%f,%f\n", m[0],m[1],m[2],m[3], m[4],m[5],m[6],m[7], m[8],m[9],m[10],m[11]); } #endif DumpInfo=true; } 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 = DRAWSTUFF_TEXTURE_PATH; // uses default world = dWorldCreate(); space = dHashSpaceCreate (0); contactgroup = dJointGroupCreate (0); // run simulation dsSimulationLoop (argc,argv,400,400,&fn); dJointGroupDestroy (contactgroup); dSpaceDestroy (space); dWorldDestroy (world); return 0; } ode-0.11.1/ode/demo/icosahedron_geom.h0000644000076400007640000001260211146042210014433 00000000000000//<---- 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, }; ode-0.11.1/ode/demo/demo_space_stress.cpp0000644000076400007640000003050711206342116015174 00000000000000/************************************************************************* * * * 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 #include #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 100 // 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 draw_geom = 1; // this is called by dSpaceCollide when two objects in space are // potentially colliding. static void nearCallback (void *data, 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= '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; cmd = locase (cmd); if (cmd == 'b' || cmd == 's' || cmd == 'c' || cmd == 'x' /* || 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()*WORLD_SIZE-(WORLD_SIZE/2),dRandReal()*WORLD_SIZE-(WORLD_SIZE/2),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 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*)(size_t)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') { dGeomID g2[GPB]; // encapsulated geometries dReal dpos[GPB][3]; // delta-positions for encapsulated geometries // start accumulating masses for the encapsulated geometries dMass m2; dMassSetZero (&m); // set random delta positions for (j=0; j= 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); } /* // cylinder option not yet implemented else if (type == dCylinderClass) { dReal radius,length; dGeomCylinderGetParams (g,&radius,&length); dsDrawCylinder (pos,R,length,radius); } */ else if (type == dGeomTransformClass) { dGeomID g2 = dGeomTransformGetGeom (g); const dReal *pos2 = dGeomGetPosition (g2); const dReal *R2 = dGeomGetRotation (g2); dVector3 actual_pos; dMatrix3 actual_R; dMULTIPLY0_331 (actual_pos,R,pos2); actual_pos[0] += pos[0]; actual_pos[1] += pos[1]; actual_pos[2] += pos[2]; dMULTIPLY0_333 (actual_R,R,R2); drawGeom (g2,actual_pos,actual_R,0); } 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 #include #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; } ode-0.11.1/ode/demo/demo_jointPR.cpp0000644000076400007640000003440611075671117014077 00000000000000/************************************************************************* * * * 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 #include #include #include #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 *data, 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= 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+1 > argc || // Check if we have enough arguments argv[j] == '\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; } ode-0.11.1/ode/demo/demo_cyl.cpp0000644000076400007640000002111211206342116013255 00000000000000/************************************************************************* * * * 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 #include #ifdef HAVE_UNISTD_H #include #endif #include #include #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", o1,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 #include #include #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; imass += 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= 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 #include #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 *data, 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 #include #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) #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 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 *data, 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= 'A' && c <= 'Z') return c - ('a'-'A'); else return c; } // called when a key pressed static void command (int cmd) { size_t i; int j,k; dReal sides[3]; dMass m; int setBody; cmd = locase (cmd); if (cmd == 'b' || cmd == 's' || cmd == 'c' || cmd == 'x' || cmd == 'y' || cmd == 'v') { 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 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()+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 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); 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]); } //<---- Convex Object 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 } //----> Convex Object 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' && USE_GEOM_OFFSET) { setBody = 1; // start accumulating masses for the encapsulated geometries dMass m2; dMassSetZero (&m); dReal dpos[GPB][3]; // delta-positions for encapsulated geometries dMatrix3 drot[GPB]; // set random delta positions for (j=0; j= 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 == '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); } //<---- Convex Object 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 } //----> Convex Object else if (type == dCylinderClass) { dReal radius,length; dGeomCylinderGetParams (g,&radius,&length); dsDrawCylinder (pos,R,length,radius); } else if (type == dGeomTransformClass) { dGeomID g2 = dGeomTransformGetGeom (g); const dReal *pos2 = dGeomGetPosition (g2); const dReal *R2 = dGeomGetRotation (g2); dVector3 actual_pos; dMatrix3 actual_R; dMULTIPLY0_331 (actual_pos,R,pos2); actual_pos[0] += pos[0]; actual_pos[1] += pos[1]; actual_pos[2] += pos[2]; dMULTIPLY0_333 (actual_R,R,R2); drawGeom (g2,actual_pos,actual_R,0); } 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) { dsSetColor (0,0,2); 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 #include #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* pUserData, int x, int z ) { dIASSERT( x < HFIELD_WSTEP ); dIASSERT( z < HFIELD_DSTEP ); 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 *data, 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= 'A' && c <= 'Z') return c - ('a'-'A'); else return c; } // called when a key pressed static void command (int cmd) { size_t i; int j,k; dReal sides[3]; dMass m; 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++; 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()-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 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); 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]); } //<---- Convex Object else if (cmd == 'v') { dMassSetBox (&m,DENSITY,0.25,0.25,0.25); obj[i].geom[0] = dCreateConvex (space, planes, planecount, points, pointcount, polygons); } //----> Convex Object 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)); 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') { dGeomID g2[GPB]; // encapsulated geometries dReal dpos[GPB][3]; // delta-positions for encapsulated geometries // start accumulating masses for the encapsulated geometries dMass m2; dMassSetZero (&m); // set random delta positions for (j=0; j= 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 == '1') { write_world = 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); } //<---- Convex Object else if (type == dConvexClass) { //dVector3 sides={0.50,0.50,0.50}; dsDrawConvex(pos,R,planes, planecount, points, pointcount, polygons); } //----> Convex Object else if (type == dCylinderClass) { dReal radius,length; dGeomCylinderGetParams (g,&radius,&length); dsDrawCylinder (pos,R,length,radius); } else if (type == dGeomTransformClass) { dGeomID g2 = dGeomTransformGetGeom (g); const dReal *pos2 = dGeomGetPosition (g2); const dReal *R2 = dGeomGetRotation (g2); dVector3 actual_pos; dMatrix3 actual_R; dMULTIPLY0_331 (actual_pos,R,pos2); actual_pos[0] += pos[0]; actual_pos[1] += pos[1]; actual_pos[2] += pos[2]; dMULTIPLY0_333 (actual_R,R,R2); drawGeom (g2,actual_pos,actual_R,0); } 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) { int i,j; dsSetColor (0,0,2); dSpaceCollide (space,0,&nearCallback); //if (!pause) dWorldStep (world,0.05); //if (!pause) dWorldQuickStep (world,0.05); if (!pause) dWorldStepFast1 (world,0.05, 5); 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); const dReal* pReal = dGeomGetPosition( gheight ); const dReal* RReal = dGeomGetRotation( gheight ); // // Draw Heightfield // // 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( pReal, RReal, a, c, b, 1 ); dsDrawTriangle( pReal, RReal, b, c, d, 1 ); } } dsSetColor (1,1,0); dsSetTexture (DS_WOOD); for (i=0; i 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 #include #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 *data, 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 #include #ifdef HAVE_UNISTD_H #include #endif #include #include #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", o1,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 #include #ifdef HAVE_UNISTD_H #include #endif #include #include #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", o1,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 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; i1.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; ifirstbody; 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 = dDOT( 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 = dDOT( 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 = dDOT( b->avel, b->avel ); if (aspeed > max_ang_speed*max_ang_speed) { const dReal coef = max_ang_speed/dSqrt(aspeed); dOPEC(b->avel, *=, coef); } } // end of angular velocity cap int j; // handle linear velocity for (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 = dDOT (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 (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 (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 (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 for (dxGeom *geom = b->geom; geom; geom = dGeomGetBodyNext (geom)) dGeomMoved (geom); // notify the user if (b->moved_callback) b->moved_callback(b); // damping if (b->flags & dxBodyLinearDamping) { const dReal lin_threshold = b->dampingp.linear_threshold; const dReal lin_speed = dDOT( b->lvel, b->lvel ); if ( lin_speed > lin_threshold) { const dReal k = 1 - b->dampingp.linear_scale; dOPEC(b->lvel, *=, k); } } if (b->flags & dxBodyAngularDamping) { const dReal ang_threshold = b->dampingp.angular_threshold; const dReal ang_speed = dDOT( b->avel, b->avel ); if ( ang_speed > ang_threshold) { const dReal k = 1 - b->dampingp.angular_scale; dOPEC(b->avel, *=, k); } } } //**************************************************************************** // island processing // 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. void dxProcessIslands (dxWorld *world, dReal stepsize, dstepper_fn_t stepper) { dxBody *b,*bb,**body; dxJoint *j,**joint; // nothing to do if no bodies if (world->nb <= 0) return; // handle auto-disabling of bodies dInternalHandleAutoDisabling (world,stepsize); // make arrays for body and joint lists (for a single island) to go into body = (dxBody**) ALLOCA (world->nb * sizeof(dxBody*)); joint = (dxJoint**) ALLOCA (world->nj * sizeof(dxJoint*)); int bcount = 0; // number of bodies in `body' int jcount = 0; // number of joints in `joint' // set all body/joint tags to 0 for (b=world->firstbody; b; b=(dxBody*)b->next) b->tag = 0; for (j=world->firstjoint; j; j=(dxJoint*)j->next) j->tag = 0; // 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! int stackalloc = (world->nj < world->nb) ? world->nj : world->nb; dxBody **stack = (dxBody**) ALLOCA (stackalloc * sizeof(dxBody*)); for (bb=world->firstbody; bb; bb=(dxBody*)bb->next) { // get bb = the next enabled, untagged body, and tag it if (bb->tag || (bb->flags & dxBodyDisabled)) continue; bb->tag = 1; // tag all bodies and joints starting from bb. int stacksize = 0; b = bb; body[0] = bb; bcount = 1; jcount = 0; goto quickstart; while (stacksize > 0) { b = stack[--stacksize]; // pop body off stack body[bcount++] = b; // put body on body list quickstart: // traverse and tag all body's joints, add untagged connected bodies // to stack for (dxJointNode *n=b->firstjoint; n; n=n->next) { if (!n->joint->tag && n->joint->isEnabled()) { n->joint->tag = 1; joint[jcount++] = n->joint; if (n->body && !n->body->tag) { n->body->tag = 1; stack[stacksize++] = n->body; } } } dIASSERT(stacksize <= world->nb); dIASSERT(stacksize <= world->nj); } // now do something with body and joint lists stepper (world,body,bcount,joint,jcount,stepsize); // what we've just done may have altered the body/joint tag values. // we must make sure that these tags are nonzero. // also make sure all bodies are in the enabled state. int i; for (i=0; itag = 1; body[i]->flags &= ~dxBodyDisabled; } for (i=0; itag = 1; } // if debugging, check that all objects (except for disabled bodies, // unconnected joints, and joints that are connected to disabled bodies) // were tagged. # ifndef dNODEBUG for (b=world->firstbody; b; b=(dxBody*)b->next) { if (b->flags & dxBodyDisabled) { if (b->tag) dDebug (0,"disabled body tagged"); } else { if (!b->tag) dDebug (0,"enabled body not tagged"); } } for (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) dDebug (0,"attached enabled joint not tagged"); } else { if (j->tag) dDebug (0,"unattached or disabled joint tagged"); } } # endif } ode-0.11.1/ode/src/quickstep.cpp0000644000076400007640000006316711205772203013360 00000000000000/************************************************************************* * * * 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 "objects.h" #include "joints/joint.h" #include #include "config.h" #include #include #include #include #include #include #include "lcp.h" #include "util.h" #define ALLOCA dALLOCA16 typedef const dReal *dRealPtr; typedef dReal *dRealMutablePtr; #define dRealAllocaArray(name,n) dReal *name = (dReal*) ALLOCA ((n)*sizeof(dReal)); //*************************************************************************** // 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 // 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 REORDER_CONSTRAINTS 1 // 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 RANDOMLY_REORDER_CONSTRAINTS 1 //**************************************************************************** // special matrix multipliers // multiply block of B matrix (q x 6) with 12 dReal per row with C vektor (q) static void Multiply1_12q1 (dReal *A, dReal *B, dReal *C, int q) { int i, k; 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(i=0, k = 0; iinvMass; for (j=0; j<3; j++) iMJ_ptr[j] = k*J_ptr[j]; dMULTIPLY0_331 (iMJ_ptr + 3, invI + 12*b1, J_ptr + 3); if (b2 >= 0) { k = body[b2]->invMass; for (j=0; j<3; j++) iMJ_ptr[j+6] = k*J_ptr[j+6]; dMULTIPLY0_331 (iMJ_ptr + 9, invI + 12*b2, J_ptr + 9); } J_ptr += 12; iMJ_ptr += 12; } } // compute out = inv(M)*J'*in. #if 0 static void multiply_invM_JT (int m, int nb, dRealMutablePtr iMJ, int *jb, dRealMutablePtr in, dRealMutablePtr out) { int i,j; dSetZero (out,6*nb); dRealPtr iMJ_ptr = iMJ; for (i=0; i= 0) { out_ptr = out + b2*6; for (j=0; j<6; j++) out_ptr[j] += iMJ_ptr[j] * in[i]; } iMJ_ptr += 6; } } #endif // compute out = J*in. static void multiply_J (int m, dRealMutablePtr J, int *jb, dRealMutablePtr in, dRealMutablePtr out) { int i,j; dRealPtr J_ptr = J; for (i=0; i= 0) { in_ptr = in + b2*6; for (j=0; j<6; j++) sum += J_ptr[j] * in_ptr[j]; } J_ptr += 6; out[i] = sum; } } // compute out = (J*inv(M)*J' + cfm)*in. // use z as an nb*6 temporary. #if 0 static void multiply_J_invM_JT (int m, int nb, dRealMutablePtr J, dRealMutablePtr iMJ, int *jb, dRealPtr cfm, dRealMutablePtr z, dRealMutablePtr in, dRealMutablePtr out) { multiply_invM_JT (m,nb,iMJ,jb,in,z); multiply_J (m,J,jb,z,out); // add cfm for (int i=0; inum_iterations; // precompute iMJ = inv(M)*J' dRealAllocaArray (iMJ,m*12); compute_invM_JT (m,J,iMJ,jb,body,invI); dReal last_rho = 0; dRealAllocaArray (r,m); dRealAllocaArray (z,m); dRealAllocaArray (p,m); dRealAllocaArray (q,m); // precompute 1 / diagonals of A dRealAllocaArray (Ad,m); dRealPtr iMJ_ptr = iMJ; dRealPtr J_ptr = J; for (i=0; i= 0) { for (j=6; j<12; j++) sum += iMJ_ptr[j] * J_ptr[j]; } iMJ_ptr += 12; J_ptr += 12; Ad[i] = REAL(1.0) / (sum + cfm[i]); } #ifdef WARM_STARTING // compute residual r = b - A*lambda multiply_J_invM_JT (m,nb,J,iMJ,jb,cfm,fc,lambda,r); for (i=0; ifindex < 0 && i2->findex >= 0) return -1; if (i1->findex >= 0 && i2->findex < 0) return 1; if (i1->error < i2->error) return -1; if (i1->error > i2->error) return 1; return 0; } #endif static void SOR_LCP (int m, int nb, dRealMutablePtr J, int *jb, dxBody * const *body, dRealPtr invI, dRealMutablePtr lambda, dRealMutablePtr fc, dRealMutablePtr b, dRealMutablePtr lo, dRealMutablePtr hi, dRealPtr cfm, int *findex, dxQuickStepParameters *qs) { const int num_iterations = qs->num_iterations; const dReal sor_w = qs->w; // SOR over-relaxation parameter int i,j; #ifdef WARM_STARTING // for warm starting, this seems to be necessary to prevent // jerkiness in motor-driven joints. i have no idea why this works. for (i=0; i= 0) { for (j=6; j<12; j++) sum += iMJ_ptr[j] * J_ptr[j]; } iMJ_ptr += 12; J_ptr += 12; Ad[i] = sor_w / (sum + cfm[i]); } // scale J and b by Ad J_ptr = J; for (i=0; i v2) ? v1 : v2; if (max > 0) { //@@@ relative error: order[i].error = dFabs(lambda[i]-last_lambda[i])/max; order[i].error = dFabs(lambda[i]-last_lambda[i]); } else { order[i].error = dInfinity; } order[i].findex = findex[i]; order[i].index = i; } } qsort (order,m,sizeof(IndexError),&compare_index_error); //@@@ potential optimization: swap lambda and last_lambda pointers rather // than copying the data. we must make sure lambda is properly // returned to the caller memcpy (last_lambda,lambda,m*sizeof(dReal)); #endif #ifdef RANDOMLY_REORDER_CONSTRAINTS if ((iteration & 7) == 0) { for (i=1; i= 0) { hi[index] = dFabs (hicopy[index] * lambda[findex[index]]); lo[index] = -hi[index]; } int b1 = jb[index*2]; int b2 = jb[index*2+1]; dReal delta = b[index] - lambda[index]*Ad[index]; dRealMutablePtr fc_ptr = fc + 6*b1; // @@@ potential optimization: SIMD-ize this and the b2 >= 0 case delta -=fc_ptr[0] * J_ptr[0] + fc_ptr[1] * J_ptr[1] + fc_ptr[2] * J_ptr[2] + fc_ptr[3] * J_ptr[3] + fc_ptr[4] * J_ptr[4] + fc_ptr[5] * J_ptr[5]; // @@@ potential optimization: handle 1-body constraints in a separate // loop to avoid the cost of test & jump? if (b2 >= 0) { fc_ptr = fc + 6*b2; delta -=fc_ptr[0] * J_ptr[6] + fc_ptr[1] * J_ptr[7] + fc_ptr[2] * J_ptr[8] + fc_ptr[3] * J_ptr[9] + fc_ptr[4] * J_ptr[10] + fc_ptr[5] * J_ptr[11]; } // compute lambda and clamp it to [lo,hi]. // @@@ potential optimization: does SSE have clamping instructions // to save test+jump penalties here? dReal new_lambda = lambda[index] + delta; if (new_lambda < lo[index]) { delta = lo[index]-lambda[index]; lambda[index] = lo[index]; } else if (new_lambda > hi[index]) { delta = hi[index]-lambda[index]; lambda[index] = hi[index]; } else { lambda[index] = new_lambda; } //@@@ a trick that may or may not help //dReal ramp = (1-((dReal)(iteration+1)/(dReal)num_iterations)); //delta *= ramp; // update fc. // @@@ potential optimization: SIMD for this and the b2 >= 0 case fc_ptr = fc + 6*b1; fc_ptr[0] += delta * iMJ_ptr[0]; fc_ptr[1] += delta * iMJ_ptr[1]; fc_ptr[2] += delta * iMJ_ptr[2]; fc_ptr[3] += delta * iMJ_ptr[3]; fc_ptr[4] += delta * iMJ_ptr[4]; fc_ptr[5] += delta * iMJ_ptr[5]; // @@@ potential optimization: handle 1-body constraints in a separate // loop to avoid the cost of test & jump? if (b2 >= 0) { fc_ptr = fc + 6*b2; fc_ptr[0] += delta * iMJ_ptr[6]; fc_ptr[1] += delta * iMJ_ptr[7]; fc_ptr[2] += delta * iMJ_ptr[8]; fc_ptr[3] += delta * iMJ_ptr[9]; fc_ptr[4] += delta * iMJ_ptr[10]; fc_ptr[5] += delta * iMJ_ptr[11]; } } } } void dxQuickStepper (dxWorld *world, dxBody * const *body, int nb, dxJoint * const *_joint, int nj, dReal stepsize) { int i,j; IFTIMING(dTimerStart("preprocessing");) dReal stepsize1 = dRecip(stepsize); // number all bodies in the body list - set their tag values for (i=0; itag = i; // make a local copy of the joint array, because we might want to modify it. // (the "dxJoint *const*" declaration says we're allowed to modify the joints // but not the joint array, because the caller might need it unchanged). //@@@ do we really need to do this? we'll be sorting constraint rows individually, not joints dxJoint **joint = (dxJoint**) ALLOCA (nj * sizeof(dxJoint*)); memcpy (joint,_joint,nj * sizeof(dxJoint*)); // 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. dRealAllocaArray (invI,3*4*nb); for (i=0; iinvI,body[i]->posr.R); dMULTIPLY0_333 (invI+i*12,body[i]->posr.R,tmp); if (body[i]->flags & dxBodyGyroscopic) { dMatrix3 I; // compute inertia tensor in global frame dMULTIPLY2_333 (tmp,body[i]->mass.I,body[i]->posr.R); dMULTIPLY0_333 (I,body[i]->posr.R,tmp); // compute rotational force dMULTIPLY0_331 (tmp,I,body[i]->avel); dCROSS (body[i]->tacc,-=,body[i]->avel,tmp); } } // add the gravity force to all bodies for (i=0; iflags & dxBodyNoGravity)==0) { body[i]->facc[0] += body[i]->mass.mass * world->gravity[0]; body[i]->facc[1] += body[i]->mass.mass * world->gravity[1]; body[i]->facc[2] += body[i]->mass.mass * world->gravity[2]; } } // 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. //@@@ do we really need to save all the info1's dxJoint::Info1 *info = (dxJoint::Info1*) ALLOCA (nj*sizeof(dxJoint::Info1)); for (i=0, j=0; jgetInfo1 (info+i); dIASSERT (info[i].m >= 0 && info[i].m <= 6 && info[i].nub >= 0 && info[i].nub <= info[i].m); if (info[i].m > 0) { joint[i] = joint[j]; i++; } } nj = i; // create the row offset array int m = 0; int *ofs = (int*) ALLOCA (nj*sizeof(int)); for (i=0; i 0) { // 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. dRealAllocaArray (c,m); dRealAllocaArray (cfm,m); dRealAllocaArray (lo,m); dRealAllocaArray (hi,m); int *findex = (int*) ALLOCA (m*sizeof(int)); dSetZero (c,m); dSetValue (cfm,m,world->global_cfm); dSetValue (lo,m,-dInfinity); dSetValue (hi,m, dInfinity); for (i=0; iglobal_erp; int mfb = 0; // number of rows of Jacobian we will have to save for joint feedback for (i=0; igetInfo2 (&Jinfo); // adjust returned findex values for global index numbering for (j=0; j= 0) findex[ofs[i] + j] += ofs[i]; } if (joint[i]->feedback) mfb += info[i].m; } // 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 normaly much less) dReal *Jcopy = NULL; if (mfb > 0) { Jcopy = (dReal*) ALLOCA (mfb*12*sizeof(dReal)); mfb = 0; for (i=0; ifeedback) { memcpy(Jcopy+mfb*12, J+ofs[i]*12, info[i].m*12*sizeof(dReal)); mfb += info[i].m; } } // create an array of body numbers for each joint row int *jb_ptr = jb; for (i=0; inode[0].body) ? (joint[i]->node[0].body->tag) : -1; int b2 = (joint[i]->node[1].body) ? (joint[i]->node[1].body->tag) : -1; for (j=0; jinvMass; for (j=0; j<3; j++) tmp1[i*6+j] = body[i]->facc[j] * body_invMass + body[i]->lvel[j] * stepsize1; dMULTIPLY0_331 (tmp1 + i*6 + 3,invI + i*12,body[i]->tacc); for (j=0; j<3; j++) tmp1[i*6+3+j] += body[i]->avel[j] * stepsize1; } // put J*tmp1 into rhs dRealAllocaArray (rhs,m); multiply_J (m,J,jb,tmp1,rhs); // complete rhs for (i=0; ilambda,info[i].m * sizeof(dReal)); } #endif // solve the LCP problem and get lambda and invM*constraint_force IFTIMING (dTimerNow ("solving LCP problem");) dRealAllocaArray (cforce,nb*6); SOR_LCP (m,nb,J,jb,body,invI,lambda,cforce,rhs,lo,hi,cfm,findex,&world->qs); #ifdef WARM_STARTING // save lambda for the next iteration //@@@ note that this doesn't work for contact joints yet, as they are // recreated every iteration for (i=0; ilambda,lambda+ofs[i],info[i].m * sizeof(dReal)); } #endif // note that the SOR method overwrites rhs and J at this point, so // they should not be used again. // add stepsize * cforce to the body velocity for (i=0; ilvel[j] += stepsize * cforce[i*6+j]; for (j=0; j<3; j++) body[i]->avel[j] += stepsize * cforce[i*6+3+j]; } if (mfb > 0) { // straightforward computation of joint constraint forces: // multiply related lambdas with respective J' block for joints // where feedback was requested mfb = 0; for (i=0; ifeedback) { dJointFeedback *fb = joint[i]->feedback; dReal data[6]; Multiply1_12q1 (data, Jcopy+mfb*12, lambda+ofs[i], info[i].m); fb->f1[0] = data[0]; fb->f1[1] = data[1]; fb->f1[2] = data[2]; fb->t1[0] = data[3]; fb->t1[1] = data[4]; fb->t1[2] = data[5]; if (joint[i]->node[1].body) { Multiply1_12q1 (data, Jcopy+mfb*12+6, lambda+ofs[i], info[i].m); fb->f2[0] = data[0]; fb->f2[1] = data[1]; fb->f2[2] = data[2]; fb->t2[0] = data[3]; fb->t2[1] = data[4]; fb->t2[2] = data[5]; } mfb += info[i].m; } } } } // compute the velocity update: // add stepsize * invM * fe to the body velocity IFTIMING (dTimerNow ("compute velocity update");) for (i=0; iinvMass; for (j=0; j<3; j++) body[i]->lvel[j] += stepsize * body_invMass * body[i]->facc[j]; for (j=0; j<3; j++) body[i]->tacc[j] *= stepsize; dMULTIPLYADD0_331 (body[i]->avel,invI + i*12,body[i]->tacc); } #if 0 // check that the updated velocity obeys the constraint (this check needs unmodified J) dRealAllocaArray (vel,nb*6); for (i=0; ilvel[j]; for (j=0; j<3; j++) vel[i*6+3+j] = body[i]->avel[j]; } dRealAllocaArray (tmp,m); multiply_J (m,J,jb,vel,tmp); dReal error = 0; for (i=0; ifacc,3); dSetZero (body[i]->tacc,3); } IFTIMING (dTimerEnd();) IFTIMING (if (m > 0) dTimerReport (stdout,1);) } ode-0.11.1/ode/src/collision_transform.cpp0000644000076400007640000001574010737023615015435 00000000000000/************************************************************************* * * * 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 #include #include #include #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; ig1 = 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; } ode-0.11.1/ode/src/obstack.h0000644000076400007640000000567710412315665012451 00000000000000/************************************************************************* * * * 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 { struct Arena { Arena *next; // next arena in linked list size_t used; // total number of bytes used in this arena, counting }; // this header Arena *first; // head of the arena linked list. 0 if no arenas yet Arena *last; // arena where blocks are currently being allocated // used for iterator Arena *current_arena; size_t current_ofs; dObStack(); ~dObStack(); void *alloc (int 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 (int 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(). }; #endif ode-0.11.1/ode/src/config.h.in0000644000076400007640000002120311206343411012644 00000000000000/* ode/src/config.h.in. Generated from configure.in 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 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 `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 header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ #undef HAVE_DOPRNT /* Define to 1 if you have the `fabsf' function. */ #undef HAVE_FABSF /* Define to 1 if you have the 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 header file. */ #undef HAVE_GL_GLEXT_H /* Define to 1 if you have the header file. */ #undef HAVE_GL_GLU_H /* Define to 1 if you have the header file. */ #undef HAVE_GL_GL_H /* Define to 1 if you have the 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 `sunmath' library (-lsunmath). */ #undef HAVE_LIBSUNMATH /* Define to 1 if your system has a GNU libc compatible `malloc' function, and to 0 otherwise. */ #undef HAVE_MALLOC /* Define to 1 if you have the header file. */ #undef HAVE_MALLOC_H /* Define to 1 if you have the 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 header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `memset' function. */ #undef HAVE_MEMSET /* Define to 1 if libc includes obstacks. */ #undef HAVE_OBSTACK /* Define to 1 if your system has a GNU libc compatible `realloc' function, and to 0 otherwise. */ #undef HAVE_REALLOC /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT /* 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 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 header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDIO_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SELECT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `vprintf' function. */ #undef HAVE_VPRINTF /* 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 in which libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Mac OS X version setting for OU Library */ #undef MAC_OS_X_VERSION /* Define to 1 if your C compiler doesn't accept -c and -o together. */ #undef NO_MINUS_C_MINUS_O /* 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 version of this package. */ #undef PACKAGE_VERSION /* compiling for a pentium on a gcc-based platform? */ #undef PENTIUM /* Define to the type of arg 1 for `select'. */ #undef SELECT_TYPE_ARG1 /* Define to the type of args 2, 3 and 4 for `select'. */ #undef SELECT_TYPE_ARG234 /* Define to the type of arg 5 for `select'. */ #undef SELECT_TYPE_ARG5 /* 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 /* Define to 1 if the X Window System is missing or not being used. */ #undef X_DISPLAY_MISSING /* libou namespace for ODE */ #undef _OU_NAMESPACE /* Target OS setting for OU Library */ #undef _OU_TARGET_OS /* Atomic API of OU is enabled */ #undef dATOMICS_ENABLED /* Generic OU features are enabled */ #undef dOU_ENABLED /* 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 /* use malloc() instead of alloca() */ #undef dUSE_MALLOC_FOR_ALLOCA /* 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 rpl_malloc if the replacement function should be used. */ #undef malloc /* Define to rpl_realloc if the replacement function should be used. */ #undef realloc /* Define to `unsigned int' if does not define. */ #undef size_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 #endif #ifdef HAVE_MALLOC_H #include #endif #ifdef HAVE_STDINT_H #include #endif /* an integer type that we can safely cast a pointer to and * from without loss of bits. */ typedef uintptr_t intP; // Use the error-checking memory allocation system. Because this system uses heap // (malloc) instead of stack (alloca), it is slower. However, it allows you to // simulate larger scenes, as well as handle out-of-memory errors in a somewhat // graceful manner #ifdef dUSE_MALLOC_FOR_ALLOCA enum { d_MEMORY_OK = 0, /* no memory errors */ d_MEMORY_OUT_OF_MEMORY /* malloc failed due to out of memory error */ }; #endif #ifdef dSINGLE #define dEpsilon FLT_EPSILON #else #define dEpsilon DBL_EPSILON #endif #endif /* #define ODE_CONFIG_H */ ode-0.11.1/ode/src/memory.cpp0000644000076400007640000000523410771630024012650 00000000000000/************************************************************************* * * * 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 #include "config.h" #include #include 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 (size_t size) { if (allocfn) return allocfn (size); else return malloc (size); } void * dRealloc (void *ptr, size_t oldsize, size_t newsize) { if (reallocfn) return reallocfn (ptr,oldsize,newsize); else return realloc (ptr,newsize); } void dFree (void *ptr, size_t size) { if (!ptr) return; if (freefn) freefn (ptr,size); else free (ptr); } ode-0.11.1/ode/src/collision_cylinder_box.cpp0000644000076400007640000006634211116517541016105 00000000000000/************************************************************************* * * * 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 #include #include #include #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(dVector3Length2( vAxis ) > fEpsilon ) { if (!_cldTestAxis( vAxis, 5 )) { return 0; } } // axis CxA1 //vAxis = ( vCylinderAxis cross mthGetColM33f( mBoxRot, 1 )); dVector3CrossMat3Col(m_mBoxRot, 1 ,m_vCylinderAxis, vAxis); if(dVector3Length2( vAxis ) > fEpsilon ) { if (!_cldTestAxis( vAxis, 6 )) { return 0; } } // axis CxA2 //vAxis = ( vCylinderAxis cross mthGetColM33f( mBoxRot, 2 )); dVector3CrossMat3Col(m_mBoxRot, 2 ,m_vCylinderAxis, vAxis); if(dVector3Length2( 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(dVector3Length2( 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= 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 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 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(); } ode-0.11.1/ode/src/mass.cpp0000644000076400007640000003362211046662653012316 00000000000000/************************************************************************* * * * 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 #include "config.h" #include #include #include // 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)) { 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); dCROSSMAT (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)) { 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 = (dxTriMesh *)g; unsigned int triangles = FetchTriangleCount( TriMesh ); 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]; FetchTransformedTriangle( TriMesh, i, v); dVector3 n, a, b; dOP( a, -, v[1], v[0] ); dOP( b, -, v[2], v[0] ); dCROSS( 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 = - dDOT(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); dCROSSMAT (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); dCROSSMAT (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); } ode-0.11.1/ode/src/error.cpp0000644000076400007640000001067210765152110012471 00000000000000/************************************************************************* * * * 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 #include "config.h" #include 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); 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); // *((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); } #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); } 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); } 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); } #endif ode-0.11.1/ode/src/collision_trimesh_gimpact.cpp0000644000076400007640000003366211142520432016572 00000000000000/************************************************************************* * * * 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 #include #include #include #include "config.h" #if dTRIMESH_ENABLED #include "collision_util.h" #include "collision_trimesh_internal.h" #if dTRIMESH_GIMPACT void dxTriMeshData::Preprocess(){ // stub } dTriMeshDataID dGeomTriMeshDataCreate(){ return new dxTriMeshData(); } void dGeomTriMeshDataDestroy(dTriMeshDataID g){ delete g; } void dGeomTriMeshSetLastTransform( dxGeom* g, dMatrix4 last_trans ) { //stub } dReal* dGeomTriMeshGetLastTransform( dxGeom* g ) { return NULL; // stub } void dGeomTriMeshDataSet(dTriMeshDataID g, int data_id, void* in_data) { //stub } void* dGeomTriMeshDataGet(dTriMeshDataID g, int data_id) { dUASSERT(g, "argument not trimesh data"); return NULL; // stub } void dGeomTriMeshDataBuildSingle1(dTriMeshDataID g, const void* Vertices, int VertexStride, int VertexCount, const void* Indices, int IndexCount, int TriStride, const void* Normals) { dUASSERT(g, "argument not trimesh data"); dIASSERT(Vertices); dIASSERT(Indices); g->Build(Vertices, VertexStride, VertexCount, Indices, IndexCount, TriStride, Normals, true); } 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, (void*)NULL); } void dGeomTriMeshDataBuildDouble1(dTriMeshDataID g, const void* Vertices, int VertexStride, int VertexCount, const void* Indices, int IndexCount, int TriStride, const void* Normals) { dUASSERT(g, "argument not trimesh data"); g->Build(Vertices, VertexStride, VertexCount, Indices, IndexCount, TriStride, Normals, false); } 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); } 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(unsigned int), Normals); #endif } void dGeomTriMeshDataBuildSimple(dTriMeshDataID g, const dReal* Vertices, int VertexCount, const dTriIndex* Indices, int IndexCount) { dGeomTriMeshDataBuildSimple1(g, Vertices, VertexCount, Indices, IndexCount, (const int*)NULL); } void dGeomTriMeshDataPreprocess(dTriMeshDataID g) { dUASSERT(g, "argument not trimesh data"); g->Preprocess(); } void dGeomTriMeshDataGetBuffer(dTriMeshDataID g, unsigned char** buf, int* bufLen) { dUASSERT(g, "argument not trimesh data"); *buf = NULL; *bufLen = 0; } void dGeomTriMeshDataSetBuffer(dTriMeshDataID g, unsigned char* buf) { dUASSERT(g, "argument not trimesh data"); // g->UseFlags = buf; } // Trimesh dxTriMesh::dxTriMesh(dSpaceID Space, dTriMeshDataID Data) : dxGeom(Space, 1){ type = dTriMeshClass; Callback = NULL; ArrayCallback = NULL; RayCallback = NULL; TriMergeCallback = NULL; // Not initialized in dCreateTriMesh gim_init_buffer_managers(m_buffer_managers); dGeomTriMeshSetData(this,Data); /* TC has speed/space 'issues' that don't make it a clear win by default on spheres/boxes. */ this->doSphereTC = true; this->doBoxTC = true; this->doCapsuleTC = true; } dxTriMesh::~dxTriMesh(){ //Terminate Trimesh gim_trimesh_destroy(&m_collision_trimesh); gim_terminate_buffer_managers(m_buffer_managers); } void dxTriMesh::ClearTCCache(){ } int dxTriMesh::AABBTest(dxGeom* g, dReal aabb[6]){ return 1; } 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 dxTriMeshData::UpdateData() { // BVTree.Refit(); } dGeomID dCreateTriMesh(dSpaceID space, dTriMeshDataID Data, dTriCallback* Callback, dTriArrayCallback* ArrayCallback, dTriRayCallback* RayCallback) { dxTriMesh* Geom = new dxTriMesh(space, Data); Geom->Callback = Callback; Geom->ArrayCallback = ArrayCallback; Geom->RayCallback = RayCallback; return Geom; } void dGeomTriMeshSetCallback(dGeomID g, dTriCallback* Callback) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); ((dxTriMesh*)g)->Callback = Callback; } dTriCallback* dGeomTriMeshGetCallback(dGeomID g) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); return ((dxTriMesh*)g)->Callback; } void dGeomTriMeshSetArrayCallback(dGeomID g, dTriArrayCallback* ArrayCallback) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); ((dxTriMesh*)g)->ArrayCallback = ArrayCallback; } dTriArrayCallback* dGeomTriMeshGetArrayCallback(dGeomID g) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); return ((dxTriMesh*)g)->ArrayCallback; } void dGeomTriMeshSetRayCallback(dGeomID g, dTriRayCallback* Callback) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); ((dxTriMesh*)g)->RayCallback = Callback; } dTriRayCallback* dGeomTriMeshGetRayCallback(dGeomID g) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); return ((dxTriMesh*)g)->RayCallback; } void dGeomTriMeshSetTriMergeCallback(dGeomID g, dTriTriMergeCallback* Callback) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); ((dxTriMesh*)g)->TriMergeCallback = Callback; } dTriTriMergeCallback* dGeomTriMeshGetTriMergeCallback(dGeomID g) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); return ((dxTriMesh*)g)->TriMergeCallback; } void dGeomTriMeshSetData(dGeomID g, dTriMeshDataID Data) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); dxTriMesh* mesh = (dxTriMesh*) g; mesh->Data = Data; // I changed my data -- I know nothing about my own AABB anymore. ((dxTriMesh*)g)->gflags |= (GEOM_DIRTY|GEOM_AABB_BAD); // GIMPACT only supports stride 12, so we need to catch the error early. dUASSERT ( Data->m_VertexStride == 3*sizeof(float) && Data->m_TriStride == 3*sizeof(int), "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" ); //Create trimesh if ( Data->m_Vertices ) gim_trimesh_create_from_data ( mesh->m_buffer_managers, &mesh->m_collision_trimesh, // gimpact mesh ( vec3f *)(&Data->m_Vertices[0]), // vertices Data->m_VertexCount, // nr of verts 0, // copy verts? ( GUINT32 *)(&Data->m_Indices[0]), // indices Data->m_TriangleCount*3, // nr of indices 0, // copy indices? 1 // transformed reply ); } dTriMeshDataID dGeomTriMeshGetData(dGeomID g) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); return ((dxTriMesh*)g)->Data; } void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); switch (geomClass) { case dSphereClass: ((dxTriMesh*)g)->doSphereTC = (1 == enable); break; case dBoxClass: ((dxTriMesh*)g)->doBoxTC = (1 == enable); break; case dCapsuleClass: // case dCCylinderClass: ((dxTriMesh*)g)->doCapsuleTC = (1 == enable); break; } } int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); switch (geomClass) { case dSphereClass: if (((dxTriMesh*)g)->doSphereTC) return 1; break; case dBoxClass: if (((dxTriMesh*)g)->doBoxTC) return 1; break; case dCapsuleClass: if (((dxTriMesh*)g)->doCapsuleTC) return 1; break; } return 0; } void dGeomTriMeshClearTCCache(dGeomID g){ dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); dxTriMesh* Geom = (dxTriMesh*)g; Geom->ClearTCCache(); } /* * returns the TriMeshDataID */ dTriMeshDataID dGeomTriMeshGetTriMeshDataID(dGeomID g) { dxTriMesh* Geom = (dxTriMesh*) g; return Geom->Data; } // Getting data void dGeomTriMeshGetTriangle(dGeomID g, int Index, dVector3* v0, dVector3* v1, dVector3* v2) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); // Redirect null vectors to dummy storage dVector3 v[3]; dxTriMesh* Geom = (dxTriMesh*)g; FetchTransformedTriangle(Geom, Index, v); if (v0){ (*v0)[0] = v[0][0]; (*v0)[1] = v[0][1]; (*v0)[2] = v[0][2]; (*v0)[3] = v[0][3]; } if (v1){ (*v1)[0] = v[1][0]; (*v1)[1] = v[1][1]; (*v1)[2] = v[1][2]; (*v1)[3] = v[1][3]; } if (v2){ (*v2)[0] = v[2][0]; (*v2)[1] = v[2][1]; (*v2)[2] = v[2][2]; (*v2)[3] = v[2][3]; } } void dGeomTriMeshGetPoint(dGeomID g, int Index, dReal u, dReal v, dVector3 Out){ dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); dxTriMesh* Geom = (dxTriMesh*)g; dVector3 dv[3]; gim_trimesh_locks_work_data(&Geom->m_collision_trimesh); gim_trimesh_get_triangle_vertices(&Geom->m_collision_trimesh, Index, dv[0],dv[1],dv[2]); GetPointFromBarycentric(dv, u, v, Out); gim_trimesh_unlocks_work_data(&Geom->m_collision_trimesh); } int dGeomTriMeshGetTriangleCount (dGeomID g) { dxTriMesh* Geom = (dxTriMesh*)g; return FetchTriangleCount(Geom); } void dGeomTriMeshDataUpdate(dTriMeshDataID g) { dUASSERT(g, "argument not trimesh data"); g->UpdateData(); } // // GIMPACT TRIMESH-TRIMESH COLLIDER // 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; //Create contact list GDYNAMIC_ARRAY trimeshcontacts; GIM_CREATE_CONTACT_LIST(trimeshcontacts); g1 -> recomputeAABB(); g2 -> recomputeAABB(); //Collide trimeshes gim_trimesh_trimesh_collision(&TriMesh1->m_collision_trimesh,&TriMesh2->m_collision_trimesh,&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; unsigned maxcontacts = (unsigned)(Flags & NUMC_MASK); if (contactcount > maxcontacts) { contactcount = maxcontacts; } dContactGeom* pcontact; unsigned i; for (i=0;ipos[0] = ptrimeshcontacts->m_point[0]; pcontact->pos[1] = ptrimeshcontacts->m_point[1]; pcontact->pos[2] = ptrimeshcontacts->m_point[2]; pcontact->pos[3] = 1.0f; pcontact->normal[0] = ptrimeshcontacts->m_normal[0]; pcontact->normal[1] = ptrimeshcontacts->m_normal[1]; pcontact->normal[2] = ptrimeshcontacts->m_normal[2]; pcontact->normal[3] = 0; pcontact->depth = ptrimeshcontacts->m_depth; pcontact->g1 = g1; pcontact->g2 = g2; pcontact->side1 = ptrimeshcontacts->m_feature1; pcontact->side2 = ptrimeshcontacts->m_feature2; ptrimeshcontacts++; } GIM_DYNARRAY_DESTROY(trimeshcontacts); return (int)contactcount; } #endif // dTRIMESH_GIMPACT #endif // dTRIMESH_ENABLED ode-0.11.1/ode/src/quickstep.h0000644000076400007640000000337710052451016013015 00000000000000/************************************************************************* * * * 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 void dxQuickStepper (dxWorld *world, dxBody * const *body, int nb, dxJoint * const *_joint, int nj, dReal stepsize); #endif ode-0.11.1/ode/src/odeou.cpp0000644000076400007640000000722311005162546012453 00000000000000/************************************************************************* * * * OU library interface file for Open Dynamics Engine, * * Copyright (C) 2008 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 #include #include "config.h" #include "odeou.h" #if dOU_ENABLED template<> const char *const CEnumUnsortedElementArray::m_aetElementArray[] = { "assert", // AFS_ASSERT, "check", // AFS_CHECK, }; static const CEnumUnsortedElementArray 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 ode-0.11.1/ode/src/collision_std.h0000644000076400007640000002017311016651643013654 00000000000000/************************************************************************* * * * 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 #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 { dReal *planes; /*!< An array of planes in the form: normal X, normal Y, normal Z,Distance */ dReal *points; /*!< An array of points X,Y,Z */ 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, dReal *planes, unsigned int planecount, dReal *points, unsigned int pointcount, 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 = dDOT(points,rdir); dReal tmp; for (unsigned int i = 1; i < pointcount; ++i) { tmp = dDOT(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 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 Arcs,std::vector Polygons); void GetFacesSharedByVertex(int i, std::vector f); void GetFacesSharedByEdge(int i, int* f); void GetFaceNormal(int i, dVector3 normal); BSPNode* tree; #endif }; #endif ode-0.11.1/ode/src/plane.cpp0000644000076400007640000001052411142520432012427 00000000000000/************************************************************************* * * * 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 #include #include #include #include #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; } ode-0.11.1/ode/src/misc.cpp0000644000076400007640000001052110765152110012264 00000000000000/************************************************************************* * * * 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 #include "config.h" #include #include //**************************************************************************** // random numbers static unsigned long seed = 0; unsigned long dRand() { seed = (1664525L*seed + 1013904223L) & 0xffffffff; return seed; } 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) { // seems good; xor-fold and modulus const unsigned long un = n; unsigned long r = dRand(); // 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); } } } } } return (int) (r % un); } dReal dRandReal() { return ((dReal) dRand()) / ((dReal) 0xffffffff); } //**************************************************************************** // matrix utility stuff void dPrintMatrix (const dReal *A, int n, int m, char *fmt, FILE *f) { int i,j; int skip = dPAD(m); for (i=0; i max) max = diff; } } return max; } dReal dMaxDifferenceLowerTriangle (const dReal *A, const dReal *B, int n) { int i,j; int skip = dPAD(n); dReal diff,max; max = 0; for (i=0; i max) max = diff; } } return max; } ode-0.11.1/ode/src/obstack.cpp0000644000076400007640000001025311011472041012752 00000000000000/************************************************************************* * * * 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 #include #include #include "obstack.h" #include "util.h" //**************************************************************************** // macros and constants #define ROUND_UP_OFFSET_TO_EFFICIENT_SIZE(arena,ofs) \ ofs = (size_t) (dEFFICIENT_SIZE( ((intP)(arena)) + ofs ) - ((intP)(arena)) ); #define MAX_ALLOC_SIZE \ ((size_t)(dOBSTACK_ARENA_SIZE - sizeof (Arena) - EFFICIENT_ALIGNMENT + 1)) //**************************************************************************** // dObStack dObStack::dObStack() { first = 0; last = 0; current_arena = 0; current_ofs = 0; } dObStack::~dObStack() { // free all arenas Arena *a,*nexta; a = first; while (a) { nexta = a->next; dFree (a,dOBSTACK_ARENA_SIZE); a = nexta; } } void *dObStack::alloc (int num_bytes) { if ((size_t)num_bytes > MAX_ALLOC_SIZE) dDebug (0,"num_bytes too large"); // allocate or move to a new arena if necessary if (!first) { // allocate the first arena if necessary first = last = (Arena *) dAlloc (dOBSTACK_ARENA_SIZE); first->next = 0; first->used = sizeof (Arena); ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (first,first->used); } else { // we already have one or more arenas, see if a new arena must be used if ((last->used + num_bytes) > dOBSTACK_ARENA_SIZE) { if (!last->next) { last->next = (Arena *) dAlloc (dOBSTACK_ARENA_SIZE); last->next->next = 0; } last = last->next; last->used = sizeof (Arena); ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (last,last->used); } } // allocate an area in the arena char *c = ((char*) last) + last->used; last->used += num_bytes; ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (last,last->used); return c; } void dObStack::freeAll() { last = first; if (first) { first->used = sizeof(Arena); ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (first,first->used); } } void *dObStack::rewind() { current_arena = first; current_ofs = sizeof (Arena); if (current_arena) { ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (current_arena,current_ofs) return ((char*) current_arena) + current_ofs; } else return 0; } void *dObStack::next (int num_bytes) { // this functions like alloc, except that no new storage is ever allocated if (!current_arena) return 0; current_ofs += num_bytes; ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (current_arena,current_ofs); if (current_ofs >= current_arena->used) { current_arena = current_arena->next; if (!current_arena) return 0; current_ofs = sizeof (Arena); ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (current_arena,current_ofs); } return ((char*) current_arena) + current_ofs; } ode-0.11.1/ode/src/box.cpp0000644000076400007640000006472411142520432012133 00000000000000/************************************************************************* * * * 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 #include #include #include #include #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 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 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 = dDOT44(R1+0,R2+0); R12 = dDOT44(R1+0,R2+1); R13 = dDOT44(R1+0,R2+2); R21 = dDOT44(R1+1,R2+0); R22 = dDOT44(R1+1,R2+1); R23 = dDOT44(R1+1,R2+2); R31 = dDOT44(R1+2,R2+0); R32 = dDOT44(R1+2,R2+1); R33 = dDOT44(R1+2,R2+2); Q11 = 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 (dDOT41(R2+0,p),(A[0]*Q11 + A[1]*Q21 + A[2]*Q31 + B[0]),R2+0,4); TST (dDOT41(R2+1,p),(A[0]*Q12 + A[1]*Q22 + A[2]*Q32 + B[1]),R2+1,5); TST (dDOT41(R2+2,p),(A[0]*Q13 + A[1]*Q23 + A[2]*Q33 + B[2]),R2+2,6); // note: cross product axes need to be scaled when s is computed. // normal (n1,n2,n3) is relative to box 1. #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 = (dDOT14(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 = (dDOT14(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 = dDOT14 (center,Ra+code1); c2 = dDOT14 (center,Ra+code2); // optimize this? - we have already computed this data above, but it is not // stored in an easy-to-index format. for now it's quicker just to recompute // the four dot products. m11 = dDOT44 (Ra+code1,Rb+a1); m12 = dDOT44 (Ra+code1,Rb+a2); m21 = dDOT44 (Ra+code2,Rb+a1); m22 = dDOT44 (Ra+code2,Rb+a2); { 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] - dDOT(normal2,point+cnum*3); if (dep[cnum] >= 0) { ret[cnum*2] = ret[j*2]; ret[cnum*2+1] = ret[j*2+1]; cnum++; if ((cnum | 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 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; inormal[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 = dDOT14(n,R+0); dReal Q2 = dDOT14(n,R+1); dReal Q3 = dDOT14(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) - dDOT(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 > 3) maxc = 3; // not more than 3 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->normal[0] = n[0]; contact->normal[1] = n[1]; contact->normal[2] = n[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) \ depth -= B ## sideinc; \ if (depth < 0) goto done; \ if (A ## sideinc > 0) { FOO(ctact,side,+); } else { FOO(ctact,side,-); } \ CONTACT(contact,ctact*skip)->depth = depth; \ ret++; CONTACT(contact,skip)->normal[0] = n[0]; CONTACT(contact,skip)->normal[1] = n[1]; CONTACT(contact,skip)->normal[2] = n[2]; if (maxc == 3) { CONTACT(contact,2*skip)->normal[0] = n[0]; CONTACT(contact,2*skip)->normal[1] = n[1]; CONTACT(contact,2*skip)->normal[2] = n[2]; } 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: for (int i=0; ig1 = o1; currContact->g2 = o2; currContact->side1 = -1; currContact->side2 = -1; } return ret; } ode-0.11.1/ode/src/collision_trimesh_plane.cpp0000644000076400007640000001506511142520432016242 00000000000000/************************************************************************* * * * 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 #include #include #include #include "config.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. // // Cache the triangle count. const int tri_count = trimesh->Data->Mesh.GetNbTriangles(); VertexPointers VP; ConversionArea VC; dReal alpha; dVector3 vertex; #if !defined(dSINGLE) || 1 dVector3 int_vertex; // Intermediate vertex for double precision mode. #endif // dSINGLE // For each triangle for ( int t = 0; t < tri_count; ++t ) { // Get triangle, which should also use callback. trimesh->Data->Mesh.GetTriangle( VP, t, VC); // For each vertex. for ( int v = 0; v < 3; ++v ) { // // 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 ] - dDOT( 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 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; } unsigned int contactcount = collision_result.m_size; unsigned int contactmax = (unsigned int)(flags & NUMC_MASK); if (contactcount > contactmax) { contactcount = contactmax; } dContactGeom* pcontact; vec4f * planecontact_results = GIM_DYNARRAY_POINTER(vec4f,collision_result); for(unsigned int i = 0; i < contactcount; i++ ) { pcontact = SAFECONTACT(flags, contacts, i, skip); pcontact->pos[0] = (*planecontact_results)[0]; pcontact->pos[1] = (*planecontact_results)[1]; pcontact->pos[2] = (*planecontact_results)[2]; pcontact->pos[3] = REAL(1.0); pcontact->normal[0] = plane[0]; pcontact->normal[1] = plane[1]; pcontact->normal[2] = plane[2]; pcontact->normal[3] = 0; pcontact->depth = (*planecontact_results)[3]; pcontact->g1 = o1; // trimesh geom pcontact->g2 = o2; // plane geom pcontact->side1 = -1; // note: don't have the triangle index, but OPCODE *does* do this properly pcontact->side2 = -1; planecontact_results++; } GIM_DYNARRAY_DESTROY(collision_result); return (int)contactcount; } #endif // dTRIMESH_GIMPACT #endif // dTRIMESH_ENABLED ode-0.11.1/ode/src/collision_util.cpp0000644000076400007640000004516310737023615014401 00000000000000/************************************************************************* * * * 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 #include #include #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 = dDISTANCE (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 = dDOT(ua,ub); dReal q1 = dDOT(ua,p); dReal q2 = -dDOT(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 = dDOT(a1a2,a1b1); db1 = dDOT(b1b2,a1b1); if (da1 <= 0 && db1 >= 0) { SET2 (cp1,a1); SET2 (cp2,b1); return; } SET3 (a1b2,b2,-,a1); da2 = dDOT(a1a2,a1b2); db2 = dDOT(b1b2,a1b2); if (da2 <= 0 && db2 <= 0) { SET2 (cp1,a1); SET2 (cp2,b2); return; } SET3 (a2b1,b1,-,a2); da3 = dDOT(a1a2,a2b1); db3 = dDOT(b1b2,a2b1); if (da3 >= 0 && db3 >= 0) { SET2 (cp1,a2); SET2 (cp2,b1); return; } SET3 (a2b2,b2,-,a2); da4 = dDOT(a1a2,a2b2); db4 = dDOT(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 = dDOT(a1a2,a1a2); if (da1 >= 0 && da3 <= 0) { k = da1 / la; SET3 (n,a1b1,-,k*a1a2); if (dDOT(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 (dDOT(b1b2,n) <= 0) { SET3 (cp1,a1,+,k*a1a2); SET2 (cp2,b2); return; } } lb = dDOT(b1b2,b1b2); if (db1 <= 0 && db2 >= 0) { k = -db1 / lb; SET3 (n,-a1b1,-,k*b1b2); if (dDOT(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 (dDOT(a1a2,n) <= 0) { SET2 (cp1,a2); SET3 (cp2,b1,+,k*b1b2); return; } } // it must be edge-edge k = dDOT(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 = dDOT44(R1+0,R2+0); R12 = dDOT44(R1+0,R2+1); R13 = dDOT44(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 = dDOT44(R1+1,R2+0); R22 = dDOT44(R1+1,R2+1); R23 = dDOT44(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 = dDOT44(R1+2,R2+0); R32 = dDOT44(R1+2,R2+1); R33 = dDOT44(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(dDOT41(R2+0,p)) > (A1*Q11 + A2*Q21 + A3*Q31 + B1)) return 0; if (dFabs(dDOT41(R2+1,p)) > (A1*Q12 + A2*Q22 + A3*Q32 + B2)) return 0; if (dFabs(dDOT41(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 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= 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= 0 ) { // emit point if (dVector3Length2(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 (dVector3Length2(avArrayIn[i0]) <= fRadius*fRadius) { avArrayOut[ctOut][0] = vIntersectionPoint[0]; avArrayOut[ctOut][1] = vIntersectionPoint[1]; avArrayOut[ctOut][2] = vIntersectionPoint[2]; ctOut++; } } } } ode-0.11.1/ode/src/heightfield.h0000644000076400007640000001470411142520432013255 00000000000000// 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 #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 size_t asize = trianglelistCurrentSize; if (asize > 0) { maxAAAB = trianglelist[0]->maxAAAB; for (size_t k = 1; asize > k; k++) { if (trianglelist[k]->maxAAAB > maxAAAB) maxAAAB = trianglelist[k]->maxAAAB; } } }; void resetTriangleListSize(const size_t 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; size_t trianglelistReservedSize; size_t 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 size_t AlignBufferSize(size_t value, size_t alignment) { dIASSERT((alignment & (alignment - 1)) == 0); return (value + (alignment - 1)) & ~(alignment - 1); } void allocateTriangleBuffer(size_t numTri); void resetTriangleBuffer(); void allocatePlaneBuffer(size_t numTri); void resetPlaneBuffer(); void allocateHeightBuffer(size_t numX, size_t numZ); void resetHeightBuffer(); void sortPlanes(const size_t numPlanes); HeightFieldPlane **tempPlaneBuffer; HeightFieldPlane *tempPlaneInstances; size_t tempPlaneBufferSize; HeightFieldTriangle *tempTriangleBuffer; size_t tempTriangleBufferSize; HeightFieldVertex **tempHeightBuffer; HeightFieldVertex *tempHeightInstances; size_t tempHeightBufferSizeX; size_t tempHeightBufferSizeZ; }; //------------------------------------------------------------------------------ #endif //_DHEIGHTFIELD_H_ ode-0.11.1/ode/src/collision_trimesh_trimesh_new.cpp0000644000076400007640000010013311206274560017467 00000000000000/************************************************************************* * * * 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 Len (http://gimpact.sourceforge.net) #ifdef _MSC_VER #pragma warning(disable:4244 4305) // for VC++, no precision loss complaints #endif #include #include #include #include #include "config.h" // New Implementation #if !dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER #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 #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 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 CROSS(dest,v1,v2) { dest[0]=v1[1]*v2[2]-v1[2]*v2[1]; \ dest[1]=v1[2]*v2[0]-v1[0]*v2[2]; \ dest[2]=v1[0]*v2[1]-v1[1]*v2[0]; } #define DOT(v1,v2) (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2]) #define SUB(dest,v1,v2) { dest[0]=v1[0]-v2[0]; dest[1]=v1[1]-v2[1]; dest[2]=v1[2]-v2[2]; } #define ADD(dest,v1,v2) { dest[0]=v1[0]+v2[0]; dest[1]=v1[1]+v2[1]; dest[2]=v1[2]+v2[2]; } #define MULT(dest,v,factor) { dest[0]=factor*v[0]; dest[1]=factor*v[1]; dest[2]=factor*v[2]; } #define SET(dest,src) { dest[0]=src[0]; dest[1]=src[1]; dest[2]=src[2]; } #define SMULT(p,q,s) { p[0]=q[0]*s; p[1]=q[1]*s; p[2]=q[2]*s; } #define COMBO(combo,p,t,q) { combo[0]=p[0]+t*q[0]; combo[1]=p[1]+t*q[1]; combo[2]=p[2]+t*q[2]; } #define LENGTH(x) ((dReal) 1.0f/InvSqrt(dDOT(x, x))) #define DEPTH(d, p, q, n) d = (p[0] - q[0])*n[0] + (p[1] - q[1])*n[1] + (p[2] - q[2])*n[2]; inline const dReal dMin(const dReal x, const dReal y) { return x < y ? x : y; } 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 Len (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) 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> 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; } dContactGeom *AddContactToNode(const CONTACT_KEY * contactkey,CONTACT_KEY_HASH_NODE * node) { for(int i=0;im_keycount;i++) { if(node->m_keyarray[i].m_key == contactkey->m_key) { dContactGeom *contactfound = node->m_keyarray[i].m_contact; if (dDISTANCE(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; } 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); } } 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; } 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; } void ClearContactSet(CONTACT_KEY_HASH_TABLE &hashcontactset) { memset(&hashcontactset, 0, sizeof(CONTACT_KEY_HASH_TABLE)); } //return true if found dContactGeom *InsertContactInSet(CONTACT_KEY_HASH_TABLE &hashcontactset, const CONTACT_KEY &newkey) { unsigned int index = MakeContactIndex(newkey.m_key); return AddContactToNode(&newkey, &hashcontactset[index]); } void RemoveNewContactFromSet(CONTACT_KEY_HASH_TABLE &hashcontactset, const CONTACT_KEY &contactkey) { unsigned int index = MakeContactIndex(contactkey.m_key); RemoveNewContactFromNode(&contactkey, &hashcontactset[index]); } void RemoveArbitraryContactFromSet(CONTACT_KEY_HASH_TABLE &hashcontactset, const CONTACT_KEY &contactkey) { unsigned int index = MakeContactIndex(contactkey.m_key); RemoveArbitraryContactFromNode(&contactkey, &hashcontactset[index]); } 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); } 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; } 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; } 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)->TriMergeCallback ? ((dxTriMesh *)pcontact->g1)->TriMergeCallback((dxTriMesh *)pcontact->g1, pcontact->side1, TriIndex1) : -1; pcontact->side2 = ((dxTriMesh *)pcontact->g2)->TriMergeCallback ? ((dxTriMesh *)pcontact->g2)->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; } //////////////////////////////////////////////////////////////////////////////////////////// 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->_AABBTreeCollider; BVTCache &ColCache = pccColliderCache->ColCache; CONTACT_KEY_HASH_TABLE &hashcontactset = pccColliderCache->_hashcontactset; ColCache.Model0 = &TriMesh1->Data->BVTree; ColCache.Model1 = &TriMesh2->Data->BVTree; ////Prepare contact list ClearContactSet(hashcontactset); // Collision query Matrix4x4 amatrix, bmatrix; BOOL IsOk = Collider.Collide(ColCache, &MakeMatrix(TLPosition1, TLRotation1, amatrix), &MakeMatrix(TLPosition2, TLRotation2, 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]; // 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 FetchTriangle((dxTriMesh*) g1, id1, TLPosition1, TLRotation1, v1); FetchTriangle((dxTriMesh*) g2, id2, TLPosition2, TLRotation2, v2); // 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] 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 = dDOT(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 (dDOT(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 (dDOT(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&&i0) { 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;idist) vmin=dist; else if(vmaxmaxdeep) { 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;i0.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 separate out into limits and motors? // * make sure ODE-specific parameters divided out #include "ode/ode.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, 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= 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); } static void printAMotor (PrintingContext &c, dxJoint *j) { dxJointAMotor *a = (dxJointAMotor*) j; c.print ("num",a->num); c.print ("mode",a->mode); 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); c.print ("angle1",a->angle[0]); c.print ("angle2",a->angle[1]); c.print ("angle3",a->angle[2]); } //*************************************************************************** // 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 printGeomTransform (PrintingContext &c, dxGeom *g) { dxGeom *g2 = dGeomTransformGetGeom (g); const dReal *pos = dGeomGetPosition (g2); dQuaternion q; dGeomGetQuaternion (g2,q); c.print ("type","transform"); c.print ("pos",pos); c.print ("q",q,4); c.print ("geometry = {"); c.indent++; printGeom (c,g2); c.indent--; c.print ("}"); } 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 dGeomTransformClass: printGeomTransform (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++; } } ode-0.11.1/ode/src/collision_trimesh_sphere.cpp0000644000076400007640000004123311177261240016434 00000000000000/************************************************************************* * * * 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 #include #include #include #include "collision_util.h" #if dTRIMESH_ENABLED #include "collision_trimesh_internal.h" #if dTRIMESH_OPCODE #define MERGECONTACTS //#define MERGECONTACTNORMALS // 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 = dDOT(Edge0, Edge0); dReal A01 = dDOT(Edge0, Edge1); dReal A11 = dDOT(Edge1, Edge1); dReal B0 = dDOT(Diff, Edge0); dReal B1 = dDOT(Diff, Edge1); dReal C = dDOT(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; // Init const dVector3& TLPosition = *(const dVector3*)dGeomGetPosition(TriMesh); const dMatrix3& TLRotation = *(const dMatrix3*)dGeomGetRotation(TriMesh); const unsigned uiTLSKind = TriMesh->getParentSpaceTLSKind(); dIASSERT(uiTLSKind == SphereGeom->getParentSpaceTLSKind()); // The colliding spaces must use matching cleanup method TrimeshCollidersCache *pccColliderCache = GetTrimeshCollidersCache(uiTLSKind); SphereCollider& Collider = pccColliderCache->_SphereCollider; const dVector3& Position = *(const dVector3*)dGeomGetPosition(SphereGeom); dReal Radius = dGeomSphereGetRadius(SphereGeom); // Sphere Sphere Sphere; Sphere.mCenter.x = Position[0]; Sphere.mCenter.y = Position[1]; Sphere.mCenter.z = Position[2]; Sphere.mRadius = Radius; Matrix4x4 amatrix; // TC results if (TriMesh->doSphereTC) { dxTriMesh::SphereTC* sphereTC = 0; for (int i = 0; i < TriMesh->SphereTCCache.size(); i++){ if (TriMesh->SphereTCCache[i].Geom == SphereGeom){ sphereTC = &TriMesh->SphereTCCache[i]; break; } } if (!sphereTC){ TriMesh->SphereTCCache.push(dxTriMesh::SphereTC()); sphereTC = &TriMesh->SphereTCCache[TriMesh->SphereTCCache.size() - 1]; sphereTC->Geom = SphereGeom; } // Intersect Collider.SetTemporalCoherence(true); Collider.Collide(*sphereTC, Sphere, TriMesh->Data->BVTree, null, &MakeMatrix(TLPosition, TLRotation, amatrix)); } else { Collider.SetTemporalCoherence(false); Collider.Collide(pccColliderCache->defaultSphereCache, Sphere, TriMesh->Data->BVTree, null, &MakeMatrix(TLPosition, TLRotation, amatrix)); } 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->ArrayCallback != null){ TriMesh->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 (!Callback(TriMesh, SphereGeom, TriIndex)) continue; FetchTriangle(TriMesh, TriIndex, TLPosition, TLRotation, dv); 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; dCROSS(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 = dDOT(Plane,Position) - dDOT(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 = dDOT(dir, Plane) / dSqrt(dDOT(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 #if !defined MERGECONTACTS // Merge all contacts into 1 Contact->g1 = TriMesh; Contact->g2 = SphereGeom; Contact->side2 = -1; #endif // Otherwise assigned later Contact->side1 = TriIndex; OutTriCount++; } #if defined MERGECONTACTS // Merge all contacts into 1 if (OutTriCount > 0){ 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; 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->TriMergeCallback) ? TriMesh->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; // Remember to divide in square space. Contact->depth = dSqrt(dDOT(normal, normal) / OutTriCount); if (Contact->depth > dEpsilon) { // otherwise the normal is too small dVector3Copy(normal, Contact->normal); dNormalize3(Contact->normal); } // otherwise original Contact's normal would be used and it should be already normalized } return 1; } else return 0; #elif defined MERGECONTACTNORMALS // Merge all normals, and distribute between all contacts if (OutTriCount != 0){ 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 return 0; #else // none of MERGECONTACTS and MERGECONTACTNORMALS // Just return return OutTriCount; #endif // MERGECONTACTS } else return 0; } #endif // dTRIMESH_OPCODE #if dTRIMESH_GIMPACT 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; unsigned maxcontacts = (unsigned)(Flags & NUMC_MASK); if (contactcount > maxcontacts) { contactcount = maxcontacts; } dContactGeom* pcontact; unsigned i; for (i=0;ipos[0] = ptrimeshcontacts->m_point[0]; pcontact->pos[1] = ptrimeshcontacts->m_point[1]; pcontact->pos[2] = ptrimeshcontacts->m_point[2]; pcontact->pos[3] = REAL(1.0); pcontact->normal[0] = ptrimeshcontacts->m_normal[0]; pcontact->normal[1] = ptrimeshcontacts->m_normal[1]; pcontact->normal[2] = ptrimeshcontacts->m_normal[2]; pcontact->normal[3] = 0; pcontact->depth = ptrimeshcontacts->m_depth; pcontact->g1 = g1; pcontact->g2 = SphereGeom; pcontact->side1 = ptrimeshcontacts->m_feature1; pcontact->side2 = -1; ptrimeshcontacts++; } GIM_DYNARRAY_DESTROY(trimeshcontacts); return (int)contactcount; } #endif // dTRIMESH_GIMPACT #endif // dTRIMESH_ENABLED ode-0.11.1/ode/src/step.cpp0000644000076400007640000010011611042177700012305 00000000000000/************************************************************************* * * * 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 "objects.h" #include "joints/joint.h" #include #include "config.h" #include #include #include #include #include #include "lcp.h" #include "util.h" //**************************************************************************** // misc defines #define FAST_FACTOR //#define TIMING // memory allocation system #ifdef dUSE_MALLOC_FOR_ALLOCA unsigned int dMemoryFlag; #define REPORT_OUT_OF_MEMORY fprintf(stderr, "Insufficient memory to complete rigid body simulation. Results will not be accurate.\n") #define CHECK(p) \ if (!p) { \ dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; \ return; \ } #define ALLOCA(t,v,s) \ Auto v(malloc(s)); \ CHECK(v) #else // use alloca() #define ALLOCA(t,v,s) \ Auto v( dALLOCA16(s) ); #endif /* This template should work almost like std::auto_ptr */ template struct Auto { T *p; Auto(void * q) : p(reinterpret_cast(q)) { } ~Auto() { #ifdef dUSE_MALLOC_FOR_ALLOCA free(p); #endif } operator T*() { return p; } T& operator[] (int i) { return p[i]; } private: // intentionally undefined, don't use this template Auto& operator=(const Auto&) const; }; //**************************************************************************** // debugging - comparison of various vectors and matrices produced by the // slow and fast versions of the stepper. //#define COMPARE_METHODS #ifdef COMPARE_METHODS #include "testing.h" dMatrixComparison comparator; #endif // undef to use the fast decomposition #define DIRECT_CHOLESKY #undef REPORT_ERROR //**************************************************************************** // special matrix multipliers // this assumes the 4th and 8th rows of B and C are zero. static void Multiply2_p8r (dReal *A, dReal *B, dReal *C, int p, int r, int Askip) { int i,j; dReal sum,*bb,*cc; dIASSERT (p>0 && r>0 && A && B && C); bb = B; for (i=p; i; i--) { cc = C; for (j=r; j; j--) { sum = bb[0]*cc[0]; sum += bb[1]*cc[1]; sum += bb[2]*cc[2]; sum += bb[4]*cc[4]; sum += bb[5]*cc[5]; sum += bb[6]*cc[6]; *(A++) = sum; cc += 8; } A += Askip - r; bb += 8; } } // this assumes the 4th and 8th rows of B and C are zero. static void MultiplyAdd2_p8r (dReal *A, dReal *B, dReal *C, int p, int r, int Askip) { int i,j; dReal sum,*bb,*cc; dIASSERT (p>0 && r>0 && A && B && C); bb = B; for (i=p; i; i--) { cc = C; for (j=r; j; j--) { sum = bb[0]*cc[0]; sum += bb[1]*cc[1]; sum += bb[2]*cc[2]; sum += bb[4]*cc[4]; sum += bb[5]*cc[5]; sum += bb[6]*cc[6]; *(A++) += sum; cc += 8; } A += Askip - r; bb += 8; } } // this assumes the 4th and 8th rows of B are zero. static void Multiply0_p81 (dReal *A, dReal *B, dReal *C, int p) { int i; dIASSERT (p>0 && A && B && C); dReal sum; for (i=p; i; i--) { sum = B[0]*C[0]; sum += B[1]*C[1]; sum += B[2]*C[2]; sum += B[4]*C[4]; sum += B[5]*C[5]; sum += B[6]*C[6]; *(A++) = sum; B += 8; } } // this assumes the 4th and 8th rows of B are zero. static void MultiplyAdd0_p81 (dReal *A, dReal *B, dReal *C, int p) { int i; dIASSERT (p>0 && A && B && C); dReal sum; for (i=p; i; i--) { sum = B[0]*C[0]; sum += B[1]*C[1]; sum += B[2]*C[2]; sum += B[4]*C[4]; sum += B[5]*C[5]; sum += B[6]*C[6]; *(A++) += sum; B += 8; } } // this assumes the 4th and 8th rows of B are zero. static void MultiplyAdd1_8q1 (dReal *A, dReal *B, dReal *C, int q) { int k; dReal sum; dIASSERT (q>0 && A && B && C); sum = 0; for (k=0; k0 && A && B && C); sum = 0; for (k=0; ktag = i; // make a local copy of the joint array, because we might want to modify it. // (the "dxJoint *const*" declaration says we're allowed to modify the joints // but not the joint array, because the caller might need it unchanged). ALLOCA(dxJoint*,joint,nj*sizeof(dxJoint*)); memcpy (joint,_joint,nj * sizeof(dxJoint*)); // 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. // @@@ check computation of rotational force. ALLOCA(dReal,I,3*nb*4*sizeof(dReal)); ALLOCA(dReal,invI,3*nb*4*sizeof(dReal)); //dSetZero (I,3*nb*4); //dSetZero (invI,3*nb*4); for (i=0; imass.I,body[i]->posr.R); dMULTIPLY0_333 (I+i*12,body[i]->posr.R,tmp); // compute inverse inertia tensor in global frame dMULTIPLY2_333 (tmp,body[i]->invI,body[i]->posr.R); dMULTIPLY0_333 (invI+i*12,body[i]->posr.R,tmp); // compute rotational force dMULTIPLY0_331 (tmp,I+i*12,body[i]->avel); dCROSS (body[i]->tacc,-=,body[i]->avel,tmp); } // add the gravity force to all bodies for (i=0; iflags & dxBodyNoGravity)==0) { body[i]->facc[0] += body[i]->mass.mass * world->gravity[0]; body[i]->facc[1] += body[i]->mass.mass * world->gravity[1]; body[i]->facc[2] += body[i]->mass.mass * world->gravity[2]; } } // 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. // // joints with m=0 are inactive and are removed from the joints array // entirely, so that the code that follows does not consider them. int m = 0; ALLOCA(dxJoint::Info1,info,nj*sizeof(dxJoint::Info1)); ALLOCA(int,ofs,nj*sizeof(int)); for (i=0, j=0; jgetInfo1 (info+i); dIASSERT (info[i].m >= 0 && info[i].m <= 6 && info[i].nub >= 0 && info[i].nub <= info[i].m); if (info[i].m > 0) { joint[i] = joint[j]; i++; } } nj = i; // the purely unbounded constraints for (i=0; i 0 && info[i].nub < info[i].m) { ofs[i] = m; m += info[i].m; } // the purely LCP constraints for (i=0; iinvMass; MM[nskip+1] = body[i]->invMass; MM[2*nskip+2] = body[i]->invMass; MM += 3*nskip+3; for (j=0; j<3; j++) for (k=0; k<3; k++) { MM[j*nskip+k] = invI[i*12+j*4+k]; } } // assemble some body vectors: fe = external forces, v = velocities ALLOCA(dReal,fe,n6*sizeof(dReal)); ALLOCA(dReal,v,n6*sizeof(dReal)); //dSetZero (fe,n6); //dSetZero (v,n6); for (i=0; ifacc[j]; for (j=0; j<3; j++) fe[i*6+3+j] = body[i]->tacc[j]; for (j=0; j<3; j++) v[i*6+j] = body[i]->lvel[j]; for (j=0; j<3; j++) v[i*6+3+j] = body[i]->avel[j]; } // this will be set to the velocity update ALLOCA(dReal,vnew,n6*sizeof(dReal)); dSetZero (vnew,n6); // if there are constraints, compute cforce if (m > 0) { // 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. ALLOCA(dReal,c,m*sizeof(dReal)); ALLOCA(dReal,cfm,m*sizeof(dReal)); ALLOCA(dReal,lo,m*sizeof(dReal)); ALLOCA(dReal,hi,m*sizeof(dReal)); ALLOCA(int,findex,m*sizeof(int)); dSetZero (c,m); dSetValue (cfm,m,world->global_cfm); dSetValue (lo,m,-dInfinity); dSetValue (hi,m, dInfinity); for (i=0; iglobal_erp; for (i=0; inode[0].body->tag; Jinfo.J1a = Jinfo.J1l + 3; if (joint[i]->node[1].body) { Jinfo.J2l = J + nskip*ofs[i] + 6*joint[i]->node[1].body->tag; Jinfo.J2a = Jinfo.J2l + 3; } else { Jinfo.J2l = 0; Jinfo.J2a = 0; } Jinfo.c = c + ofs[i]; Jinfo.cfm = cfm + ofs[i]; Jinfo.lo = lo + ofs[i]; Jinfo.hi = hi + ofs[i]; Jinfo.findex = findex + ofs[i]; joint[i]->getInfo2 (&Jinfo); // adjust returned findex values for global index numbering for (j=0; j= 0) findex[ofs[i] + j] += ofs[i]; } } // compute A = J*invM*J' # ifdef TIMING dTimerNow ("compute A"); # endif ALLOCA(dReal,JinvM,m*nskip*sizeof(dReal)); //dSetZero (JinvM,m*nskip); dMultiply0 (JinvM,J,invM,m,n6,n6); int mskip = dPAD(m); ALLOCA(dReal,A,m*mskip*sizeof(dReal)); //dSetZero (A,m*mskip); dMultiply2 (A,JinvM,J,m,n6,m); // add cfm to the diagonal of A for (i=0; ilvel[j] = vnew[i*6+j]; for (j=0; j<3; j++) body[i]->avel[j] = vnew[i*6+3+j]; } // update the position and orientation from the new linear/angular velocity // (over the given timestep) #ifdef TIMING dTimerNow ("update position"); #endif for (i=0; ifacc[0] = 0; body[i]->facc[1] = 0; body[i]->facc[2] = 0; body[i]->facc[3] = 0; body[i]->tacc[0] = 0; body[i]->tacc[1] = 0; body[i]->tacc[2] = 0; body[i]->tacc[3] = 0; } #ifdef TIMING dTimerEnd(); if (m > 0) dTimerReport (stdout,1); #endif } //**************************************************************************** // an optimized version of dInternalStepIsland1() void dInternalStepIsland_x2 (dxWorld *world, dxBody * const *body, int nb, dxJoint * const *_joint, int nj, dReal stepsize) { int i,j,k; #ifdef TIMING dTimerStart("preprocessing"); #endif dReal stepsize1 = dRecip(stepsize); // number all bodies in the body list - set their tag values for (i=0; itag = i; // make a local copy of the joint array, because we might want to modify it. // (the "dxJoint *const*" declaration says we're allowed to modify the joints // but not the joint array, because the caller might need it unchanged). ALLOCA(dxJoint*,joint,nj*sizeof(dxJoint*)); memcpy (joint,_joint,nj * sizeof(dxJoint*)); // 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. invI are vertically stacked 3x4 matrices, one per body. // @@@ check computation of rotational force. ALLOCA(dReal,invI,3*nb*4*sizeof(dReal)); //dSetZero (I,3*nb*4); //dSetZero (invI,3*nb*4); for (i=0; iinvI,body[i]->posr.R); dMULTIPLY0_333 (invI+i*12,body[i]->posr.R,tmp); if (body[i]->flags & dxBodyGyroscopic) { dMatrix3 I; // compute inertia tensor in global frame dMULTIPLY2_333 (tmp,body[i]->mass.I,body[i]->posr.R); dMULTIPLY0_333 (I,body[i]->posr.R,tmp); // compute rotational force dMULTIPLY0_331 (tmp,I,body[i]->avel); dCROSS (body[i]->tacc,-=,body[i]->avel,tmp); } } // add the gravity force to all bodies for (i=0; iflags & dxBodyNoGravity)==0) { body[i]->facc[0] += body[i]->mass.mass * world->gravity[0]; body[i]->facc[1] += body[i]->mass.mass * world->gravity[1]; body[i]->facc[2] += body[i]->mass.mass * world->gravity[2]; } } // 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. int m = 0; ALLOCA(dxJoint::Info1,info,nj*sizeof(dxJoint::Info1)); ALLOCA(int,ofs,nj*sizeof(int)); for (i=0, j=0; jgetInfo1 (info+i); dIASSERT (info[i].m >= 0 && info[i].m <= 6 && info[i].nub >= 0 && info[i].nub <= info[i].m); if (info[i].m > 0) { joint[i] = joint[j]; joint[i]->tag = i; i++; } else { joint[j]->tag = -1; } } nj = i; // the purely unbounded constraints for (i=0; i 0 && info[i].nub < info[i].m) { ofs[i] = m; m += info[i].m; } // the purely LCP constraints for (i=0; i 0) { // 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. ALLOCA(dReal,c,m*sizeof(dReal)); ALLOCA(dReal,cfm,m*sizeof(dReal)); ALLOCA(dReal,lo,m*sizeof(dReal)); ALLOCA(dReal,hi,m*sizeof(dReal)); ALLOCA(int,findex,m*sizeof(int)); dSetZero (c,m); dSetValue (cfm,m,world->global_cfm); dSetValue (lo,m,-dInfinity); dSetValue (hi,m, dInfinity); for (i=0; iglobal_erp; for (i=0; igetInfo2 (&Jinfo); // adjust returned findex values for global index numbering for (j=0; j= 0) findex[ofs[i] + j] += ofs[i]; } } // 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. # ifdef TIMING dTimerNow ("compute A"); # endif ALLOCA(dReal,JinvM,2*m*8*sizeof(dReal)); dSetZero (JinvM,2*m*8); for (i=0; inode[0].body->tag; dReal body_invMass = body[b]->invMass; dReal *body_invI = invI + b*12; dReal *Jsrc = J + 2*8*ofs[i]; dReal *Jdst = JinvM + 2*8*ofs[i]; for (j=info[i].m-1; j>=0; j--) { for (k=0; k<3; k++) Jdst[k] = Jsrc[k] * body_invMass; dMULTIPLY0_133 (Jdst+4,Jsrc+4,body_invI); Jsrc += 8; Jdst += 8; } if (joint[i]->node[1].body) { b = joint[i]->node[1].body->tag; body_invMass = body[b]->invMass; body_invI = invI + b*12; for (j=info[i].m-1; j>=0; j--) { for (k=0; k<3; k++) Jdst[k] = Jsrc[k] * body_invMass; dMULTIPLY0_133 (Jdst+4,Jsrc+4,body_invI); Jsrc += 8; Jdst += 8; } } } // 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. this fact suggests // the algorithm used to fill A: // // for b = all bodies // n = number of joints attached to body b // for i = 1..n // for j = i+1..n // ii = actual joint number for i // jj = actual joint number for j // // (ii,jj) will be set to all pairs of joints around body b // compute blockwise: A(ii,jj) += JinvM(ii) * J(jj)' // // this algorithm catches all pairs of joints that have at least one body // in common. it does not compute the diagonal blocks of A however - // another similar algorithm does that. int mskip = dPAD(m); ALLOCA(dReal,A,m*mskip*sizeof(dReal)); dSetZero (A,m*mskip); for (i=0; ifirstjoint; n1; n1=n1->next) { for (dxJointNode *n2=n1->next; n2; n2=n2->next) { // get joint numbers and ensure ofs[j1] >= ofs[j2] int j1 = n1->joint->tag; int j2 = n2->joint->tag; if (ofs[j1] < ofs[j2]) { int tmp = j1; j1 = j2; j2 = tmp; } // if either joint was tagged as -1 then it is an inactive (m=0) // joint that should not be considered if (j1==-1 || j2==-1) continue; // determine if body i is the 1st or 2nd body of joints j1 and j2 int jb1 = (joint[j1]->node[1].body == body[i]); int jb2 = (joint[j2]->node[1].body == body[i]); // jb1/jb2 must be 0 for joints with only one body dIASSERT(joint[j1]->node[1].body || jb1==0); dIASSERT(joint[j2]->node[1].body || jb2==0); // set block of A MultiplyAdd2_p8r (A + ofs[j1]*mskip + ofs[j2], JinvM + 2*8*ofs[j1] + jb1*8*info[j1].m, J + 2*8*ofs[j2] + jb2*8*info[j2].m, info[j1].m,info[j2].m, mskip); } } } // compute diagonal blocks of A for (i=0; inode[1].body) { MultiplyAdd2_p8r (A + ofs[i]*(mskip+1), JinvM + 2*8*ofs[i] + 8*info[i].m, J + 2*8*ofs[i] + 8*info[i].m, info[i].m,info[i].m, mskip); } } // add cfm to the diagonal of A for (i=0; iinvMass; dReal *body_invI = invI + i*12; for (j=0; j<3; j++) tmp1[i*8+j] = body[i]->facc[j] * body_invMass + body[i]->lvel[j] * stepsize1; dMULTIPLY0_331 (tmp1 + i*8 + 4,body_invI,body[i]->tacc); for (j=0; j<3; j++) tmp1[i*8+4+j] += body[i]->avel[j] * stepsize1; } // put J*tmp1 into rhs ALLOCA(dReal,rhs,m*sizeof(dReal)); //dSetZero (rhs,m); for (i=0; inode[0].body->tag, info[i].m); if (joint[i]->node[1].body) { MultiplyAdd0_p81 (rhs+ofs[i],JJ + 8*info[i].m, tmp1 + 8*joint[i]->node[1].body->tag, info[i].m); } } // complete rhs for (i=0; inode[0].body; dxBody* b2 = joint[i]->node[1].body; dJointFeedback *fb = joint[i]->feedback; if (fb) { // the user has requested feedback on the amount of force that this // joint is applying to the bodies. we use a slightly slower // computation that splits out the force components and puts them // in the feedback structure. dReal data[8]; Multiply1_8q1 (data, JJ, lambda+ofs[i], info[i].m); dReal *cf1 = cforce + 8*b1->tag; cf1[0] += (fb->f1[0] = data[0]); cf1[1] += (fb->f1[1] = data[1]); cf1[2] += (fb->f1[2] = data[2]); cf1[4] += (fb->t1[0] = data[4]); cf1[5] += (fb->t1[1] = data[5]); cf1[6] += (fb->t1[2] = data[6]); if (b2){ Multiply1_8q1 (data, JJ + 8*info[i].m, lambda+ofs[i], info[i].m); dReal *cf2 = cforce + 8*b2->tag; cf2[0] += (fb->f2[0] = data[0]); cf2[1] += (fb->f2[1] = data[1]); cf2[2] += (fb->f2[2] = data[2]); cf2[4] += (fb->t2[0] = data[4]); cf2[5] += (fb->t2[1] = data[5]); cf2[6] += (fb->t2[2] = data[6]); } } else { // no feedback is required, let's compute cforce the faster way MultiplyAdd1_8q1 (cforce + 8*b1->tag,JJ, lambda+ofs[i], info[i].m); if (b2) { MultiplyAdd1_8q1 (cforce + 8*b2->tag, JJ + 8*info[i].m, lambda+ofs[i], info[i].m); } } } } // compute the velocity update #ifdef TIMING dTimerNow ("compute velocity update"); #endif // add fe to cforce for (i=0; ifacc[j]; for (j=0; j<3; j++) cforce[i*8+4+j] += body[i]->tacc[j]; } // multiply cforce by stepsize for (i=0; i < nb*8; i++) cforce[i] *= stepsize; // add invM * cforce to the body velocity for (i=0; iinvMass; dReal *body_invI = invI + i*12; for (j=0; j<3; j++) body[i]->lvel[j] += body_invMass * cforce[i*8+j]; dMULTIPLYADD0_331 (body[i]->avel,body_invI,cforce+i*8+4); } // update the position and orientation from the new linear/angular velocity // (over the given timestep) # ifdef TIMING dTimerNow ("update position"); # endif for (i=0; ilvel[j]; for (j=0; j<3; j++) tmp_vnew[i*6+3+j] = body[i]->avel[j]; } comparator.nextMatrix (tmp_vnew,nb*6,1,0,"vnew"); #endif #ifdef TIMING dTimerNow ("tidy up"); #endif // zero all force accumulators for (i=0; ifacc[0] = 0; body[i]->facc[1] = 0; body[i]->facc[2] = 0; body[i]->facc[3] = 0; body[i]->tacc[0] = 0; body[i]->tacc[1] = 0; body[i]->tacc[2] = 0; body[i]->tacc[3] = 0; } #ifdef TIMING dTimerEnd(); if (m > 0) dTimerReport (stdout,1); #endif } //**************************************************************************** void dInternalStepIsland (dxWorld *world, dxBody * const *body, int nb, dxJoint * const *joint, int nj, dReal stepsize) { #ifdef dUSE_MALLOC_FOR_ALLOCA dMemoryFlag = d_MEMORY_OK; #endif #ifndef COMPARE_METHODS dInternalStepIsland_x2 (world,body,nb,joint,nj,stepsize); #ifdef dUSE_MALLOC_FOR_ALLOCA if (dMemoryFlag == d_MEMORY_OUT_OF_MEMORY) { REPORT_OUT_OF_MEMORY; return; } #endif #endif #ifdef COMPARE_METHODS int i; // save body state ALLOCA(dxBody,state,nb*sizeof(dxBody)); for (i=0; i #include #include #include "collision_trimesh_internal.h" //------------------------------------------------------------------------------ /** @brief Finds the shortest distance squared between a point and a triangle. @param pfSParam Barycentric coordinate of triangle at point closest to p (u) @param pfTParam Barycentric coordinate of triangle at point closest to p (v) @return Shortest distance squared. The third Barycentric coordinate is implicit, ie. w = 1.0 - u - v Taken from: Magic Software, Inc. http://www.magic-software.com */ dReal SqrDistancePointTri( const dVector3 p, const dVector3 triOrigin, const dVector3 triEdge0, const dVector3 triEdge1, dReal* pfSParam, dReal* pfTParam ) { dVector3 kDiff; Vector3Subtract( triOrigin, p, kDiff ); dReal fA00 = dDOT( triEdge0, triEdge0 ); dReal fA01 = dDOT( triEdge0, triEdge1 ); dReal fA11 = dDOT( triEdge1, triEdge1 ); dReal fB0 = dDOT( kDiff, triEdge0 ); dReal fB1 = dDOT( kDiff, triEdge1 ); dReal fC = dDOT( kDiff, kDiff ); dReal fDet = dReal(fabs(fA00*fA11-fA01*fA01)); dReal fS = fA01*fB1-fA11*fB0; dReal fT = fA01*fB0-fA00*fB1; dReal fSqrDist; if ( fS + fT <= fDet ) { if ( fS < REAL(0.0) ) { if ( fT < REAL(0.0) ) // region 4 { if ( fB0 < REAL(0.0) ) { fT = REAL(0.0); if ( -fB0 >= fA00 ) { fS = REAL(1.0); fSqrDist = fA00+REAL(2.0)*fB0+fC; } else { fS = -fB0/fA00; fSqrDist = fB0*fS+fC; } } else { fS = REAL(0.0); if ( fB1 >= REAL(0.0) ) { fT = REAL(0.0); fSqrDist = fC; } else if ( -fB1 >= fA11 ) { fT = REAL(1.0); fSqrDist = fA11+REAL(2.0)*fB1+fC; } else { fT = -fB1/fA11; fSqrDist = fB1*fT+fC; } } } else // region 3 { fS = REAL(0.0); if ( fB1 >= REAL(0.0) ) { fT = REAL(0.0); fSqrDist = fC; } else if ( -fB1 >= fA11 ) { fT = REAL(1.0); fSqrDist = fA11+REAL(2.0)*fB1+fC; } else { fT = -fB1/fA11; fSqrDist = fB1*fT+fC; } } } else if ( fT < REAL(0.0) ) // region 5 { fT = REAL(0.0); if ( fB0 >= REAL(0.0) ) { fS = REAL(0.0); fSqrDist = fC; } else if ( -fB0 >= fA00 ) { fS = REAL(1.0); fSqrDist = fA00+REAL(2.0)*fB0+fC; } else { fS = -fB0/fA00; fSqrDist = fB0*fS+fC; } } else // region 0 { // minimum at interior point if ( fDet == REAL(0.0) ) { fS = REAL(0.0); fT = REAL(0.0); fSqrDist = dInfinity; } else { dReal fInvDet = REAL(1.0)/fDet; fS *= fInvDet; fT *= fInvDet; fSqrDist = fS*(fA00*fS+fA01*fT+REAL(2.0)*fB0) + fT*(fA01*fS+fA11*fT+REAL(2.0)*fB1)+fC; } } } else { dReal fTmp0, fTmp1, fNumer, fDenom; if ( fS < REAL(0.0) ) // region 2 { fTmp0 = fA01 + fB0; fTmp1 = fA11 + fB1; if ( fTmp1 > fTmp0 ) { fNumer = fTmp1 - fTmp0; fDenom = fA00-REAL(2.0)*fA01+fA11; if ( fNumer >= fDenom ) { fS = REAL(1.0); fT = REAL(0.0); fSqrDist = fA00+REAL(2.0)*fB0+fC; } else { fS = fNumer/fDenom; fT = REAL(1.0) - fS; fSqrDist = fS*(fA00*fS+fA01*fT+REAL(2.0)*fB0) + fT*(fA01*fS+fA11*fT+REAL(2.0)*fB1)+fC; } } else { fS = REAL(0.0); if ( fTmp1 <= REAL(0.0) ) { fT = REAL(1.0); fSqrDist = fA11+REAL(2.0)*fB1+fC; } else if ( fB1 >= REAL(0.0) ) { fT = REAL(0.0); fSqrDist = fC; } else { fT = -fB1/fA11; fSqrDist = fB1*fT+fC; } } } else if ( fT < REAL(0.0) ) // region 6 { fTmp0 = fA01 + fB1; fTmp1 = fA00 + fB0; if ( fTmp1 > fTmp0 ) { fNumer = fTmp1 - fTmp0; fDenom = fA00-REAL(2.0)*fA01+fA11; if ( fNumer >= fDenom ) { fT = REAL(1.0); fS = REAL(0.0); fSqrDist = fA11+REAL(2.0)*fB1+fC; } else { fT = fNumer/fDenom; fS = REAL(1.0) - fT; fSqrDist = fS*(fA00*fS+fA01*fT+REAL(2.0)*fB0) + fT*(fA01*fS+fA11*fT+REAL(2.0)*fB1)+fC; } } else { fT = REAL(0.0); if ( fTmp1 <= REAL(0.0) ) { fS = REAL(1.0); fSqrDist = fA00+REAL(2.0)*fB0+fC; } else if ( fB0 >= REAL(0.0) ) { fS = REAL(0.0); fSqrDist = fC; } else { fS = -fB0/fA00; fSqrDist = fB0*fS+fC; } } } else // region 1 { fNumer = fA11 + fB1 - fA01 - fB0; if ( fNumer <= REAL(0.0) ) { fS = REAL(0.0); fT = REAL(1.0); fSqrDist = fA11+REAL(2.0)*fB1+fC; } else { fDenom = fA00-REAL(2.0)*fA01+fA11; if ( fNumer >= fDenom ) { fS = REAL(1.0); fT = REAL(0.0); fSqrDist = fA00+REAL(2.0)*fB0+fC; } else { fS = fNumer/fDenom; fT = REAL(1.0) - fS; fSqrDist = fS*(fA00*fS+fA01*fT+REAL(2.0)*fB0) + fT*(fA01*fS+fA11*fT+REAL(2.0)*fB1)+fC; } } } } if ( pfSParam ) *pfSParam = (float)fS; if ( pfTParam ) *pfTParam = (float)fT; return dReal(fabs(fSqrDist)); } //------------------------------------------------------------------------------ /** @brief Finds the shortest distance squared between two line segments. @param pfSegP0 t value for seg1 where the shortest distance between the segments exists. @param pfSegP0 t value for seg2 where the shortest distance between the segments exists. @return Shortest distance squared. Taken from: Magic Software, Inc. http://www.magic-software.com */ dReal SqrDistanceSegments( const dVector3 seg1Origin, const dVector3 seg1Direction, const dVector3 seg2Origin, const dVector3 seg2Direction, dReal* pfSegP0, dReal* pfSegP1 ) { const dReal gs_fTolerance = 1e-05f; dVector3 kDiff, kNegDiff, seg1NegDirection; Vector3Subtract( seg1Origin, seg2Origin, kDiff ); Vector3Negate( kDiff, kNegDiff ); dReal fA00 = dDOT( seg1Direction, seg1Direction ); Vector3Negate( seg1Direction, seg1NegDirection ); dReal fA01 = dDOT( seg1NegDirection, seg2Direction ); dReal fA11 = dDOT( seg2Direction, seg2Direction ); dReal fB0 = dDOT( kDiff, seg1Direction ); dReal fC = dDOT( kDiff, kDiff ); dReal fDet = dReal(fabs(fA00*fA11-fA01*fA01)); dReal fB1, fS, fT, fSqrDist, fTmp; if ( fDet >= gs_fTolerance ) { // line segments are not parallel fB1 = dDOT( kNegDiff, seg2Direction ); fS = fA01*fB1-fA11*fB0; fT = fA01*fB0-fA00*fB1; if ( fS >= REAL(0.0) ) { if ( fS <= fDet ) { if ( fT >= REAL(0.0) ) { if ( fT <= fDet ) // region 0 (interior) { // minimum at two interior points of 3D lines dReal fInvDet = REAL(1.0)/fDet; fS *= fInvDet; fT *= fInvDet; fSqrDist = fS*(fA00*fS+fA01*fT+REAL(2.0)*fB0) + fT*(fA01*fS+fA11*fT+REAL(2.0)*fB1)+fC; } else // region 3 (side) { fT = REAL(1.0); fTmp = fA01+fB0; if ( fTmp >= REAL(0.0) ) { fS = REAL(0.0); fSqrDist = fA11+REAL(2.0)*fB1+fC; } else if ( -fTmp >= fA00 ) { fS = REAL(1.0); fSqrDist = fA00+fA11+fC+REAL(2.0)*(fB1+fTmp); } else { fS = -fTmp/fA00; fSqrDist = fTmp*fS+fA11+REAL(2.0)*fB1+fC; } } } else // region 7 (side) { fT = REAL(0.0); if ( fB0 >= REAL(0.0) ) { fS = REAL(0.0); fSqrDist = fC; } else if ( -fB0 >= fA00 ) { fS = REAL(1.0); fSqrDist = fA00+REAL(2.0)*fB0+fC; } else { fS = -fB0/fA00; fSqrDist = fB0*fS+fC; } } } else { if ( fT >= REAL(0.0) ) { if ( fT <= fDet ) // region 1 (side) { fS = REAL(1.0); fTmp = fA01+fB1; if ( fTmp >= REAL(0.0) ) { fT = REAL(0.0); fSqrDist = fA00+REAL(2.0)*fB0+fC; } else if ( -fTmp >= fA11 ) { fT = REAL(1.0); fSqrDist = fA00+fA11+fC+REAL(2.0)*(fB0+fTmp); } else { fT = -fTmp/fA11; fSqrDist = fTmp*fT+fA00+REAL(2.0)*fB0+fC; } } else // region 2 (corner) { fTmp = fA01+fB0; if ( -fTmp <= fA00 ) { fT = REAL(1.0); if ( fTmp >= REAL(0.0) ) { fS = REAL(0.0); fSqrDist = fA11+REAL(2.0)*fB1+fC; } else { fS = -fTmp/fA00; fSqrDist = fTmp*fS+fA11+REAL(2.0)*fB1+fC; } } else { fS = REAL(1.0); fTmp = fA01+fB1; if ( fTmp >= REAL(0.0) ) { fT = REAL(0.0); fSqrDist = fA00+REAL(2.0)*fB0+fC; } else if ( -fTmp >= fA11 ) { fT = REAL(1.0); fSqrDist = fA00+fA11+fC+REAL(2.0)*(fB0+fTmp); } else { fT = -fTmp/fA11; fSqrDist = fTmp*fT+fA00+REAL(2.0)*fB0+fC; } } } } else // region 8 (corner) { if ( -fB0 < fA00 ) { fT = REAL(0.0); if ( fB0 >= REAL(0.0) ) { fS = REAL(0.0); fSqrDist = fC; } else { fS = -fB0/fA00; fSqrDist = fB0*fS+fC; } } else { fS = REAL(1.0); fTmp = fA01+fB1; if ( fTmp >= REAL(0.0) ) { fT = REAL(0.0); fSqrDist = fA00+REAL(2.0)*fB0+fC; } else if ( -fTmp >= fA11 ) { fT = REAL(1.0); fSqrDist = fA00+fA11+fC+REAL(2.0)*(fB0+fTmp); } else { fT = -fTmp/fA11; fSqrDist = fTmp*fT+fA00+REAL(2.0)*fB0+fC; } } } } } else { if ( fT >= REAL(0.0) ) { if ( fT <= fDet ) // region 5 (side) { fS = REAL(0.0); if ( fB1 >= REAL(0.0) ) { fT = REAL(0.0); fSqrDist = fC; } else if ( -fB1 >= fA11 ) { fT = REAL(1.0); fSqrDist = fA11+REAL(2.0)*fB1+fC; } else { fT = -fB1/fA11; fSqrDist = fB1*fT+fC; } } else // region 4 (corner) { fTmp = fA01+fB0; if ( fTmp < REAL(0.0) ) { fT = REAL(1.0); if ( -fTmp >= fA00 ) { fS = REAL(1.0); fSqrDist = fA00+fA11+fC+REAL(2.0)*(fB1+fTmp); } else { fS = -fTmp/fA00; fSqrDist = fTmp*fS+fA11+REAL(2.0)*fB1+fC; } } else { fS = REAL(0.0); if ( fB1 >= REAL(0.0) ) { fT = REAL(0.0); fSqrDist = fC; } else if ( -fB1 >= fA11 ) { fT = REAL(1.0); fSqrDist = fA11+REAL(2.0)*fB1+fC; } else { fT = -fB1/fA11; fSqrDist = fB1*fT+fC; } } } } else // region 6 (corner) { if ( fB0 < REAL(0.0) ) { fT = REAL(0.0); if ( -fB0 >= fA00 ) { fS = REAL(1.0); fSqrDist = fA00+REAL(2.0)*fB0+fC; } else { fS = -fB0/fA00; fSqrDist = fB0*fS+fC; } } else { fS = REAL(0.0); if ( fB1 >= REAL(0.0) ) { fT = REAL(0.0); fSqrDist = fC; } else if ( -fB1 >= fA11 ) { fT = REAL(1.0); fSqrDist = fA11+REAL(2.0)*fB1+fC; } else { fT = -fB1/fA11; fSqrDist = fB1*fT+fC; } } } } } else { // line segments are parallel if ( fA01 > REAL(0.0) ) { // direction vectors form an obtuse angle if ( fB0 >= REAL(0.0) ) { fS = REAL(0.0); fT = REAL(0.0); fSqrDist = fC; } else if ( -fB0 <= fA00 ) { fS = -fB0/fA00; fT = REAL(0.0); fSqrDist = fB0*fS+fC; } else { //fB1 = -kDiff % seg2.m; fB1 = dDOT( kNegDiff, seg2Direction ); fS = REAL(1.0); fTmp = fA00+fB0; if ( -fTmp >= fA01 ) { fT = REAL(1.0); fSqrDist = fA00+fA11+fC+REAL(2.0)*(fA01+fB0+fB1); } else { fT = -fTmp/fA01; fSqrDist = fA00+REAL(2.0)*fB0+fC+fT*(fA11*fT+REAL(2.0)*(fA01+fB1)); } } } else { // direction vectors form an acute angle if ( -fB0 >= fA00 ) { fS = REAL(1.0); fT = REAL(0.0); fSqrDist = fA00+REAL(2.0)*fB0+fC; } else if ( fB0 <= REAL(0.0) ) { fS = -fB0/fA00; fT = REAL(0.0); fSqrDist = fB0*fS+fC; } else { fB1 = dDOT( kNegDiff, seg2Direction ); fS = REAL(0.0); if ( fB0 >= -fA01 ) { fT = REAL(1.0); fSqrDist = fA11+REAL(2.0)*fB1+fC; } else { fT = -fB0/fA01; fSqrDist = fC+fT*(REAL(2.0)*fB1+fA11*fT); } } } } if ( pfSegP0 ) *pfSegP0 = fS; if ( pfSegP1 ) *pfSegP1 = fT; return dReal(fabs(fSqrDist)); } //------------------------------------------------------------------------------ /** @brief Finds the shortest distance squared between a line segment and a triangle. @param pfSegP t value for the line segment where the shortest distance between the segment and the triangle occurs. So the point along the segment that is the shortest distance away from the triangle can be obtained by (seg.end - seg.start) * t. @param pfTriP0 Barycentric coordinate of triangle at point closest to seg (u) @param pfTriP1 Barycentric coordinate of triangle at point closest to seg (v) @return Shortest distance squared. The third Barycentric coordinate is implicit, ie. w = 1.0 - u - v Taken from: Magic Software, Inc. http://www.magic-software.com */ dReal SqrDistanceSegTri( const dVector3 segOrigin, const dVector3 segEnd, const dVector3 triOrigin, const dVector3 triEdge0, const dVector3 triEdge1, dReal* pfSegP, dReal* pfTriP0, dReal* pfTriP1 ) { const dReal gs_fTolerance = 1e-06f; dVector3 segDirection, segNegDirection, kDiff, kNegDiff; Vector3Subtract( segEnd, segOrigin, segDirection ); Vector3Negate( segDirection, segNegDirection ); Vector3Subtract( triOrigin, segOrigin, kDiff ); Vector3Negate( kDiff, kNegDiff ); dReal fA00 = dDOT( segDirection, segDirection ); dReal fA01 = dDOT( segNegDirection, triEdge0 ); dReal fA02 = dDOT( segNegDirection, triEdge1 ); dReal fA11 = dDOT( triEdge0, triEdge0 ); dReal fA12 = dDOT( triEdge0, triEdge1 ); dReal fA22 = dDOT( triEdge1, triEdge1 ); dReal fB0 = dDOT( kNegDiff, segDirection ); dReal fB1 = dDOT( kDiff, triEdge0 ); dReal fB2 = dDOT( kDiff, triEdge1 ); dVector3 kTriSegOrigin, kTriSegDirection, kPt; dReal fSqrDist, fSqrDist0, fR, fS, fT, fR0, fS0, fT0; // Set up for a relative error test on the angle between ray direction // and triangle normal to determine parallel/nonparallel status. dVector3 kN; dCROSS( kN, =, triEdge0, triEdge1 ); dReal fNSqrLen = dDOT( kN, kN ); dReal fDot = dDOT( segDirection, kN ); bool bNotParallel = (fDot*fDot >= gs_fTolerance*fA00*fNSqrLen); if ( bNotParallel ) { dReal fCof00 = fA11*fA22-fA12*fA12; dReal fCof01 = fA02*fA12-fA01*fA22; dReal fCof02 = fA01*fA12-fA02*fA11; dReal fCof11 = fA00*fA22-fA02*fA02; dReal fCof12 = fA02*fA01-fA00*fA12; dReal fCof22 = fA00*fA11-fA01*fA01; dReal fInvDet = REAL(1.0)/(fA00*fCof00+fA01*fCof01+fA02*fCof02); dReal fRhs0 = -fB0*fInvDet; dReal fRhs1 = -fB1*fInvDet; dReal fRhs2 = -fB2*fInvDet; fR = fCof00*fRhs0+fCof01*fRhs1+fCof02*fRhs2; fS = fCof01*fRhs0+fCof11*fRhs1+fCof12*fRhs2; fT = fCof02*fRhs0+fCof12*fRhs1+fCof22*fRhs2; if ( fR < REAL(0.0) ) { if ( fS+fT <= REAL(1.0) ) { if ( fS < REAL(0.0) ) { if ( fT < REAL(0.0) ) // region 4m { // min on face s=0 or t=0 or r=0 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge1, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fT ); fS = REAL(0.0); Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge0, kTriSegDirection ); fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR0, &fS0 ); fT0 = REAL(0.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } fSqrDist0 = SqrDistancePointTri( segOrigin, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(0.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } else // region 3m { // min on face s=0 or r=0 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge1, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR,&fT ); fS = REAL(0.0); fSqrDist0 = SqrDistancePointTri( segOrigin, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(0.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } } else if ( fT < REAL(0.0) ) // region 5m { // min on face t=0 or r=0 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge0, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fS ); fT = REAL(0.0); fSqrDist0 = SqrDistancePointTri( segOrigin, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(0.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } else // region 0m { // min on face r=0 fSqrDist = SqrDistancePointTri( segOrigin, triOrigin, triEdge0, triEdge1, &fS, &fT ); fR = REAL(0.0); } } else { if ( fS < REAL(0.0) ) // region 2m { // min on face s=0 or s+t=1 or r=0 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge1, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fT ); fS = REAL(0.0); Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR0, &fT0 ); fS0 = REAL(1.0) - fT0; if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } fSqrDist0 = SqrDistancePointTri( segOrigin, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(0.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } else if ( fT < REAL(0.0) ) // region 6m { // min on face t=0 or s+t=1 or r=0 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge0, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fS ); fT = REAL(0.0); Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR0, &fT0 ); fS0 = REAL(1.0) - fT0; if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } fSqrDist0 = SqrDistancePointTri( segOrigin, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(0.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } else // region 1m { // min on face s+t=1 or r=0 Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fT ); fS = REAL(1.0) - fT; fSqrDist0 = SqrDistancePointTri( segOrigin, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(0.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } } } else if ( fR <= REAL(1.0) ) { if ( fS+fT <= REAL(1.0) ) { if ( fS < REAL(0.0) ) { if ( fT < REAL(0.0) ) // region 4 { // min on face s=0 or t=0 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge1, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fT ); fS = REAL(0.0); Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge0, kTriSegDirection ); fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR0, &fS0 ); fT0 = REAL(0.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } else // region 3 { // min on face s=0 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge1, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fT ); fS = REAL(0.0); } } else if ( fT < REAL(0.0) ) // region 5 { // min on face t=0 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge0, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fS ); fT = REAL(0.0); } else // region 0 { // global minimum is interior, done fSqrDist = REAL(0.0); } } else { if ( fS < REAL(0.0) ) // region 2 { // min on face s=0 or s+t=1 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge1, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fT ); fS = REAL(0.0); Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR0, &fT0 ); fS0 = REAL(1.0) - fT0; if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } else if ( fT < REAL(0.0) ) // region 6 { // min on face t=0 or s+t=1 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge0, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fS ); fT = REAL(0.0); Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR0, &fT0 ); fS0 = REAL(1.0) - fT0; if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } else // region 1 { // min on face s+t=1 Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fT ); fS = REAL(1.0) - fT; } } } else // fR > 1 { if ( fS+fT <= REAL(1.0) ) { if ( fS < REAL(0.0) ) { if ( fT < REAL(0.0) ) // region 4p { // min on face s=0 or t=0 or r=1 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge1, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fT ); fS = REAL(0.0); Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge0, kTriSegDirection ); fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR0, &fS0 ); fT0 = REAL(0.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } Vector3Add( segOrigin, segDirection, kPt ); fSqrDist0 = SqrDistancePointTri( kPt, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(1.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } else // region 3p { // min on face s=0 or r=1 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge1, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fT ); fS = REAL(0.0); Vector3Add( segOrigin, segDirection, kPt ); fSqrDist0 = SqrDistancePointTri( kPt, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(1.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } } else if ( fT < REAL(0.0) ) // region 5p { // min on face t=0 or r=1 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge0, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fS ); fT = REAL(0.0); Vector3Add( segOrigin, segDirection, kPt ); fSqrDist0 = SqrDistancePointTri( kPt, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(1.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } else // region 0p { // min face on r=1 Vector3Add( segOrigin, segDirection, kPt ); fSqrDist = SqrDistancePointTri( kPt, triOrigin, triEdge0, triEdge1, &fS, &fT ); fR = REAL(1.0); } } else { if ( fS < REAL(0.0) ) // region 2p { // min on face s=0 or s+t=1 or r=1 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge1, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fT ); fS = REAL(0.0); Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR0, &fT0 ); fS0 = REAL(1.0) - fT0; if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } Vector3Add( segOrigin, segDirection, kPt ); fSqrDist0 = SqrDistancePointTri( kPt, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(1.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } else if ( fT < REAL(0.0) ) // region 6p { // min on face t=0 or s+t=1 or r=1 Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge0, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fS ); fT = REAL(0.0); Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR0, &fT0 ); fS0 = REAL(1.0) - fT0; if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } Vector3Add( segOrigin, segDirection, kPt ); fSqrDist0 = SqrDistancePointTri( kPt, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(1.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } else // region 1p { // min on face s+t=1 or r=1 Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fT ); fS = REAL(1.0) - fT; Vector3Add( segOrigin, segDirection, kPt ); fSqrDist0 = SqrDistancePointTri( kPt, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(1.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } } } } else { // segment and triangle are parallel Vector3Copy( triOrigin, kTriSegOrigin ); Vector3Copy( triEdge0, kTriSegDirection ); fSqrDist = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR, &fS ); fT = REAL(0.0); Vector3Copy( triEdge1, kTriSegDirection ); fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR0, &fT0 ); fS0 = REAL(0.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } Vector3Add( triOrigin, triEdge0, kTriSegOrigin ); Vector3Subtract( triEdge1, triEdge0, kTriSegDirection ); fSqrDist0 = SqrDistanceSegments( segOrigin, segDirection, kTriSegOrigin, kTriSegDirection, &fR0, &fT0 ); fS0 = REAL(1.0) - fT0; if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } fSqrDist0 = SqrDistancePointTri( segOrigin, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(0.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } Vector3Add( segOrigin, segDirection, kPt ); fSqrDist0 = SqrDistancePointTri( kPt, triOrigin, triEdge0, triEdge1, &fS0, &fT0 ); fR0 = REAL(1.0); if ( fSqrDist0 < fSqrDist ) { fSqrDist = fSqrDist0; fR = fR0; fS = fS0; fT = fT0; } } if ( pfSegP ) *pfSegP = fR; if ( pfTriP0 ) *pfTriP0 = fS; if ( pfTriP1 ) *pfTriP1 = fT; return fSqrDist; } ode-0.11.1/ode/src/collision_cylinder_plane.cpp0000644000076400007640000001762211142520432016401 00000000000000/************************************************************************* * * * 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 #include #include #include #include #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; } ode-0.11.1/ode/src/cylinder.cpp0000644000076400007640000000715411142520432013146 00000000000000/************************************************************************* * * * 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 #include #include #include #include #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 // 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 xrange = dFabs (R[0] * radius) + dFabs (R[1] * radius) + REAL(0.5)* dFabs (R[2] * lz); dReal yrange = dFabs (R[4] * radius) + dFabs (R[5] * radius) + REAL(0.5)* dFabs (R[6] * lz); dReal zrange = dFabs (R[8] * radius) + dFabs (R[9] * radius) + REAL(0.5)* dFabs (R[10] * lz); 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; } ode-0.11.1/ode/src/fastdot.c0000644000076400007640000000067507270126173012455 00000000000000/* generated code, do not edit. */ #include "ode/matrix.h" dReal dDot (const dReal *a, const dReal *b, int n) { dReal p0,q0,m0,p1,q1,m1,sum; sum = 0; n -= 2; while (n >= 0) { p0 = a[0]; q0 = b[0]; m0 = p0 * q0; p1 = a[1]; q1 = b[1]; m1 = p1 * q1; sum += m0; sum += m1; a += 2; b += 2; n -= 2; } n += 2; while (n > 0) { sum += (*a) * (*b); a++; b++; n--; } return sum; } ode-0.11.1/ode/src/util.h0000644000076400007640000000566011102036010011745 00000000000000/************************************************************************* * * * 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" /* 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 /* utility */ /* round something up to be a multiple of the EFFICIENT_ALIGNMENT */ #define dEFFICIENT_SIZE(x) ((((x)-1)|(EFFICIENT_ALIGNMENT-1))+1) /* 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) \ ((char*)dEFFICIENT_SIZE(((size_t)(alloca((n)+(EFFICIENT_ALIGNMENT-1)))))) void dInternalHandleAutoDisabling (dxWorld *world, dReal stepsize); void dxStepBody (dxBody *b, dReal h); typedef void (*dstepper_fn_t) (dxWorld *world, dxBody * const *body, int nb, dxJoint * const *_joint, int nj, dReal stepsize); void dxProcessIslands (dxWorld *world, dReal stepsize, dstepper_fn_t stepper); #endif ode-0.11.1/ode/src/collision_kernel.cpp0000644000076400007640000007024511156775756014723 00000000000000/************************************************************************* * * * 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 #include #include #include #include #include "config.h" #include "collision_kernel.h" #include "collision_util.h" #include "collision_std.h" #include "collision_transform.h" #include "collision_trimesh_internal.h" #include "odeou.h" #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 Convex Collision setCollider (dConvexClass,dPlaneClass,&dCollideConvexPlane); setCollider (dSphereClass,dConvexClass,&dCollideSphereConvex); setCollider (dConvexClass,dBoxClass,&dCollideConvexBox); setCollider (dConvexClass,dCapsuleClass,&dCollideConvexCapsule); setCollider (dConvexClass,dConvexClass,&dCollideConvexConvex); 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; inormal[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; 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 *o, dReal aabb[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); } //**************************************************************************** // misc dxGeom *dGeomGetBodyNext (dxGeom *geom) { return geom->body_next; } //**************************************************************************** // public API for geometry objects #define CHECK_NOT_LOCKED(space) \ dUASSERT (!(space && space->lock_count), \ "invalid operation for geom in locked space"); 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"); g->recomputePosr(); return g->final_posr->pos; } void dGeomCopyPosition(dxGeom *g, dVector3 pos) { dAASSERT (g); dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); g->recomputePosr(); const dReal* src = g->final_posr->pos; pos[0] = src[0]; pos[1] = src[1]; pos[2] = src[2]; } const dReal * dGeomGetRotation (dxGeom *g) { dAASSERT (g); dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); g->recomputePosr(); return g->final_posr->R; } void dGeomCopyRotation(dxGeom *g, dMatrix3 R) { dAASSERT (g); dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable"); g->recomputePosr(); const dReal* src = g->final_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]; } 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; } //**************************************************************************** // 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->final_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; } } ode-0.11.1/ode/src/matrix.cpp0000644000076400007640000002214511011472041012633 00000000000000/************************************************************************* * * * 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 #include #include "util.h" #include "config.h" // misc defines #define ALLOCA dALLOCA16 void dSetZero (dReal *a, int n) { dAASSERT (a && n >= 0); while (n > 0) { *(a++) = 0; n--; } } void dSetValue (dReal *a, int n, dReal value) { dAASSERT (a && n >= 0); while (n > 0) { *(a++) = value; n--; } } void dMultiply0 (dReal *A, const dReal *B, const dReal *C, int p, int q, int r) { int i,j,k,qskip,rskip,rpad; dAASSERT (A && B && C && p>0 && q>0 && r>0); qskip = dPAD(q); rskip = dPAD(r); rpad = rskip - r; dReal sum; const dReal *b,*c,*bb; bb = B; for (i=p; i; i--) { for (j=0 ; j0 && q>0 && r>0); pskip = dPAD(p); rskip = dPAD(r); for (i=0; i0 && q>0 && r>0); rpad = dPAD(r) - r; qskip = dPAD(q); bb = B; for (i=p; i; i--) { cc = C; for (j=r; j; j--) { z = 0; sum = 0; for (k=q; k; k--,z++) sum += bb[z] * cc[z]; *(A++) = sum; cc += qskip; } A += rpad; bb += qskip; } } int dFactorCholesky (dReal *A, int n) { int i,j,k,nskip; dReal sum,*a,*b,*aa,*bb,*cc,*recip; dAASSERT (n > 0 && A); nskip = dPAD (n); recip = (dReal*) ALLOCA (n * sizeof(dReal)); aa = A; for (i=0; i 0 && L && b); nskip = dPAD (n); y = (dReal*) ALLOCA (n*sizeof(dReal)); for (i=0; i= 0; i--) { sum = 0; for (k=i+1; k < n; k++) sum += L[k*nskip+i]*b[k]; b[i] = (y[i]-sum)/L[i*nskip+i]; } } int dInvertPDMatrix (const dReal *A, dReal *Ainv, int n) { int i,j,nskip; dReal *L,*x; dAASSERT (n > 0 && A && Ainv); nskip = dPAD (n); L = (dReal*) ALLOCA (nskip*n*sizeof(dReal)); memcpy (L,A,nskip*n*sizeof(dReal)); x = (dReal*) ALLOCA (n*sizeof(dReal)); if (dFactorCholesky (L,n)==0) return 0; dSetZero (Ainv,n*nskip); // make sure all padding elements set to 0 for (i=0; i 0 && A); int nskip = dPAD (n); Acopy = (dReal*) ALLOCA (nskip*n * sizeof(dReal)); memcpy (Acopy,A,nskip*n * sizeof(dReal)); return dFactorCholesky (Acopy,n); } /***** this has been replaced by a faster version void dSolveL1T (const dReal *L, dReal *b, int n, int nskip) { int i,j; dAASSERT (L && b && n >= 0 && nskip >= n); dReal sum; for (i=n-2; i>=0; i--) { sum = 0; for (j=i+1; j= 0); for (int i=0; i 0 && nskip >= n); dSolveL1 (L,b,n,nskip); dVectorScale (b,d,n); dSolveL1T (L,b,n,nskip); } void dLDLTAddTL (dReal *L, dReal *d, const dReal *a, int n, int nskip) { int j,p; dReal *W1,*W2,W11,W21,alpha1,alpha2,alphanew,gamma1,gamma2,k1,k2,Wp,ell,dee; dAASSERT (L && d && a && n > 0 && nskip >= n); if (n < 2) return; W1 = (dReal*) ALLOCA (n*sizeof(dReal)); W2 = (dReal*) ALLOCA (n*sizeof(dReal)); W1[0] = 0; W2[0] = 0; for (j=1; j j) ? _GETA(i,j) : _GETA(j,i)) void dLDLTRemove (dReal **A, const int *p, dReal *L, dReal *d, int n1, int n2, int r, int nskip) { int i; dAASSERT(A && p && L && d && n1 > 0 && n2 > 0 && r >= 0 && r < n2 && n1 >= n2 && nskip >= n1); #ifndef dNODEBUG for (i=0; i= 0 && p[i] < n1); #endif if (r==n2-1) { return; // deleting last row/col is easy } else if (r==0) { dReal *a = (dReal*) ALLOCA (n2 * sizeof(dReal)); for (i=0; i 0 && nskip >= n && r >= 0 && r < n); if (r >= n-1) return; if (r > 0) { for (i=0; i #include #include #include #include "util.h" #include "collision_kernel.h" #include "collision_space_internal.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) { CHECK_NOT_LOCKED (parent); geom->gflags |= GEOM_DIRTY | GEOM_AABB_BAD; 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->gflags |= GEOM_DIRTY | GEOM_AABB_BAD; CHECK_NOT_LOCKED (geom->parent_space); 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; jnext; 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; // new geoms are added to the front of the list and are always // considered to be dirty. as a consequence, this space and all its // parents are dirty too. geom->gflags |= GEOM_DIRTY | GEOM_AABB_BAD; 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(); g->gflags &= (~(GEOM_DIRTY|GEOM_AABB_BAD)); } 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 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 { dxAABB *next; // next in the list of all AABBs 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) int 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 getVirtualAddress (int level, int x, int y, int z) { return level*1000 + x*100 + y*10 + z; } //**************************************************************************** // 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(); g->gflags &= (~(GEOM_DIRTY|GEOM_AABB_BAD)); } lock_count--; } void dxHashSpace::collide (void *data, dNearCallback *callback) { dAASSERT(this && callback); dxGeom *geom; dxAABB *aabb; 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. int n = 0; // number of AABBs in main list dxAABB *first_aabb = 0; // list of AABBs in hash table dxAABB *big_boxes = 0; // 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 = (dxAABB*) ALLOCA (sizeof(dxAABB)); 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 goes in main list aabb->next = first_aabb; first_aabb = aabb; aabb->level = level; if (level > maxlevel) maxlevel = level; // cellsize = 2^level dReal cellsize = (dReal) ldexp (1.0,level); // discretize AABB position to cell size for (i=0; i < 6; i++) aabb->dbounds[i] = (int) floor (geom->aabb[i]/cellsize); // set AABB index aabb->index = n; n++; } else { // aabb is too big, put it in the big_boxes list. we don't care about // setting level, dbounds, index, or the maxlevel aabb->next = big_boxes; big_boxes = aabb; } } // 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 unsigned char *tested = (unsigned char *) ALLOCA (n * tested_rowsize); memset (tested,0,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= (8*n)) break; } if (i >= NUM_PRIMES) i = NUM_PRIMES-1; // probably pointless int sz = prime[i]; // allocate and initialize hash table node pointers Node **table = (Node **) ALLOCA (sizeof(Node*) * sz); for (i=0; inext) { int *dbounds = aabb->dbounds; for (int xi = dbounds[0]; xi <= dbounds[1]; xi++) { for (int yi = dbounds[2]; yi <= dbounds[3]; yi++) { for (int zi = dbounds[4]; zi <= dbounds[5]; zi++) { // get the hash index unsigned long hi = getVirtualAddress (aabb->level,xi,yi,zi) % sz; // add a new node to the hash table Node *node = (Node*) ALLOCA (sizeof (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 (aabb=first_aabb; aabb; aabb=aabb->next) { // we are searching for collisions with aabb for (i=0; i<6; i++) db[i] = aabb->dbounds[i]; for (int level = aabb->level; level <= maxlevel; level++) { for (int xi = db[0]; xi <= db[1]; xi++) { for (int yi = db[2]; yi <= db[3]; yi++) { for (int zi = db[4]; zi <= db[5]; zi++) { // get the hash index unsigned long hi = getVirtualAddress (level,xi,yi,zi) % sz; // search all nodes at this index Node *node; for (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 && i < (tested_rowsize*n)); if ((tested[i] & mask)==0) { collideAABBs (aabb->geom,node->aabb->geom,data,callback); } tested[i] |= mask; } } } } } // 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. for (aabb=first_aabb; aabb; aabb=aabb->next) { for (dxAABB *aabb2=big_boxes; aabb2; aabb2=aabb2->next) { collideAABBs (aabb->geom,aabb2->geom,data,callback); } } // intersected all AABBs in the big_boxes list together for (aabb=big_boxes; aabb; aabb=aabb->next) { for (dxAABB *aabb2=aabb->next; aabb2; aabb2=aabb2->next) { collideAABBs (aabb->geom,aabb2->geom,data,callback); } } 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); } } } ode-0.11.1/ode/src/rotation.cpp0000644000076400007640000002062510471024761013202 00000000000000/************************************************************************* * * * 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 #include #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]); } ode-0.11.1/ode/src/collision_trimesh_internal.h0000644000076400007640000004454611206274560016443 00000000000000/************************************************************************* * * * 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 #ifndef _ODE_COLLISION_TRIMESH_INTERNAL_H_ #define _ODE_COLLISION_TRIMESH_INTERNAL_H_ //**************************************************************************** // dxTriMesh class #include "collision_kernel.h" #include "collision_trimesh_colliders.h" #include #if dTRIMESH_OPCODE #define BAN_OPCODE_AUTOLINK #include "Opcode.h" using namespace Opcode; #endif // dTRIMESH_OPCODE #if dTRIMESH_GIMPACT #include #endif #if dTLS_ENABLED #include "odetls.h" #endif #if dTRIMESH_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 #endif // dTRIMESH_OPCODE struct TrimeshCollidersCache { TrimeshCollidersCache() { #if dTRIMESH_OPCODE InitOPCODECaches(); #endif // dTRIMESH_OPCODE } #if dTRIMESH_OPCODE void InitOPCODECaches(); // Collider caches BVTCache ColCache; #if !dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER CONTACT_KEY_HASH_TABLE _hashcontactset; #endif // Colliders /* -- not used -- also uncomment in InitOPCODECaches() PlanesCollider _PlanesCollider; -- not used */ SphereCollider _SphereCollider; OBBCollider _OBBCollider; RayCollider _RayCollider; AABBTreeCollider _AABBTreeCollider; /* -- not used -- also uncomment in InitOPCODECaches() LSSCollider _LSSCollider; */ // Trimesh caches CollisionFaces Faces; SphereCache defaultSphereCache; OBBCache defaultBoxCache; LSSCache defaultCapsuleCache; #endif // dTRIMESH_OPCODE }; #if dTLS_ENABLED inline TrimeshCollidersCache *GetTrimeshCollidersCache(unsigned uiTLSKind) { EODETLSKIND tkTLSKind = (EODETLSKIND)uiTLSKind; return COdeTls::GetTrimeshCollidersCache(tkTLSKind); } #else // dTLS_ENABLED inline TrimeshCollidersCache *GetTrimeshCollidersCache(unsigned uiTLSKind) { extern TrimeshCollidersCache g_ccTrimeshCollidersCache; return &g_ccTrimeshCollidersCache; } #endif // dTLS_ENABLED struct dxTriMeshData : public dBase { /* Array of flags for which edges and verts should be used on each triangle */ enum UseFlags { kEdge0 = 0x1, kEdge1 = 0x2, kEdge2 = 0x4, kVert0 = 0x8, kVert1 = 0x10, kVert2 = 0x20, kUseAll = 0xFF, }; /* Setup the UseFlags array */ void Preprocess(); /* For when app changes the vertices */ void UpdateData(); #if dTRIMESH_OPCODE Model BVTree; MeshInterface Mesh; dxTriMeshData(); ~dxTriMeshData(); void Build(const void* Vertices, int VertexStide, int VertexCount, const void* Indices, int IndexCount, int TriStride, const void* Normals, bool Single); /* aabb in model space */ dVector3 AABBCenter; dVector3 AABBExtents; // data for use in collision resolution const void* Normals; uint8* UseFlags; #endif // dTRIMESH_OPCODE #if dTRIMESH_GIMPACT const char* m_Vertices; int m_VertexStride; int m_VertexCount; const char* m_Indices; int m_TriangleCount; int m_TriStride; bool m_single; dxTriMeshData() { m_Vertices=NULL; m_VertexStride = 12; m_VertexCount = 0; m_Indices = 0; m_TriangleCount = 0; m_TriStride = 12; m_single = true; } void Build(const void* Vertices, int VertexStride, int VertexCount, const void* Indices, int IndexCount, int TriStride, const void* Normals, bool Single) { dIASSERT(Vertices); dIASSERT(Indices); dIASSERT(VertexStride); dIASSERT(TriStride); dIASSERT(IndexCount); m_Vertices=(const char *)Vertices; m_VertexStride = VertexStride; m_VertexCount = VertexCount; m_Indices = (const char *)Indices; m_TriangleCount = IndexCount/3; m_TriStride = TriStride; m_single = Single; } inline void GetVertex(unsigned int i, dVector3 Out) { if(m_single) { const float * fverts = (const float * )(m_Vertices + m_VertexStride*i); Out[0] = fverts[0]; Out[1] = fverts[1]; Out[2] = fverts[2]; Out[3] = 1.0f; } else { const double * dverts = (const double * )(m_Vertices + m_VertexStride*i); Out[0] = (float)dverts[0]; Out[1] = (float)dverts[1]; Out[2] = (float)dverts[2]; Out[3] = 1.0f; } } inline void GetTriIndices(unsigned int itriangle, unsigned int triindices[3]) { const unsigned int * ind = (const unsigned int * )(m_Indices + m_TriStride*itriangle); triindices[0] = ind[0]; triindices[1] = ind[1]; triindices[2] = ind[2]; } #endif // dTRIMESH_GIMPACT }; struct dxTriMesh : public dxGeom{ // Callbacks dTriCallback* Callback; dTriArrayCallback* ArrayCallback; dTriRayCallback* RayCallback; dTriTriMergeCallback* TriMergeCallback; // Data types dxTriMeshData* Data; bool doSphereTC; bool doBoxTC; bool doCapsuleTC; // Functions dxTriMesh(dSpaceID Space, dTriMeshDataID Data); ~dxTriMesh(); void ClearTCCache(); int AABBTest(dxGeom* g, dReal aabb[6]); void computeAABB(); #if dTRIMESH_OPCODE // Instance data for last transform. dMatrix4 last_trans; // Some constants // Temporal coherence struct SphereTC : public SphereCache{ dxGeom* Geom; }; dArray SphereTCCache; struct BoxTC : public OBBCache{ dxGeom* Geom; }; dArray BoxTCCache; struct CapsuleTC : public LSSCache{ dxGeom* Geom; }; dArray CapsuleTCCache; #endif // dTRIMESH_OPCODE #if dTRIMESH_GIMPACT GIM_TRIMESH m_collision_trimesh; GBUFFER_MANAGER_DATA m_buffer_managers[G_BUFFER_MANAGER__MAX]; #endif // dTRIMESH_GIMPACT }; #if 0 #include "collision_kernel.h" // Fetches a contact 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 dTRIMESH_OPCODE inline unsigned FetchTriangleCount(dxTriMesh* TriMesh) { return TriMesh->Data->Mesh.GetNbTriangles(); } inline void FetchTriangle(dxTriMesh* TriMesh, int Index, const dVector3 Position, const dMatrix3 Rotation, dVector3 Out[3]){ VertexPointers VP; ConversionArea VC; TriMesh->Data->Mesh.GetTriangle(VP, Index, VC); for (int i = 0; i < 3; i++){ dVector3 v; v[0] = VP.Vertex[i]->x; v[1] = VP.Vertex[i]->y; v[2] = VP.Vertex[i]->z; v[3] = 0; dMULTIPLY0_331(Out[i], Rotation, v); Out[i][0] += Position[0]; Out[i][1] += Position[1]; Out[i][2] += Position[2]; Out[i][3] = 0; } } inline void FetchTransformedTriangle(dxTriMesh* TriMesh, int Index, dVector3 Out[3]){ const dVector3& Position = *(const dVector3*)dGeomGetPosition(TriMesh); const dMatrix3& Rotation = *(const dMatrix3*)dGeomGetRotation(TriMesh); FetchTriangle(TriMesh, Index, Position, Rotation, Out); } inline Matrix4x4& MakeMatrix(const dVector3 Position, const dMatrix3 Rotation, Matrix4x4& Out){ Out.m[0][0] = (float) Rotation[0]; Out.m[1][0] = (float) Rotation[1]; Out.m[2][0] = (float) Rotation[2]; Out.m[0][1] = (float) Rotation[4]; Out.m[1][1] = (float) Rotation[5]; Out.m[2][1] = (float) Rotation[6]; Out.m[0][2] = (float) Rotation[8]; Out.m[1][2] = (float) Rotation[9]; Out.m[2][2] = (float) Rotation[10]; Out.m[3][0] = (float) Position[0]; Out.m[3][1] = (float) Position[1]; Out.m[3][2] = (float) Position[2]; Out.m[0][3] = 0.0f; Out.m[1][3] = 0.0f; Out.m[2][3] = 0.0f; Out.m[3][3] = 1.0f; return Out; } inline Matrix4x4& MakeMatrix(dxGeom* g, Matrix4x4& Out){ const dVector3& Position = *(const dVector3*)dGeomGetPosition(g); const dMatrix3& Rotation = *(const dMatrix3*)dGeomGetRotation(g); return MakeMatrix(Position, Rotation, Out); } #endif // dTRIMESH_OPCODE #if dTRIMESH_GIMPACT #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; \ } inline void gim_trimesh_get_triangle_verticesODE(GIM_TRIMESH * trimesh, GUINT32 triangle_index, dVector3 v1, dVector3 v2, dVector3 v3) { vec3f src1, src2, src3; gim_trimesh_get_triangle_vertices(trimesh, triangle_index, src1, src2, src3); dVECTOR3_VEC3F_COPY(v1, src1); dVECTOR3_VEC3F_COPY(v2, src2); 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 inline int gim_trimesh_ray_closest_collisionODE( GIM_TRIMESH *mesh, dVector3 origin, dVector3 dir, GREAL tmax, GIM_TRIANGLE_RAY_CONTACT_DATA *contact ) { vec3f dir_vec3f = { dir[ 0 ], dir[ 1 ], dir[ 2 ] }; vec3f origin_vec3f = { origin[ 0 ], origin[ 1 ], origin[ 2 ] }; return gim_trimesh_ray_closest_collision( mesh, origin_vec3f, dir_vec3f, tmax, contact ); } inline int gim_trimesh_ray_collisionODE( GIM_TRIMESH *mesh, dVector3 origin, dVector3 dir, GREAL tmax, GIM_TRIANGLE_RAY_CONTACT_DATA *contact ) { vec3f dir_vec3f = { dir[ 0 ], dir[ 1 ], dir[ 2 ] }; vec3f origin_vec3f = { origin[ 0 ], origin[ 1 ], origin[ 2 ] }; return gim_trimesh_ray_collision( mesh, origin_vec3f, dir_vec3f, tmax, contact ); } #define gim_trimesh_sphere_collisionODE( mesh, Position, Radius, contact ) { \ vec3f pos_vec3f = { Position[ 0 ], Position[ 1 ], Position[ 2 ] }; \ gim_trimesh_sphere_collision( mesh, pos_vec3f, Radius, contact ); \ } #define gim_trimesh_plane_collisionODE( mesh, plane, contact ) { \ vec4f plane_vec4f = { plane[ 0 ], plane[ 1 ], plane[ 2 ], 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 // 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 // dDouble inline unsigned FetchTriangleCount(dxTriMesh* TriMesh) { return gim_trimesh_get_triangle_count(&TriMesh->m_collision_trimesh); } inline void FetchTransformedTriangle(dxTriMesh* TriMesh, int Index, dVector3 Out[3]){ gim_trimesh_locks_work_data(&TriMesh->m_collision_trimesh); gim_trimesh_get_triangle_vertices(&TriMesh->m_collision_trimesh, (GUINT32)Index, Out[0], Out[1], Out[2]); gim_trimesh_unlocks_work_data(&TriMesh->m_collision_trimesh); } inline void MakeMatrix(const dVector3 Position, const dMatrix3 Rotation, mat4f m) { m[0][0] = (float) Rotation[0]; m[0][1] = (float) Rotation[1]; m[0][2] = (float) Rotation[2]; m[1][0] = (float) Rotation[4]; m[1][1] = (float) Rotation[5]; m[1][2] = (float) Rotation[6]; m[2][0] = (float) Rotation[8]; m[2][1] = (float) Rotation[9]; m[2][2] = (float) Rotation[10]; m[0][3] = (float) Position[0]; m[1][3] = (float) Position[1]; m[2][3] = (float) Position[2]; } inline void MakeMatrix(dxGeom* g, mat4f Out){ const dVector3& Position = *(const dVector3*)dGeomGetPosition(g); const dMatrix3& Rotation = *(const dMatrix3*)dGeomGetRotation(g); MakeMatrix(Position, Rotation, Out); } #endif // dTRIMESH_GIMPACT // Outputs a matrix to 3 vectors inline void Decompose(const dMatrix3 Matrix, dVector3 Right, dVector3 Up, dVector3 Direction){ Right[0] = Matrix[0 * 4 + 0]; Right[1] = Matrix[1 * 4 + 0]; Right[2] = Matrix[2 * 4 + 0]; Right[3] = REAL(0.0); Up[0] = Matrix[0 * 4 + 1]; Up[1] = Matrix[1 * 4 + 1]; Up[2] = Matrix[2 * 4 + 1]; Up[3] = REAL(0.0); Direction[0] = Matrix[0 * 4 + 2]; Direction[1] = Matrix[1 * 4 + 2]; Direction[2] = Matrix[2 * 4 + 2]; Direction[3] = REAL(0.0); } // Outputs a matrix to 3 vectors inline void Decompose(const dMatrix3 Matrix, dVector3 Vectors[3]){ Decompose(Matrix, Vectors[0], Vectors[1], Vectors[2]); } // Finds barycentric 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); } // Performs a callback inline bool Callback(dxTriMesh* TriMesh, dxGeom* Object, int TriIndex){ if (TriMesh->Callback != NULL){ return (TriMesh->Callback(TriMesh, Object, TriIndex)!=0); } else return true; } // Some utilities template const T& dcMAX(const T& x, const T& y){ return x > y ? x : y; } template const T& dcMIN(const T& x, const T& y){ return x < y ? x : y; } dReal SqrDistancePointTri( const dVector3 p, const dVector3 triOrigin, const dVector3 triEdge1, const dVector3 triEdge2, dReal* pfSParam = 0, dReal* pfTParam = 0 ); dReal SqrDistanceSegments( const dVector3 seg1Origin, const dVector3 seg1Direction, const dVector3 seg2Origin, const dVector3 seg2Direction, dReal* pfSegP0 = 0, dReal* pfSegP1 = 0 ); dReal SqrDistanceSegTri( const dVector3 segOrigin, const dVector3 segEnd, const dVector3 triOrigin, const dVector3 triEdge1, const dVector3 triEdge2, dReal* t = 0, dReal* u = 0, dReal* v = 0 ); inline void Vector3Subtract( const dVector3 left, const dVector3 right, dVector3 result ) { result[0] = left[0] - right[0]; result[1] = left[1] - right[1]; result[2] = left[2] - right[2]; result[3] = REAL(0.0); } inline void Vector3Add( const dVector3 left, const dVector3 right, dVector3 result ) { result[0] = left[0] + right[0]; result[1] = left[1] + right[1]; result[2] = left[2] + right[2]; result[3] = REAL(0.0); } inline void Vector3Negate( const dVector3 in, dVector3 out ) { out[0] = -in[0]; out[1] = -in[1]; out[2] = -in[2]; out[3] = REAL(0.0); } inline void Vector3Copy( const dVector3 in, dVector3 out ) { out[0] = in[0]; out[1] = in[1]; out[2] = in[2]; out[3] = REAL(0.0); } inline void Vector3Multiply( const dVector3 in, dReal scalar, dVector3 out ) { out[0] = in[0] * scalar; out[1] = in[1] * scalar; out[2] = in[2] * scalar; out[3] = REAL(0.0); } inline void TransformVector3( const dVector3 in, const dMatrix3 orientation, const dVector3 position, dVector3 out ) { dMULTIPLY0_331( out, orientation, in ); out[0] += position[0]; out[1] += position[1]; out[2] += position[2]; } //------------------------------------------------------------------------------ /** @brief Check for intersection between triangle and capsule. @param dist [out] Shortest distance squared between the triangle and the capsule segment (central axis). @param t [out] t value of point on segment that's the shortest distance away from the triangle, the coordinates of this point can be found by (cap.seg.end - cap.seg.start) * t, or cap.seg.ipol(t). @param u [out] Barycentric coord on triangle. @param v [out] Barycentric coord on triangle. @return True if intersection exists. The third Barycentric coord is implicit, ie. w = 1.0 - u - v The Barycentric coords give the location of the point on the triangle closest to the capsule (where the distance between the two shapes is the shortest). */ inline bool IntersectCapsuleTri( const dVector3 segOrigin, const dVector3 segEnd, const dReal radius, const dVector3 triOrigin, const dVector3 triEdge0, const dVector3 triEdge1, dReal* dist, dReal* t, dReal* u, dReal* v ) { dReal sqrDist = SqrDistanceSegTri( segOrigin, segEnd, triOrigin, triEdge0, triEdge1, t, u, v ); if ( dist ) *dist = sqrDist; return ( sqrDist <= (radius * radius) ); } #endif //_ODE_COLLISION_TRIMESH_INTERNAL_H_ ode-0.11.1/ode/src/stepfast.cpp0000755000076400007640000007556311042177700013207 00000000000000/************************************************************************* * * * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * * All rights reserved. Email: russ@q12.org Web: www.q12.org * * * * Fast iterative solver, David Whittaker. Email: david@csworkbench.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 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 the StepFast code by David Whittaker. This code is faster, but // sometimes less stable than, the original "big matrix" code. // Refer to the user's manual for more information. // Note that this source file duplicates a lot of stuff from step.cpp, // eventually we should move the common code to a third file. #include "objects.h" #include "joints/joint.h" #include #include "config.h" #include #include #include #include #include #include #include #include "lcp.h" #include "step.h" #include "util.h" // misc defines #define ALLOCA dALLOCA16 #define RANDOM_JOINT_ORDER //#define FAST_FACTOR //use a factorization approximation to the LCP solver (fast, theoretically less accurate) #define SLOW_LCP //use the old LCP solver //#define NO_ISLANDS //does not perform island creation code (3~4% of simulation time), body disabling doesn't work //#define TIMING static int autoEnableDepth = 2; void dWorldSetAutoEnableDepthSF1 (dxWorld *world, int autodepth) { if (autodepth > 0) autoEnableDepth = autodepth; else autoEnableDepth = 0; } int dWorldGetAutoEnableDepthSF1 (dxWorld *world) { return autoEnableDepth; } //little bit of math.... the _sym_ functions assume the return matrix will be symmetric static void Multiply2_sym_p8p (dReal * A, dReal * B, dReal * C, int p, int Askip) { int i, j; dReal sum, *aa, *ad, *bb, *cc; dIASSERT (p > 0 && A && B && C); bb = B; for (i = 0; i < p; i++) { //aa is going accross the matrix, ad down aa = ad = A; cc = C; for (j = i; j < p; j++) { sum = bb[0] * cc[0]; sum += bb[1] * cc[1]; sum += bb[2] * cc[2]; sum += bb[4] * cc[4]; sum += bb[5] * cc[5]; sum += bb[6] * cc[6]; *(aa++) = *ad = sum; ad += Askip; cc += 8; } bb += 8; A += Askip + 1; C += 8; } } static void MultiplyAdd2_sym_p8p (dReal * A, dReal * B, dReal * C, int p, int Askip) { int i, j; dReal sum, *aa, *ad, *bb, *cc; dIASSERT (p > 0 && A && B && C); bb = B; for (i = 0; i < p; i++) { //aa is going accross the matrix, ad down aa = ad = A; cc = C; for (j = i; j < p; j++) { sum = bb[0] * cc[0]; sum += bb[1] * cc[1]; sum += bb[2] * cc[2]; sum += bb[4] * cc[4]; sum += bb[5] * cc[5]; sum += bb[6] * cc[6]; *(aa++) += sum; *ad += sum; ad += Askip; cc += 8; } bb += 8; A += Askip + 1; C += 8; } } // this assumes the 4th and 8th rows of B are zero. static void Multiply0_p81 (dReal * A, dReal * B, dReal * C, int p) { int i; dIASSERT (p > 0 && A && B && C); dReal sum; for (i = p; i; i--) { sum = B[0] * C[0]; sum += B[1] * C[1]; sum += B[2] * C[2]; sum += B[4] * C[4]; sum += B[5] * C[5]; sum += B[6] * C[6]; *(A++) = sum; B += 8; } } // this assumes the 4th and 8th rows of B are zero. static void MultiplyAdd0_p81 (dReal * A, dReal * B, dReal * C, int p) { int i; dIASSERT (p > 0 && A && B && C); dReal sum; for (i = p; i; i--) { sum = B[0] * C[0]; sum += B[1] * C[1]; sum += B[2] * C[2]; sum += B[4] * C[4]; sum += B[5] * C[5]; sum += B[6] * C[6]; *(A++) += sum; B += 8; } } // this assumes the 4th and 8th rows of B are zero. static void Multiply1_8q1 (dReal * A, dReal * B, dReal * C, int q) { int k; dReal sum; dIASSERT (q > 0 && A && B && C); sum = 0; for (k = 0; k < q; k++) sum += B[k * 8] * C[k]; A[0] = sum; sum = 0; for (k = 0; k < q; k++) sum += B[1 + k * 8] * C[k]; A[1] = sum; sum = 0; for (k = 0; k < q; k++) sum += B[2 + k * 8] * C[k]; A[2] = sum; sum = 0; for (k = 0; k < q; k++) sum += B[4 + k * 8] * C[k]; A[4] = sum; sum = 0; for (k = 0; k < q; k++) sum += B[5 + k * 8] * C[k]; A[5] = sum; sum = 0; for (k = 0; k < q; k++) sum += B[6 + k * 8] * C[k]; A[6] = sum; } //**************************************************************************** // 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; } #if 0 // this is just dxStepBody() // given a body b, apply its linear and angular rotation over the time // interval h, thereby adjusting its position and orientation. static inline void moveAndRotateBody (dxBody * b, dReal h) { int j; // handle linear velocity for (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, irv; // finite rotation vector dReal k = dDOT (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 (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 (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 (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 for (dxGeom * geom = b->geom; geom; geom = dGeomGetBodyNext (geom)) dGeomMoved (geom); } #endif //**************************************************************************** //This is an implementation of the iterated/relaxation algorithm. //Here is a quick overview of the algorithm per Sergi Valverde's posts to the //mailing list: // // for i=0..N-1 do // for c = 0..C-1 do // Solve constraint c-th // Apply forces to constraint bodies // next // next // Integrate bodies void dInternalStepFast (dxWorld * world, dxBody * body[2], dReal * GI[2], dReal * GinvI[2], dxJoint * joint, dxJoint::Info1 info, dxJoint::Info2 Jinfo, dReal stepsize) { int i, j, k; # ifdef TIMING dTimerNow ("constraint preprocessing"); # endif dReal stepsize1 = dRecip (stepsize); int m = info.m; // nothing to do if no constraints. if (m <= 0) return; int nub = 0; if (info.nub == info.m) nub = m; // 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. # ifdef TIMING dTimerNow ("compute A"); # endif dReal JinvM[2 * 6 * 8]; //dSetZero (JinvM, 2 * m * 8); dReal *Jsrc = Jinfo.J1l; dReal *Jdst = JinvM; if (body[0]) { for (j = m - 1; j >= 0; j--) { for (k = 0; k < 3; k++) Jdst[k] = Jsrc[k] * body[0]->invMass; dMULTIPLY0_133 (Jdst + 4, Jsrc + 4, GinvI[0]); Jsrc += 8; Jdst += 8; } } if (body[1]) { Jsrc = Jinfo.J2l; Jdst = JinvM + 8 * m; for (j = m - 1; j >= 0; j--) { for (k = 0; k < 3; k++) Jdst[k] = Jsrc[k] * body[1]->invMass; dMULTIPLY0_133 (Jdst + 4, Jsrc + 4, GinvI[1]); Jsrc += 8; Jdst += 8; } } // now compute A = JinvM * J'. int mskip = dPAD (m); dReal A[6 * 8]; //dSetZero (A, 6 * 8); if (body[0]) { Multiply2_sym_p8p (A, JinvM, Jinfo.J1l, m, mskip); if (body[1]) MultiplyAdd2_sym_p8p (A, JinvM + 8 * m, Jinfo.J2l, m, mskip); } else { if (body[1]) Multiply2_sym_p8p (A, JinvM + 8 * m, Jinfo.J2l, m, mskip); } // add cfm to the diagonal of A for (i = 0; i < m; i++) A[i * mskip + i] += Jinfo.cfm[i] * stepsize1; // compute the right hand side `rhs' # ifdef TIMING dTimerNow ("compute rhs"); # endif dReal tmp1[16]; //dSetZero (tmp1, 16); // put v/h + invM*fe into tmp1 for (i = 0; i < 2; i++) { if (!body[i]) continue; for (j = 0; j < 3; j++) tmp1[i * 8 + j] = body[i]->facc[j] * body[i]->invMass + body[i]->lvel[j] * stepsize1; dMULTIPLY0_331 (tmp1 + i * 8 + 4, GinvI[i], body[i]->tacc); for (j = 0; j < 3; j++) tmp1[i * 8 + 4 + j] += body[i]->avel[j] * stepsize1; } // put J*tmp1 into rhs dReal rhs[6]; //dSetZero (rhs, 6); if (body[0]) { Multiply0_p81 (rhs, Jinfo.J1l, tmp1, m); if (body[1]) MultiplyAdd0_p81 (rhs, Jinfo.J2l, tmp1 + 8, m); } else { if (body[1]) Multiply0_p81 (rhs, Jinfo.J2l, tmp1 + 8, m); } // complete rhs for (i = 0; i < m; i++) rhs[i] = Jinfo.c[i] * stepsize1 - rhs[i]; #ifdef SLOW_LCP // solve the LCP problem and get lambda. // this will destroy A but that's okay # ifdef TIMING dTimerNow ("solving LCP problem"); # endif dReal *lambda = (dReal *) ALLOCA (m * sizeof (dReal)); dReal *residual = (dReal *) ALLOCA (m * sizeof (dReal)); dReal lo[6], hi[6]; memcpy (lo, Jinfo.lo, m * sizeof (dReal)); memcpy (hi, Jinfo.hi, m * sizeof (dReal)); dSolveLCP (m, A, lambda, rhs, residual, nub, lo, hi, Jinfo.findex); #endif // LCP Solver replacement: // This algorithm goes like this: // Do a straightforward LDLT factorization of the matrix A, solving for // A*x = rhs // For each x[i] that is outside of the bounds of lo[i] and hi[i], // clamp x[i] into that range. // Substitute into A the now known x's // subtract the residual away from the rhs. // Remove row and column i from L, updating the factorization // place the known x's at the end of the array, keeping up with location in p // Repeat until all constraints have been clamped or all are within bounds // // This is probably only faster in the single joint case where only one repeat is // the norm. #ifdef FAST_FACTOR // factorize A (L*D*L'=A) # ifdef TIMING dTimerNow ("factorize A"); # endif dReal d[6]; dReal L[6 * 8]; memcpy (L, A, m * mskip * sizeof (dReal)); dFactorLDLT (L, d, m, mskip); // compute lambda # ifdef TIMING dTimerNow ("compute lambda"); # endif int left = m; //constraints left to solve. int remove[6]; dReal lambda[6]; dReal x[6]; int p[6]; for (i = 0; i < 6; i++) p[i] = i; while (true) { memcpy (x, rhs, left * sizeof (dReal)); dSolveLDLT (L, d, x, left, mskip); int fixed = 0; for (i = 0; i < left; i++) { j = p[i]; remove[i] = false; // This isn't the exact same use of findex as dSolveLCP.... since x[findex] // may change after I've already clamped x[i], but it should be close if (Jinfo.findex[j] > -1) { dReal f = fabs (Jinfo.hi[j] * x[p[Jinfo.findex[j]]]); if (x[i] > f) x[i] = f; else if (x[i] < -f) x[i] = -f; else continue; } else { if (x[i] > Jinfo.hi[j]) x[i] = Jinfo.hi[j]; else if (x[i] < Jinfo.lo[j]) x[i] = Jinfo.lo[j]; else continue; } remove[i] = true; fixed++; } if (fixed == 0 || fixed == left) //no change or all constraints solved break; for (i = 0; i < left; i++) //sub in to right hand side. if (remove[i]) for (j = 0; j < left; j++) if (!remove[j]) rhs[j] -= A[j * mskip + i] * x[i]; for (int r = left - 1; r >= 0; r--) //eliminate row/col for fixed variables { if (remove[r]) { //dRemoveLDLT adapted for use without row pointers. if (r == left - 1) { left--; continue; // deleting last row/col is easy } else if (r == 0) { dReal a[6]; for (i = 0; i < left; i++) a[i] = -A[i * mskip]; a[0] += REAL (1.0); dLDLTAddTL (L, d, a, left, mskip); } else { dReal t[6]; dReal a[6]; for (i = 0; i < r; i++) t[i] = L[r * mskip + i] / d[i]; for (i = 0; i < left - r; i++) a[i] = dDot (L + (r + i) * mskip, t, r) - A[(r + i) * mskip + r]; a[0] += REAL (1.0); dLDLTAddTL (L + r * mskip + r, d + r, a, left - r, mskip); } dRemoveRowCol (L, left, mskip, r); //end dRemoveLDLT left--; if (r < (left - 1)) { dReal tx = x[r]; memmove (d + r, d + r + 1, (left - r) * sizeof (dReal)); memmove (rhs + r, rhs + r + 1, (left - r) * sizeof (dReal)); //x will get written over by rhs anyway, no need to move it around //just store the fixed value we just discovered in it. x[left] = tx; for (i = 0; i < m; i++) if (p[i] > r && p[i] <= left) p[i]--; p[r] = left; } } } } for (i = 0; i < m; i++) lambda[i] = x[p[i]]; # endif // compute the constraint force `cforce' # ifdef TIMING dTimerNow ("compute constraint force"); #endif // compute cforce = J'*lambda dJointFeedback *fb = joint->feedback; dReal cforce[16]; //dSetZero (cforce, 16); if (fb) { // the user has requested feedback on the amount of force that this // joint is applying to the bodies. we use a slightly slower // computation that splits out the force components and puts them // in the feedback structure. dReal data1[8], data2[8]; if (body[0]) { Multiply1_8q1 (data1, Jinfo.J1l, lambda, m); dReal *cf1 = cforce; cf1[0] = (fb->f1[0] = data1[0]); cf1[1] = (fb->f1[1] = data1[1]); cf1[2] = (fb->f1[2] = data1[2]); cf1[4] = (fb->t1[0] = data1[4]); cf1[5] = (fb->t1[1] = data1[5]); cf1[6] = (fb->t1[2] = data1[6]); } if (body[1]) { Multiply1_8q1 (data2, Jinfo.J2l, lambda, m); dReal *cf2 = cforce + 8; cf2[0] = (fb->f2[0] = data2[0]); cf2[1] = (fb->f2[1] = data2[1]); cf2[2] = (fb->f2[2] = data2[2]); cf2[4] = (fb->t2[0] = data2[4]); cf2[5] = (fb->t2[1] = data2[5]); cf2[6] = (fb->t2[2] = data2[6]); } } else { // no feedback is required, let's compute cforce the faster way if (body[0]) Multiply1_8q1 (cforce, Jinfo.J1l, lambda, m); if (body[1]) Multiply1_8q1 (cforce + 8, Jinfo.J2l, lambda, m); } for (i = 0; i < 2; i++) { if (!body[i]) continue; for (j = 0; j < 3; j++) { body[i]->facc[j] += cforce[i * 8 + j]; body[i]->tacc[j] += cforce[i * 8 + 4 + j]; } } } void dInternalStepIslandFast (dxWorld * world, dxBody * const *bodies, int nb, dxJoint * const *_joints, int nj, dReal stepsize, int maxiterations) { # ifdef TIMING dTimerNow ("preprocessing"); # endif dxBody *bodyPair[2], *body; dReal *GIPair[2], *GinvIPair[2]; dxJoint *joint; int iter, b, j, i; dReal ministep = stepsize / maxiterations; // make a local copy of the joint array, because we might want to modify it. // (the "dxJoint *const*" declaration says we're allowed to modify the joints // but not the joint array, because the caller might need it unchanged). dxJoint **joints = (dxJoint **) ALLOCA (nj * sizeof (dxJoint *)); memcpy (joints, _joints, nj * sizeof (dxJoint *)); // 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. int m = 0; dxJoint::Info1 * info = (dxJoint::Info1 *) ALLOCA (nj * sizeof (dxJoint::Info1)); int *ofs = (int *) ALLOCA (nj * sizeof (int)); for (i = 0, j = 0; j < nj; j++) { // i=dest, j=src joints[j]->getInfo1 (info + i); dIASSERT (info[i].m >= 0 && info[i].m <= 6 && info[i].nub >= 0 && info[i].nub <= info[i].m); if (info[i].m > 0) { joints[i] = joints[j]; joints[i]->tag = i; i++; } else { joints[j]->tag = -1; } } nj = i; // the purely unbounded constraints for (i = 0; i < nj; i++) { ofs[i] = m; m += info[i].m; } dReal *c = NULL; dReal *cfm = NULL; dReal *lo = NULL; dReal *hi = NULL; int *findex = NULL; dReal *J = NULL; dxJoint::Info2 * Jinfo = NULL; if (m) { // 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. c = (dReal *) ALLOCA (m * sizeof (dReal)); cfm = (dReal *) ALLOCA (m * sizeof (dReal)); lo = (dReal *) ALLOCA (m * sizeof (dReal)); hi = (dReal *) ALLOCA (m * sizeof (dReal)); findex = (int *) ALLOCA (m * sizeof (int)); dSetZero (c, m); dSetValue (cfm, m, world->global_cfm); dSetValue (lo, m, -dInfinity); dSetValue (hi, m, dInfinity); for (i = 0; i < m; i++) findex[i] = -1; // 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 // # ifdef TIMING dTimerNow ("create J"); # endif J = (dReal *) ALLOCA (2 * m * 8 * sizeof (dReal)); dSetZero (J, 2 * m * 8); Jinfo = (dxJoint::Info2 *) ALLOCA (nj * sizeof (dxJoint::Info2)); for (i = 0; i < nj; i++) { Jinfo[i].rowskip = 8; Jinfo[i].fps = dRecip (stepsize); Jinfo[i].erp = world->global_erp; Jinfo[i].J1l = J + 2 * 8 * ofs[i]; Jinfo[i].J1a = Jinfo[i].J1l + 4; Jinfo[i].J2l = Jinfo[i].J1l + 8 * info[i].m; Jinfo[i].J2a = Jinfo[i].J2l + 4; Jinfo[i].c = c + ofs[i]; Jinfo[i].cfm = cfm + ofs[i]; Jinfo[i].lo = lo + ofs[i]; Jinfo[i].hi = hi + ofs[i]; Jinfo[i].findex = findex + ofs[i]; //joints[i]->getInfo2 (Jinfo+i); } } dReal *saveFacc = (dReal *) ALLOCA (nb * 4 * sizeof (dReal)); dReal *saveTacc = (dReal *) ALLOCA (nb * 4 * sizeof (dReal)); dReal *globalI = (dReal *) ALLOCA (nb * 12 * sizeof (dReal)); dReal *globalInvI = (dReal *) ALLOCA (nb * 12 * sizeof (dReal)); for (b = 0; b < nb; b++) { for (i = 0; i < 4; i++) { saveFacc[b * 4 + i] = bodies[b]->facc[i]; saveTacc[b * 4 + i] = bodies[b]->tacc[i]; } bodies[b]->tag = b; } for (iter = 0; iter < maxiterations; iter++) { # ifdef TIMING dTimerNow ("applying inertia and gravity"); # endif dReal tmp[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; for (b = 0; b < nb; b++) { body = bodies[b]; // 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 vertically stacked 3x4 matrices, one per body. // @@@ check computation of rotational force. // compute inertia tensor in global frame dMULTIPLY2_333 (tmp, body->mass.I, body->posr.R); dMULTIPLY0_333 (globalI + b * 12, body->posr.R, tmp); // compute inverse inertia tensor in global frame dMULTIPLY2_333 (tmp, body->invI, body->posr.R); dMULTIPLY0_333 (globalInvI + b * 12, body->posr.R, tmp); for (i = 0; i < 4; i++) body->tacc[i] = saveTacc[b * 4 + i]; if (body->flags & dxBodyGyroscopic) { // DanielKO: this doesn't look right/efficient, but anyways... // compute rotational force dMULTIPLY0_331 (tmp, globalI + b * 12, body->avel); dCROSS (body->tacc, -=, body->avel, tmp); } // add the gravity force to all bodies if ((body->flags & dxBodyNoGravity) == 0) { body->facc[0] = saveFacc[b * 4 + 0] + body->mass.mass * world->gravity[0]; body->facc[1] = saveFacc[b * 4 + 1] + body->mass.mass * world->gravity[1]; body->facc[2] = saveFacc[b * 4 + 2] + body->mass.mass * world->gravity[2]; body->facc[3] = 0; } else { body->facc[0] = saveFacc[b * 4 + 0]; body->facc[1] = saveFacc[b * 4 + 1]; body->facc[2] = saveFacc[b * 4 + 2]; body->facc[3] = 0; } } #ifdef RANDOM_JOINT_ORDER #ifdef TIMING dTimerNow ("randomizing joint order"); #endif //randomize the order of the joints by looping through the array //and swapping the current joint pointer with a random one before it. for (j = 0; j < nj; j++) { joint = joints[j]; dxJoint::Info1 i1 = info[j]; dxJoint::Info2 i2 = Jinfo[j]; const int r = dRandInt(j+1); dIASSERT (r < nj); joints[j] = joints[r]; info[j] = info[r]; Jinfo[j] = Jinfo[r]; joints[r] = joint; info[r] = i1; Jinfo[r] = i2; } #endif //now iterate through the random ordered joint array we created. for (j = 0; j < nj; j++) { #ifdef TIMING dTimerNow ("setting up joint"); #endif joint = joints[j]; bodyPair[0] = joint->node[0].body; bodyPair[1] = joint->node[1].body; if (bodyPair[0] && (bodyPair[0]->flags & dxBodyDisabled)) bodyPair[0] = 0; if (bodyPair[1] && (bodyPair[1]->flags & dxBodyDisabled)) bodyPair[1] = 0; //if this joint is not connected to any enabled bodies, skip it. if (!bodyPair[0] && !bodyPair[1]) continue; if (bodyPair[0]) { GIPair[0] = globalI + bodyPair[0]->tag * 12; GinvIPair[0] = globalInvI + bodyPair[0]->tag * 12; } if (bodyPair[1]) { GIPair[1] = globalI + bodyPair[1]->tag * 12; GinvIPair[1] = globalInvI + bodyPair[1]->tag * 12; } joints[j]->getInfo2 (Jinfo + j); //dInternalStepIslandFast is an exact copy of the old routine with one //modification: the calculated forces are added back to the facc and tacc //vectors instead of applying them to the bodies and moving them. if (info[j].m > 0) { dInternalStepFast (world, bodyPair, GIPair, GinvIPair, joint, info[j], Jinfo[j], ministep); } } // } # ifdef TIMING dTimerNow ("moving bodies"); # endif //Now we can simulate all the free floating bodies, and move them. for (b = 0; b < nb; b++) { body = bodies[b]; for (i = 0; i < 4; i++) { body->facc[i] *= ministep; body->tacc[i] *= ministep; } //apply torque dMULTIPLYADD0_331 (body->avel, globalInvI + b * 12, body->tacc); //apply force for (i = 0; i < 3; i++) body->lvel[i] += body->invMass * body->facc[i]; //move It! dxStepBody (body, ministep); } } for (b = 0; b < nb; b++) for (j = 0; j < 4; j++) bodies[b]->facc[j] = bodies[b]->tacc[j] = 0; } #ifdef NO_ISLANDS // Since the iterative algorithm doesn't care about islands of bodies, this is a // faster algorithm that just sends it all the joints and bodies in one array. // It's downfall is it's inability to handle disabled bodies as well as the old one. static void processIslandsFast (dxWorld * world, dReal stepsize, int maxiterations) { // nothing to do if no bodies if (world->nb <= 0) return; dInternalHandleAutoDisabling (world,stepsize); # ifdef TIMING dTimerStart ("creating joint and body arrays"); # endif dxBody **bodies, *body; dxJoint **joints, *joint; joints = (dxJoint **) ALLOCA (world->nj * sizeof (dxJoint *)); bodies = (dxBody **) ALLOCA (world->nb * sizeof (dxBody *)); int nj = 0; for (joint = world->firstjoint; joint; joint = (dxJoint *) joint->next) joints[nj++] = joint; int nb = 0; for (body = world->firstbody; body; body = (dxBody *) body->next) bodies[nb++] = body; dInternalStepIslandFast (world, bodies, nb, joints, nj, stepsize, maxiterations); # ifdef TIMING dTimerEnd (); dTimerReport (stdout, 1); # endif } #else //**************************************************************************** // island processing // 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. static void processIslandsFast (dxWorld * world, dReal stepsize, int maxiterations) { #ifdef TIMING dTimerStart ("Island Setup"); #endif dxBody *b, *bb, **body; dxJoint *j, **joint; // nothing to do if no bodies if (world->nb <= 0) return; dInternalHandleAutoDisabling (world,stepsize); // make arrays for body and joint lists (for a single island) to go into body = (dxBody **) ALLOCA (world->nb * sizeof (dxBody *)); joint = (dxJoint **) ALLOCA (world->nj * sizeof (dxJoint *)); int bcount = 0; // number of bodies in `body' int jcount = 0; // number of joints in `joint' int tbcount = 0; int tjcount = 0; // set all body/joint tags to 0 for (b = world->firstbody; b; b = (dxBody *) b->next) b->tag = 0; for (j = world->firstjoint; j; j = (dxJoint *) j->next) j->tag = 0; // 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! int stackalloc = (world->nj < world->nb) ? world->nj : world->nb; dxBody **stack = (dxBody **) ALLOCA (stackalloc * sizeof (dxBody *)); int *autostack = (int *) ALLOCA (stackalloc * sizeof (int)); for (bb = world->firstbody; bb; bb = (dxBody *) bb->next) { #ifdef TIMING dTimerNow ("Island Processing"); #endif // get bb = the next enabled, untagged body, and tag it if (bb->tag || (bb->flags & dxBodyDisabled)) continue; bb->tag = 1; // tag all bodies and joints starting from bb. int stacksize = 0; int autoDepth = autoEnableDepth; b = bb; body[0] = bb; bcount = 1; jcount = 0; goto quickstart; while (stacksize > 0) { b = stack[--stacksize]; // pop body off stack autoDepth = autostack[stacksize]; body[bcount++] = b; // put body on body list quickstart: // traverse and tag all body's joints, add untagged connected bodies // to stack for (dxJointNode * n = b->firstjoint; n; n = n->next) { if (!n->joint->tag) { int thisDepth = autoEnableDepth; n->joint->tag = 1; joint[jcount++] = n->joint; if (n->body && !n->body->tag) { if (n->body->flags & dxBodyDisabled) thisDepth = autoDepth - 1; if (thisDepth < 0) continue; n->body->flags &= ~dxBodyDisabled; n->body->tag = 1; autostack[stacksize] = thisDepth; stack[stacksize++] = n->body; } } } dIASSERT (stacksize <= world->nb); dIASSERT (stacksize <= world->nj); } // now do something with body and joint lists dInternalStepIslandFast (world, body, bcount, joint, jcount, stepsize, maxiterations); // what we've just done may have altered the body/joint tag values. // we must make sure that these tags are nonzero. // also make sure all bodies are in the enabled state. int i; for (i = 0; i < bcount; i++) { body[i]->tag = 1; body[i]->flags &= ~dxBodyDisabled; } for (i = 0; i < jcount; i++) joint[i]->tag = 1; tbcount += bcount; tjcount += jcount; } #ifdef TIMING dMessage(0, "Total joints processed: %i, bodies: %i", tjcount, tbcount); #endif // if debugging, check that all objects (except for disabled bodies, // unconnected joints, and joints that are connected to disabled bodies) // were tagged. # ifndef dNODEBUG for (b = world->firstbody; b; b = (dxBody *) b->next) { if (b->flags & dxBodyDisabled) { if (b->tag) dDebug (0, "disabled body tagged"); } else { if (!b->tag) dDebug (0, "enabled body not tagged"); } } for (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)) { if (!j->tag) dDebug (0, "attached enabled joint not tagged"); } else { if (j->tag) dDebug (0, "unattached or disabled joint tagged"); } } # endif # ifdef TIMING dTimerEnd (); dTimerReport (stdout, 1); # endif } #endif void dWorldStepFast1 (dWorldID w, dReal stepsize, int maxiterations) { dUASSERT (w, "bad world argument"); dUASSERT (stepsize > 0, "stepsize must be > 0"); processIslandsFast (w, stepsize, maxiterations); } ode-0.11.1/ode/src/heightfield.cpp0000644000076400007640000016750511204321032013612 00000000000000// 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 #include #include #include #include #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_fMaxHeight) m_fMaxHeight = h; } break; // short case 2: data_short = (short*)m_pHeightData; m_fMinHeight = dInfinity; m_fMaxHeight = -dInfinity; for (i=0; i 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_fMaxHeight) m_fMaxHeight = h; } break; // double case 4: data_double = (double*)m_pHeightData; m_fMinHeight = dInfinity; m_fMaxHeight = -dInfinity; for (i=0; i( 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(size_t numTri) { size_t alignedNumTri = AlignBufferSize(numTri, TEMP_TRIANGLE_BUFFER_ELEMENT_COUNT_ALIGNMENT); tempTriangleBufferSize = alignedNumTri; tempTriangleBuffer = new HeightFieldTriangle[alignedNumTri]; } void dxHeightfield::resetTriangleBuffer() { delete[] tempTriangleBuffer; } void dxHeightfield::allocatePlaneBuffer(size_t numTri) { size_t alignedNumTri = AlignBufferSize(numTri, TEMP_PLANE_BUFFER_ELEMENT_COUNT_ALIGNMENT); tempPlaneBufferSize = alignedNumTri; tempPlaneBuffer = new HeightFieldPlane *[alignedNumTri]; tempPlaneInstances = new HeightFieldPlane[alignedNumTri]; HeightFieldPlane *ptrPlaneMatrix = tempPlaneInstances; for (size_t indexTri = 0; indexTri != alignedNumTri; indexTri++) { tempPlaneBuffer[indexTri] = ptrPlaneMatrix; ptrPlaneMatrix += 1; } } void dxHeightfield::resetPlaneBuffer() { delete[] tempPlaneInstances; delete[] tempPlaneBuffer; } void dxHeightfield::allocateHeightBuffer(size_t numX, size_t numZ) { size_t alignedNumX = AlignBufferSize(numX, TEMP_HEIGHT_BUFFER_ELEMENT_COUNT_ALIGNMENT_X); size_t alignedNumZ = AlignBufferSize(numZ, TEMP_HEIGHT_BUFFER_ELEMENT_COUNT_ALIGNMENT_Z); tempHeightBufferSizeX = alignedNumX; tempHeightBufferSizeZ = alignedNumZ; tempHeightBuffer = new HeightFieldVertex *[alignedNumX]; size_t numCells = alignedNumX * alignedNumZ; tempHeightInstances = new HeightFieldVertex [numCells]; HeightFieldVertex *ptrHeightMatrix = tempHeightInstances; for (size_t 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->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 size_t numPlanes) { bool has_swapped = true; do { has_swapped = false;//reset flag for (size_t 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 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 size_t 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 (size_t 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 (size_t 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 (size_t 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 (size_t 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 (size_t m = 0; m < 3; m++) { const size_t 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. dOP( 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; int nMinX; int nMaxX; int nMinZ; int nMaxZ; 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; } nMinX = int(dFloor(o2->aabb[0] * terrain->m_p_data->m_fInvSampleWidth)); nMaxX = int(dFloor(o2->aabb[1] * terrain->m_p_data->m_fInvSampleWidth)) + 1; nMinZ = int(dFloor(o2->aabb[4] * terrain->m_p_data->m_fInvSampleDepth)); nMaxZ = int(dFloor(o2->aabb[5] * terrain->m_p_data->m_fInvSampleDepth)) + 1; 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); dOPE( 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 ); dOP( pContact->pos, +, pContact->pos, terrain->final_posr->pos ); dOPE( 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; } ode-0.11.1/ode/src/collision_sapspace.cpp0000644000076400007640000006205411151015271015207 00000000000000/************************************************************************* * * * 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 #include #include #include #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(size_t nNewSize); void ReallocateRanksIfNecessary(size_t nNewSize); private: void SetCurrentSize(size_t nValue) { mCurrentSize = nValue; } size_t GetCurrentSize() const { return mCurrentSize; } void SetCurrentUtilization(size_t nValue) { mCurrentUtilization = nValue; } size_t 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: size_t mCurrentSize; //!< Current size of the indices list size_t mCurrentUtilization; //!< Current utilization of the indices list bool mRanksValid; uint32* mRanksBuffer; //!< Two lists allocated sequentially in a single block uint32* mPrimaryRanks; }; void RaixSortContext::AllocateRanks(size_t nNewSize) { dIASSERT(GetCurrentSize() == 0); mRanksBuffer = new uint32[2 * nNewSize]; mPrimaryRanks = mRanksBuffer; SetCurrentSize(nNewSize); } void RaixSortContext::FreeRanks() { SetCurrentSize(0); delete[] mRanksBuffer; } void RaixSortContext::ReallocateRanksIfNecessary(size_t nNewSize) { size_t nCurUtilization = GetCurrentUtilization(); if (nNewSize != nCurUtilization) { size_t 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 DirtyList; // dirty geoms dArray 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 TmpGeomList; // temporary for normal geoms dArray 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 indice into dirty/geom lists. #define GEOM_SET_DIRTY_IDX(g,idx) { (g)->next = (dxGeom*)(size_t)(idx); } #define GEOM_SET_GEOM_IDX(g,idx) { (g)->tome = (dxGeom**)(size_t)(idx); } #define GEOM_GET_DIRTY_IDX(g) ((int)(size_t)(g)->next) #define GEOM_GET_GEOM_IDX(g) ((int)(size_t)(g)->tome) #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->parent_space == 0 && g->next == 0, "geom is already in a space"); g->gflags |= GEOM_DIRTY | GEOM_AABB_BAD; // add to dirty list GEOM_SET_DIRTY_IDX( g, DirtyList.size() ); GEOM_SET_GEOM_IDX( g, GEOM_INVALID_IDX ); DirtyList.push( g ); g->parent_space = this; this->count++; dGeomMoved(this); } 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=0 && dirtyIdxparent_space = 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 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 && geomIdxcleanGeoms(); } g->recomputeAABB(); g->gflags &= (~(GEOM_DIRTY|GEOM_AABB_BAD)); // 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 ) { // Size the poslist (+1 for infinity end cap) poslist.setSize( tmp_geom_count + 1 ); // 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 ) { // 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 ]; poslist[ count++ ] = FLT_MAX; // 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; Pair IndexPair; while ( RunningAddress < LastSorted && Sorted < LastSorted ) { IndexPair.id0 = *Sorted++; // empty, this loop just advances RunningAddress while ( poslist[*RunningAddress++] < poslist[IndexPair.id0] ) {} if ( RunningAddress < LastSorted ) { const uint32* RunningAddress2 = RunningAddress; const dReal idx0ax0max = geoms[IndexPair.id0]->aabb[ax0idx+1]; const dReal idx0ax1max = geoms[IndexPair.id0]->aabb[ax1idx+1]; const dReal idx0ax2max = geoms[IndexPair.id0]->aabb[ax2idx+1]; while ( 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] ) if ( idx0ax2max >= aabb1[ax2idx] && aabb1[ax2idx+1] >= aabb0[ax2idx] ) { pairs.push( IndexPair ); } } } }; // while ( RunningAddress < LastSorted && Sorted < LastSorted ) } //============================================================================== //------------------------------------------------------------------------------ // Radix Sort //------------------------------------------------------------------------------ #define CHECK_PASS_VALIDITY(pass) \ /* Shortcut to current counters */ \ 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 = *(((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 ) { uint32* input = (uint32*)input2; // 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 */ uint8* p = (uint8*)input; 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 */ float* Running = (float*)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>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>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 #include #include #include // 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 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 inline void dVector3Subtract(const dVector3& a,const dVector3& b,dVector3& c) { c[0] = a[0] - b[0]; c[1] = a[1] - b[1]; c[2] = a[2] - b[2]; } // Some vector math inline void dVector3Scale(dVector3& a,dReal nScale) { a[0] *= nScale ; a[1] *= nScale ; a[2] *= nScale ; } inline void dVector3Add(const dVector3& a,const dVector3& b,dVector3& c) { c[0] = a[0] + b[0]; c[1] = a[1] + b[1]; c[2] = a[2] + b[2]; } inline void dVector3Copy(const dVector3& a,dVector3& c) { c[0] = a[0]; c[1] = a[1]; c[2] = a[2]; } inline void dVector4Copy(const dVector4& a,dVector4& c) { c[0] = a[0]; c[1] = a[1]; c[2] = a[2]; c[3] = a[3]; } inline void dVector3Cross(const dVector3& a,const dVector3& b,dVector3& c) { dCROSS(c,=,a,b); } inline dReal dVector3Length(const dVector3& a) { return dSqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]); } inline dReal dVector3Dot(const dVector3& a,const dVector3& b) { return dDOT(a,b); } inline void dVector3Inv(dVector3& a) { a[0] = -a[0]; a[1] = -a[1]; a[2] = -a[2]; } inline dReal dVector3Length2(const dVector3& a) { return (a[0]*a[0]+a[1]*a[1]+a[2]*a[2]); } inline void dMat3GetCol(const dMatrix3& m,const int col, dVector3& v) { v[0] = m[col + 0]; v[1] = m[col + 4]; v[2] = m[col + 8]; } inline void dVector3CrossMat3Col(const dMatrix3& m,const int col,const dVector3& v,dVector3& r) { r[0] = v[1] * m[2*4 + col] - v[2] * m[1*4 + col]; r[1] = v[2] * m[0*4 + col] - v[0] * m[2*4 + col]; r[2] = v[0] * m[1*4 + col] - v[1] * m[0*4 + col]; } inline void dMat3ColCrossVector3(const dMatrix3& m,const int col,const dVector3& v,dVector3& r) { r[0] = v[2] * m[1*4 + col] - v[1] * m[2*4 + col]; r[1] = v[0] * m[2*4 + col] - v[2] * m[0*4 + col]; r[2] = v[1] * m[0*4 + col] - v[0] * m[1*4 + col]; } inline void dMultiplyMat3Vec3(const dMatrix3& m,const dVector3& v, dVector3& r) { dMULTIPLY0_331(r,m,v); } inline dReal dPointPlaneDistance(const dVector3& point,const dVector4& plane) { return (plane[0]*point[0] + plane[1]*point[1] + plane[2]*point[2] + plane[3]); } 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; } inline void dMatrix3Copy(const dReal* source,dMatrix3& dest) { dest[0] = source[0]; dest[1] = source[1]; dest[2] = source[2]; dest[4] = source[4]; dest[5] = source[5]; dest[6] = source[6]; dest[8] = source[8]; dest[9] = source[9]; dest[10]= source[10]; } 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 ); } inline void dMatrix3Inv( const dMatrix3& ma, dMatrix3& dst ) { dReal det = dMatrix3Det( ma ); if ( dFabs( det ) < REAL(0.0005) ) { dRSetIdentity( dst ); return; } dst[0] = ma[5]*ma[10] - ma[6]*ma[9] / det; dst[1] = -( ma[1]*ma[10] - ma[9]*ma[2] ) / det; dst[2] = ma[1]*ma[6] - ma[5]*ma[2] / det; dst[4] = -( ma[4]*ma[10] - ma[6]*ma[8] ) / det; dst[5] = ma[0]*ma[10] - ma[8]*ma[2] / det; dst[6] = -( ma[0]*ma[6] - ma[4]*ma[2] ) / det; dst[8] = ma[4]*ma[9] - ma[8]*ma[5] / det; dst[9] = -( ma[0]*ma[9] - ma[8]*ma[1] ) / det; dst[10] = ma[0]*ma[5] - ma[1]*ma[4] / det; } 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]; */ } 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); } } 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); } } 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) { dest[0] = source[0] / norm; dest[1] = -source[1] / norm; dest[2] = -source[2] / norm; dest[3] = -source[3] / norm; } else { // Singular -> return identity dest[0] = REAL(1.0); dest[1] = REAL(0.0); dest[2] = REAL(0.0); dest[3] = REAL(0.0); } } #endif ode-0.11.1/ode/src/odetls.cpp0000644000076400007640000001153511156775756012657 00000000000000/************************************************************************* * * * Thread local storage access stub for Open Dynamics Engine, * * Copyright (C) 2008 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 #include #include "config.h" #include "odetls.h" #include "collision_trimesh_internal.h" #if dTLS_ENABLED ////////////////////////////////////////////////////////////////////////// // 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)(size_t)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) { FreeTrimeshCollidersCache(pccCacheInstance); CThreadLocalStorage::UnsafeSetStorageValue(m_ahtkStorageKeys[tkTLSKind], OTI_TRIMESH_TRIMESH_COLLIDER_CACHE, (tlsvaluetype)NULL); } } ////////////////////////////////////////////////////////////////////////// // Value type destructors void COdeTls::FreeTrimeshCollidersCache(TrimeshCollidersCache *pccCacheInstance) { delete pccCacheInstance; } ////////////////////////////////////////////////////////////////////////// // Value type destructor callbacks void COdeTls::FreeTrimeshCollidersCache_Callback(tlsvaluetype vValueData) { TrimeshCollidersCache *pccCacheInstance = (TrimeshCollidersCache *)vValueData; FreeTrimeshCollidersCache(pccCacheInstance); } #endif // #if dTLS_ENABLED ode-0.11.1/ode/src/fastldlt.c0000644000076400007640000002141711165471013012615 00000000000000/* generated code, do not edit. */ #include "ode/matrix.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 2*2. * if this is in the factorizer source file, n must be a multiple of 2. */ static void dSolveL1_1 (const dReal *L, dReal *B, int n, int lskip1) { /* declare variables - Z matrix, p and q vectors, etc */ dReal Z11,m11,Z21,m21,p1,q1,p2,*ex; const dReal *ell; int i,j; /* compute all 2 x 1 blocks of X */ for (i=0; i < n; i+=2) { /* compute all 2 x 1 block of X, from rows i..i+2-1 */ /* set the Z matrix to 0 */ Z11=0; Z21=0; ell = L + i*lskip1; ex = B; /* the inner loop that computes outer products and adds them to Z */ for (j=i-2; j >= 0; j -= 2) { /* compute outer product and add it to the Z matrix */ p1=ell[0]; q1=ex[0]; m11 = p1 * q1; p2=ell[lskip1]; m21 = p2 * q1; Z11 += m11; Z21 += m21; /* compute outer product and add it to the Z matrix */ p1=ell[1]; q1=ex[1]; m11 = p1 * q1; p2=ell[1+lskip1]; m21 = p2 * q1; /* advance pointers */ ell += 2; ex += 2; Z11 += m11; Z21 += m21; /* end of inner loop */ } /* compute left-over iterations */ j += 2; for (; j > 0; j--) { /* compute outer product and add it to the Z matrix */ p1=ell[0]; q1=ex[0]; m11 = p1 * q1; p2=ell[lskip1]; m21 = p2 * q1; /* advance pointers */ ell += 1; ex += 1; Z11 += m11; Z21 += m21; } /* finish computing the X(i) block */ Z11 = ex[0] - Z11; ex[0] = Z11; p1 = ell[lskip1]; Z21 = ex[1] - Z21 - p1*Z11; ex[1] = Z21; /* end of outer loop */ } } /* solve L*X=B, with B containing 2 right hand sides. * 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*2 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 dSolveL1_2 (const dReal *L, dReal *B, int n, int lskip1) { /* declare variables - Z matrix, p and q vectors, etc */ dReal Z11,m11,Z12,m12,Z21,m21,Z22,m22,p1,q1,p2,q2,*ex; const dReal *ell; int i,j; /* compute all 2 x 2 blocks of X */ for (i=0; i < n; i+=2) { /* compute all 2 x 2 block of X, from rows i..i+2-1 */ /* set the Z matrix to 0 */ Z11=0; Z12=0; Z21=0; Z22=0; ell = L + i*lskip1; ex = B; /* the inner loop that computes outer products and adds them to Z */ for (j=i-2; j >= 0; j -= 2) { /* compute outer product and add it to the Z matrix */ p1=ell[0]; q1=ex[0]; m11 = p1 * q1; q2=ex[lskip1]; m12 = p1 * q2; p2=ell[lskip1]; m21 = p2 * q1; m22 = p2 * q2; Z11 += m11; Z12 += m12; Z21 += m21; Z22 += m22; /* compute outer product and add it to the Z matrix */ p1=ell[1]; q1=ex[1]; m11 = p1 * q1; q2=ex[1+lskip1]; m12 = p1 * q2; p2=ell[1+lskip1]; m21 = p2 * q1; m22 = p2 * q2; /* advance pointers */ ell += 2; ex += 2; Z11 += m11; Z12 += m12; Z21 += m21; Z22 += m22; /* end of inner loop */ } /* compute left-over iterations */ j += 2; for (; j > 0; j--) { /* compute outer product and add it to the Z matrix */ p1=ell[0]; q1=ex[0]; m11 = p1 * q1; q2=ex[lskip1]; m12 = p1 * q2; p2=ell[lskip1]; m21 = p2 * q1; m22 = p2 * q2; /* advance pointers */ ell += 1; ex += 1; Z11 += m11; Z12 += m12; Z21 += m21; Z22 += m22; } /* finish computing the X(i) block */ Z11 = ex[0] - Z11; ex[0] = Z11; Z12 = ex[lskip1] - Z12; ex[lskip1] = Z12; p1 = ell[lskip1]; Z21 = ex[1] - Z21 - p1*Z11; ex[1] = Z21; Z22 = ex[1+lskip1] - Z22 - p1*Z12; ex[1+lskip1] = Z22; /* end of outer loop */ } } void dFactorLDLT (dReal *A, dReal *d, int n, int nskip1) { int i,j; dReal sum,*ell,*dee,dd,p1,p2,q1,q2,Z11,m11,Z21,m21,Z22,m22; if (n < 1) return; for (i=0; i<=n-2; i += 2) { /* solve L*(D*l)=a, l is scaled elements in 2 x i block at A(i,0) */ dSolveL1_2 (A,A+i*nskip1,i,nskip1); /* scale the elements in a 2 x i block at A(i,0), and also */ /* compute Z = the outer product matrix that we'll need. */ Z11 = 0; Z21 = 0; Z22 = 0; ell = A+i*nskip1; dee = d; for (j=i-6; j >= 0; j -= 6) { p1 = ell[0]; p2 = ell[nskip1]; dd = dee[0]; q1 = p1*dd; q2 = p2*dd; ell[0] = q1; ell[nskip1] = q2; m11 = p1*q1; m21 = p2*q1; m22 = p2*q2; Z11 += m11; Z21 += m21; Z22 += m22; p1 = ell[1]; p2 = ell[1+nskip1]; dd = dee[1]; q1 = p1*dd; q2 = p2*dd; ell[1] = q1; ell[1+nskip1] = q2; m11 = p1*q1; m21 = p2*q1; m22 = p2*q2; Z11 += m11; Z21 += m21; Z22 += m22; p1 = ell[2]; p2 = ell[2+nskip1]; dd = dee[2]; q1 = p1*dd; q2 = p2*dd; ell[2] = q1; ell[2+nskip1] = q2; m11 = p1*q1; m21 = p2*q1; m22 = p2*q2; Z11 += m11; Z21 += m21; Z22 += m22; p1 = ell[3]; p2 = ell[3+nskip1]; dd = dee[3]; q1 = p1*dd; q2 = p2*dd; ell[3] = q1; ell[3+nskip1] = q2; m11 = p1*q1; m21 = p2*q1; m22 = p2*q2; Z11 += m11; Z21 += m21; Z22 += m22; p1 = ell[4]; p2 = ell[4+nskip1]; dd = dee[4]; q1 = p1*dd; q2 = p2*dd; ell[4] = q1; ell[4+nskip1] = q2; m11 = p1*q1; m21 = p2*q1; m22 = p2*q2; Z11 += m11; Z21 += m21; Z22 += m22; p1 = ell[5]; p2 = ell[5+nskip1]; dd = dee[5]; q1 = p1*dd; q2 = p2*dd; ell[5] = q1; ell[5+nskip1] = q2; m11 = p1*q1; m21 = p2*q1; m22 = p2*q2; Z11 += m11; Z21 += m21; Z22 += m22; ell += 6; dee += 6; } /* compute left-over iterations */ j += 6; for (; j > 0; j--) { p1 = ell[0]; p2 = ell[nskip1]; dd = dee[0]; q1 = p1*dd; q2 = p2*dd; ell[0] = q1; ell[nskip1] = q2; m11 = p1*q1; m21 = p2*q1; m22 = p2*q2; Z11 += m11; Z21 += m21; Z22 += m22; ell++; dee++; } /* solve for diagonal 2 x 2 block at A(i,i) */ Z11 = ell[0] - Z11; Z21 = ell[nskip1] - Z21; Z22 = ell[1+nskip1] - Z22; dee = d + i; /* factorize 2 x 2 block Z,dee */ /* factorize row 1 */ dee[0] = dRecip(Z11); /* factorize row 2 */ sum = 0; q1 = Z21; q2 = q1 * dee[0]; Z21 = q2; sum += q1*q2; dee[1] = dRecip(Z22 - sum); /* done factorizing 2 x 2 block */ ell[nskip1] = Z21; } /* compute the (less than 2) rows at the bottom */ switch (n-i) { case 0: break; case 1: dSolveL1_1 (A,A+i*nskip1,i,nskip1); /* scale the elements in a 1 x i block at A(i,0), and also */ /* compute Z = the outer product matrix that we'll need. */ Z11 = 0; ell = A+i*nskip1; dee = d; for (j=i-6; j >= 0; j -= 6) { p1 = ell[0]; dd = dee[0]; q1 = p1*dd; ell[0] = q1; m11 = p1*q1; Z11 += m11; p1 = ell[1]; dd = dee[1]; q1 = p1*dd; ell[1] = q1; m11 = p1*q1; Z11 += m11; p1 = ell[2]; dd = dee[2]; q1 = p1*dd; ell[2] = q1; m11 = p1*q1; Z11 += m11; p1 = ell[3]; dd = dee[3]; q1 = p1*dd; ell[3] = q1; m11 = p1*q1; Z11 += m11; p1 = ell[4]; dd = dee[4]; q1 = p1*dd; ell[4] = q1; m11 = p1*q1; Z11 += m11; p1 = ell[5]; dd = dee[5]; q1 = p1*dd; ell[5] = q1; m11 = p1*q1; Z11 += m11; ell += 6; dee += 6; } /* compute left-over iterations */ j += 6; for (; j > 0; j--) { p1 = ell[0]; dd = dee[0]; q1 = p1*dd; ell[0] = q1; m11 = p1*q1; Z11 += m11; ell++; dee++; } /* solve for diagonal 1 x 1 block at A(i,i) */ Z11 = ell[0] - Z11; dee = d + i; /* factorize 1 x 1 block Z,dee */ /* factorize row 1 */ dee[0] = dRecip(Z11); /* done factorizing 1 x 1 block */ break; default: *((char*)0)=0; /* this should never happen! */ } } ode-0.11.1/ode/src/Makefile.in0000644000076400007640000011023211206343412012670 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 = collision_trimesh_gimpact.cpp \ @GIMPACT_TRUE@ collision_trimesh_trimesh.cpp \ @GIMPACT_TRUE@ collision_trimesh_sphere.cpp \ @GIMPACT_TRUE@ collision_trimesh_ray.cpp \ @GIMPACT_TRUE@ collision_trimesh_opcode.cpp \ @GIMPACT_TRUE@ collision_trimesh_box.cpp \ @GIMPACT_TRUE@ collision_trimesh_ccylinder.cpp \ @GIMPACT_TRUE@ collision_trimesh_distance.cpp \ @GIMPACT_TRUE@ collision_trimesh_internal.h \ @GIMPACT_TRUE@ collision_cylinder_trimesh.cpp \ @GIMPACT_TRUE@ collision_trimesh_plane.cpp @GIMPACT_TRUE@am__append_6 = $(top_builddir)/GIMPACT/src/libGIMPACT.la ################################# # 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_trimesh.cpp \ @OPCODE_TRUE@ collision_trimesh_trimesh_new.cpp \ @OPCODE_TRUE@ collision_trimesh_sphere.cpp \ @OPCODE_TRUE@ collision_trimesh_ray.cpp \ @OPCODE_TRUE@ collision_trimesh_opcode.cpp \ @OPCODE_TRUE@ collision_trimesh_box.cpp \ @OPCODE_TRUE@ collision_trimesh_ccylinder.cpp \ @OPCODE_TRUE@ collision_trimesh_distance.cpp \ @OPCODE_TRUE@ collision_trimesh_internal.h \ @OPCODE_TRUE@ collision_cylinder_trimesh.cpp \ @OPCODE_TRUE@ collision_trimesh_plane.cpp subdir = ode/src DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(srcdir)/config.h.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_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 = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(libdir)" libLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) libfast_la_LIBADD = am_libfast_la_OBJECTS = libfast_la-fastldlt.lo \ libfast_la-fastltsolve.lo libfast_la-fastdot.lo \ libfast_la-fastlsolve.lo libfast_la_OBJECTS = $(am_libfast_la_OBJECTS) libfast_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libfast_la_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ libode_la_DEPENDENCIES = libfast.la joints/libjoints.la \ $(am__append_2) $(am__append_6) $(am__append_8) am__libode_la_SOURCES_DIST = 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_util.cpp \ collision_util.h convex.cpp cylinder.cpp error.cpp \ export-dif.cpp heightfield.cpp heightfield.h lcp.cpp lcp.h \ mass.cpp mat.cpp mat.h matrix.cpp memory.cpp misc.cpp \ objects.h obstack.cpp obstack.h ode.cpp odeinit.cpp \ odemath.cpp odeou.h odetls.h plane.cpp quickstep.cpp \ quickstep.h ray.cpp rotation.cpp sphere.cpp step.cpp step.h \ stepfast.cpp testing.cpp testing.h timer.cpp util.cpp util.h \ odetls.cpp odeou.cpp collision_trimesh_gimpact.cpp \ collision_trimesh_trimesh.cpp collision_trimesh_sphere.cpp \ collision_trimesh_ray.cpp collision_trimesh_opcode.cpp \ collision_trimesh_box.cpp collision_trimesh_ccylinder.cpp \ collision_trimesh_distance.cpp collision_cylinder_trimesh.cpp \ collision_trimesh_plane.cpp collision_trimesh_trimesh_new.cpp @ENABLE_OU_TRUE@am__objects_1 = odetls.lo odeou.lo @GIMPACT_TRUE@am__objects_2 = collision_trimesh_gimpact.lo \ @GIMPACT_TRUE@ collision_trimesh_trimesh.lo \ @GIMPACT_TRUE@ collision_trimesh_sphere.lo \ @GIMPACT_TRUE@ collision_trimesh_ray.lo \ @GIMPACT_TRUE@ collision_trimesh_opcode.lo \ @GIMPACT_TRUE@ collision_trimesh_box.lo \ @GIMPACT_TRUE@ collision_trimesh_ccylinder.lo \ @GIMPACT_TRUE@ collision_trimesh_distance.lo \ @GIMPACT_TRUE@ collision_cylinder_trimesh.lo \ @GIMPACT_TRUE@ collision_trimesh_plane.lo @OPCODE_TRUE@am__objects_3 = collision_trimesh_trimesh.lo \ @OPCODE_TRUE@ collision_trimesh_trimesh_new.lo \ @OPCODE_TRUE@ collision_trimesh_sphere.lo \ @OPCODE_TRUE@ collision_trimesh_ray.lo \ @OPCODE_TRUE@ collision_trimesh_opcode.lo \ @OPCODE_TRUE@ collision_trimesh_box.lo \ @OPCODE_TRUE@ collision_trimesh_ccylinder.lo \ @OPCODE_TRUE@ collision_trimesh_distance.lo \ @OPCODE_TRUE@ collision_cylinder_trimesh.lo \ @OPCODE_TRUE@ collision_trimesh_plane.lo am_libode_la_OBJECTS = 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 error.lo export-dif.lo heightfield.lo lcp.lo \ mass.lo mat.lo matrix.lo memory.lo misc.lo obstack.lo ode.lo \ odeinit.lo odemath.lo plane.lo quickstep.lo ray.lo rotation.lo \ sphere.lo step.lo stepfast.lo testing.lo timer.lo util.lo \ $(am__objects_1) $(am__objects_2) $(am__objects_3) libode_la_OBJECTS = $(am_libode_la_OBJECTS) libode_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(libode_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libfast_la_SOURCES) $(libode_la_SOURCES) DIST_SOURCES = $(libfast_la_SOURCES) $(am__libode_la_SOURCES_DIST) RECURSIVE_TARGETS = all-recursive check-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 uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ 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@ 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@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODE_PRECISION = @ODE_PRECISION@ ODE_RELEASE = @ODE_RELEASE@ 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_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ 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@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ 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 $(am__append_1) $(am__append_4) \ $(am__append_7) # convenience library to simulate per object cflags noinst_LTLIBRARIES = libfast.la libfast_la_CFLAGS = -O1 -Wall libfast_la_SOURCES = fastldlt.c fastltsolve.c fastdot.c fastlsolve.c lib_LTLIBRARIES = libode.la libode_la_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ @ODE_VERSION_INFO@ libode_la_LIBADD = libfast.la joints/libjoints.la $(am__append_2) \ $(am__append_6) $(am__append_8) # please, let's keep the filenames sorted libode_la_SOURCES = 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_util.cpp \ collision_util.h convex.cpp cylinder.cpp error.cpp \ export-dif.cpp heightfield.cpp heightfield.h lcp.cpp lcp.h \ mass.cpp mat.cpp mat.h matrix.cpp memory.cpp misc.cpp \ objects.h obstack.cpp obstack.h ode.cpp odeinit.cpp \ odemath.cpp odeou.h odetls.h plane.cpp quickstep.cpp \ quickstep.h ray.cpp rotation.cpp sphere.cpp step.cpp step.h \ stepfast.cpp testing.cpp testing.h timer.cpp util.cpp util.h \ $(am__append_3) $(am__append_5) $(am__append_9) 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'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign ode/src/Makefile .PRECIOUS: 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 config.h: stamp-h1 @if test ! -f $@; then \ rm -f stamp-h1; \ $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ else :; fi 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) cd $(top_srcdir) && $(AUTOHEADER) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ f=$(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ else :; fi; \ done uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ p=$(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libfast.la: $(libfast_la_OBJECTS) $(libfast_la_DEPENDENCIES) $(libfast_la_LINK) $(libfast_la_OBJECTS) $(libfast_la_LIBADD) $(LIBS) libode.la: $(libode_la_OBJECTS) $(libode_la_DEPENDENCIES) $(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_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_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_distance.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_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_new.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)/error.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/export-dif.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)/libfast_la-fastdot.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfast_la-fastldlt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfast_la-fastlsolve.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfast_la-fastltsolve.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)/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)/rotation.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)/stepfast.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testing.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@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< libfast_la-fastldlt.lo: fastldlt.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfast_la_CFLAGS) $(CFLAGS) -MT libfast_la-fastldlt.lo -MD -MP -MF $(DEPDIR)/libfast_la-fastldlt.Tpo -c -o libfast_la-fastldlt.lo `test -f 'fastldlt.c' || echo '$(srcdir)/'`fastldlt.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libfast_la-fastldlt.Tpo $(DEPDIR)/libfast_la-fastldlt.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fastldlt.c' object='libfast_la-fastldlt.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfast_la_CFLAGS) $(CFLAGS) -c -o libfast_la-fastldlt.lo `test -f 'fastldlt.c' || echo '$(srcdir)/'`fastldlt.c libfast_la-fastltsolve.lo: fastltsolve.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfast_la_CFLAGS) $(CFLAGS) -MT libfast_la-fastltsolve.lo -MD -MP -MF $(DEPDIR)/libfast_la-fastltsolve.Tpo -c -o libfast_la-fastltsolve.lo `test -f 'fastltsolve.c' || echo '$(srcdir)/'`fastltsolve.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libfast_la-fastltsolve.Tpo $(DEPDIR)/libfast_la-fastltsolve.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fastltsolve.c' object='libfast_la-fastltsolve.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfast_la_CFLAGS) $(CFLAGS) -c -o libfast_la-fastltsolve.lo `test -f 'fastltsolve.c' || echo '$(srcdir)/'`fastltsolve.c libfast_la-fastdot.lo: fastdot.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfast_la_CFLAGS) $(CFLAGS) -MT libfast_la-fastdot.lo -MD -MP -MF $(DEPDIR)/libfast_la-fastdot.Tpo -c -o libfast_la-fastdot.lo `test -f 'fastdot.c' || echo '$(srcdir)/'`fastdot.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libfast_la-fastdot.Tpo $(DEPDIR)/libfast_la-fastdot.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fastdot.c' object='libfast_la-fastdot.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfast_la_CFLAGS) $(CFLAGS) -c -o libfast_la-fastdot.lo `test -f 'fastdot.c' || echo '$(srcdir)/'`fastdot.c libfast_la-fastlsolve.lo: fastlsolve.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfast_la_CFLAGS) $(CFLAGS) -MT libfast_la-fastlsolve.lo -MD -MP -MF $(DEPDIR)/libfast_la-fastlsolve.Tpo -c -o libfast_la-fastlsolve.lo `test -f 'fastlsolve.c' || echo '$(srcdir)/'`fastlsolve.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libfast_la-fastlsolve.Tpo $(DEPDIR)/libfast_la-fastlsolve.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fastlsolve.c' object='libfast_la-fastlsolve.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfast_la_CFLAGS) $(CFLAGS) -c -o libfast_la-fastlsolve.lo `test -f 'fastlsolve.c' || echo '$(srcdir)/'`fastlsolve.c .cpp.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(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. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; 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; \ (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" $(RECURSIVE_CLEAN_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ 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 || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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 \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 \ 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 info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-exec-am: install-libLTLIBRARIES install-html: install-html-recursive install-info: install-info-recursive install-man: install-pdf: install-pdf-recursive install-ps: install-ps-recursive 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: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool clean-noinstLTLIBRARIES \ ctags ctags-recursive 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-recursive uninstall uninstall-am \ uninstall-libLTLIBRARIES # 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: ode-0.11.1/ode/src/objects.h0000644000076400007640000001462211042177700012436 00000000000000/************************************************************************* * * * 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_OBJECT_H_ #define _ODE_OBJECT_H_ #include #include #include #include "array.h" // 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 size, 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 dObject(dxWorld *w); 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 dReal linear_average_threshold; // linear (squared) average velocity threshold dReal angular_average_threshold; // angular (squared) average velocity threshold unsigned int average_samples; // size of the average_lvel and average_avel buffers }; // 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 }; // quick-step parameters struct dxQuickStepParameters { int num_iterations; // number of SOR iterations to perform dReal w; // the SOR over-relaxation parameter }; // contact generation parameters struct dxContactParameters { dReal max_vel; // maximum correcting velocity dReal min_depth; // thickness of 'surface layer' }; // 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 { 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 costraint force mixing parameter dxAutoDisable adis; // auto-disable parameters int body_flags; // flags for new bodies dxQuickStepParameters qs; dxContactParameters contactp; dxDampingParameters dampingp; // damping parameters dReal max_angular_speed; // limit the angular velocity to this magnitude }; #endif ode-0.11.1/ode/src/collision_transform.h0000644000076400007640000000346007562664206015107 00000000000000/************************************************************************* * * * 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 #include "collision_kernel.h" int dCollideTransform (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); #endif ode-0.11.1/ode/src/collision_kernel.h0000644000076400007640000002202411156775756014360 00000000000000/************************************************************************* * * * 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 #include #include #include "config.h" #include "objects.h" #include "odetls.h" //**************************************************************************** // constants and macros // mask for the number-of-contacts field in the dCollide() flags parameter #define NUMC_MASK (0xffff) #define IS_SPACE(geom) \ ((geom)->type >= dFirstSpaceClass && (geom)->type <= dLastSpaceClass) //**************************************************************************** // 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 }; // 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 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; // calculate our new final position from our offset and body void computePosr(); // recalculate our new final position if needed void recomputePosr() { if (gflags & GEOM_POSR_BAD) { computePosr(); gflags &= ~GEOM_POSR_BAD; } } 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; } } // 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; }; //**************************************************************************** // Initialization and finalization functions void dInitColliders(); void dFinitColliders(); void dClearPosrCache(void); void dFinitUserClasses(); #endif ode-0.11.1/ode/src/collision_quadtreespace.cpp0000644000076400007640000003517711122133067016246 00000000000000/************************************************************************* * * * 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. #include #include #include #include #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 MinX, MaxX; dReal MinZ, MaxZ; dGeomID First; int GeomCount; Block* Parent; Block* Children; void Create(const dVector3 Center, const dVector3 Extents, 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->MinX; v[0][UP] = REAL(-1.0); v[0][AXIS1] = Block->MinZ; v[1][AXIS0] = Block->MinX; v[1][UP] = REAL(-1.0); v[1][AXIS1] = Block->MaxZ; v[2][AXIS0] = Block->MaxX; v[2][UP] = REAL(-1.0); v[2][AXIS1] = Block->MinZ; v[3][AXIS0] = Block->MaxX; v[3][UP] = REAL(-1.0); v[3][AXIS1] = Block->MaxZ; v[4][AXIS0] = Block->MinX; v[4][UP] = REAL(1.0); v[4][AXIS1] = Block->MinZ; v[5][AXIS0] = Block->MinX; v[5][UP] = REAL(1.0); v[5][AXIS1] = Block->MaxZ; v[6][AXIS0] = Block->MaxX; v[6][UP] = REAL(1.0); v[6][AXIS1] = Block->MinZ; v[7][AXIS0] = Block->MaxX; v[7][UP] = REAL(1.0); v[7][AXIS1] = Block->MaxZ; // 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 dVector3 Center, const dVector3 Extents, Block* Parent, int Depth, Block*& Blocks){ GeomCount = 0; First = 0; MinX = Center[AXIS0] - Extents[AXIS0]; MaxX = Center[AXIS0] + Extents[AXIS0]; MinZ = Center[AXIS1] - Extents[AXIS1]; MaxZ = Center[AXIS1] + Extents[AXIS1]; this->Parent = Parent; if (Depth > 0){ Children = Blocks; Blocks += SPLITS; dVector3 ChildExtents; ChildExtents[AXIS0] = Extents[AXIS0] / SPLITAXIS; ChildExtents[AXIS1] = Extents[AXIS1] / SPLITAXIS; ChildExtents[UP] = Extents[UP]; for (int i = 0; i < SPLITAXIS; i++){ for (int j = 0; j < SPLITAXIS; j++){ int Index = i * SPLITAXIS + j; dVector3 ChildCenter; ChildCenter[AXIS0] = Center[AXIS0] - Extents[AXIS0] + ChildExtents[AXIS0] + i * (ChildExtents[AXIS0] * 2); ChildCenter[AXIS1] = Center[AXIS1] - Extents[AXIS1] + ChildExtents[AXIS1] + j * (ChildExtents[AXIS1] * 2); ChildCenter[UP] = Center[UP]; Children[Index].Create(ChildCenter, ChildExtents, this, Depth - 1, Blocks); } } } else Children = 0; } void Block::Collide(void* UserData, dNearCallback* Callback){ #ifdef DRAWBLOCKS DrawBlock(this); #endif // Collide the local list dxGeom* g = First; while (g){ if (GEOM_ENABLED(g)){ Collide(g, g->next, UserData, Callback); } g = g->next; } // Recurse for children if (Children){ for (int i = 0; i < SPLITS; i++){ if (Children[i].GeomCount <= 1){ // Early out continue; } Children[i].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; } // Collide against children if (Children){ for (int i = 0; i < SPLITS; i++){ // Early out for empty blocks if (Children[i].GeomCount == 0){ continue; } // Does the geom's AABB collide with the block? // Dont do AABB tests for single geom blocks. if (Children[i].GeomCount == 1 && Children[i].First){ // } else if (true){ if (g1->aabb[AXIS0 * 2 + 0] > Children[i].MaxX || g1->aabb[AXIS0 * 2 + 1] < Children[i].MinX || g1->aabb[AXIS1 * 2 + 0] > Children[i].MaxZ || g1->aabb[AXIS1 * 2 + 1] < Children[i].MinZ) continue; } Children[i].Collide(g1, Children[i].First, UserData, Callback); } } } void Block::CollideLocal(dxGeom* g2, void* UserData, dNearCallback* Callback){ // Collide against local list dxGeom* g1 = First; while (g1){ if (GEOM_ENABLED(g1)){ collideAABBs (g1, g2, UserData, Callback); } g1 = g1->next; } } void Block::AddObject(dGeomID Object){ // Add the geom Object->next = First; First = Object; Object->tome = (dxGeom**)this; // Now traverse upwards to tell that we have a geom Block* Block = this; do{ Block->GeomCount++; Block = Block->Parent; } while (Block); } void Block::DelObject(dGeomID Object){ // Del the geom dxGeom* g = First; dxGeom* Last = 0; while (g){ if (g == Object){ if (Last){ Last->next = g->next; } else First = g->next; break; } Last = g; g = g->next; } Object->tome = 0; // Now traverse upwards to tell that we have lost a geom Block* Block = this; do{ Block->GeomCount--; Block = Block->Parent; } 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] >= MinX && AABB[AXIS0 * 2 + 1] <= MaxX && AABB[AXIS1 * 2 + 0] >= MinZ && AABB[AXIS1 * 2 + 1] <= MaxZ; } Block* Block::GetBlock(const dReal* AABB){ if (Inside(AABB)){ return GetBlockChild(AABB); // Child or this will have a good block } else if (Parent){ return Parent->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 (Children){ for (int i = 0; i < SPLITS; i++){ if (Children[i].Inside(AABB)){ return Children[i].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 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; }; dxQuadTreeSpace::dxQuadTreeSpace(dSpaceID _space, const dVector3 Center, const dVector3 Extents, int Depth) : dxSpace(_space){ type = dQuadTreeSpaceClass; int BlockCount = 0; // TODO: should be just BlockCount = (4^(n+1) - 1)/3 for (int i = 0; i <= Depth; i++){ BlockCount += (int)pow((dReal)SPLITS, i); } Blocks = (Block*)dAlloc(BlockCount * sizeof(Block)); Block* Blocks = this->Blocks + 1; // This pointer gets modified! this->Blocks[0].Create(Center, Extents, 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->Children; } int BlockCount = 0; for (int i = 0; i < Depth; i++){ BlockCount += (int)pow((dReal)SPLITS, i); } 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; 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; // 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->parent_space == 0 && g->next == 0, "geom is already in a space"); g->gflags |= GEOM_DIRTY | GEOM_AABB_BAD; DirtyList.push(g); // add g->parent_space = this; Blocks[0].GetBlock(g->aabb)->AddObject(g); // Add to best block count++; // enumerator has been invalidated current_geom = 0; dGeomMoved(this); } 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)->DelObject(g); count--; 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; } } // safeguard g->next = 0; g->tome = 0; g->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 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(); g->gflags &= (~(GEOM_DIRTY|GEOM_AABB_BAD)); ((Block*)g->tome)->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; // Collide against block and its children DataCallback dc = {UserData, Callback}; CurrentBlock->Collide(g2, CurrentBlock->First, &dc, swap_callback); // Collide against parents while ((CurrentBlock = CurrentBlock->Parent)) CurrentBlock->CollideLocal(g2, UserData, Callback); } else { DataCallback dc = {UserData, Callback}; Blocks[0].Collide(g2, Blocks[0].First, &dc, swap_callback); } lock_count--; } dSpaceID dQuadTreeSpaceCreate(dxSpace* space, const dVector3 Center, const dVector3 Extents, int Depth){ return new dxQuadTreeSpace(space, Center, Extents, Depth); } ode-0.11.1/ode/src/collision_trimesh_box.cpp0000644000076400007640000012210011156775756015752 00000000000000/************************************************************************* * * * 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 #include #include #include #include "collision_util.h" #include "collision_trimesh_internal.h" #if dTRIMESH_ENABLED static void GenerateContact(int in_Flags, dContactGeom* in_Contacts, int in_Stride, dxGeom* in_g1, dxGeom* in_g2, int TriIndex, const dVector3 in_ContactPos, const dVector3 in_Normal, dReal in_Depth, int& OutTriCount); // 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) do{ \ (r)[0]=(a)[0] - (b)[0]; \ (r)[1]=(a)[1] - (b)[1]; \ (r)[2]=(a)[2] - (b)[2]; }while(0) // dVector3 // a=b #define SET(a,b) do{ \ (a)[0]=(b)[0]; \ (a)[1]=(b)[1]; \ (a)[2]=(b)[2]; }while(0) // dMatrix3 // a=b #define SETM(a,b) do{ \ (a)[0]=(b)[0]; \ (a)[1]=(b)[1]; \ (a)[2]=(b)[2]; \ (a)[3]=(b)[3]; \ (a)[4]=(b)[4]; \ (a)[5]=(b)[5]; \ (a)[6]=(b)[6]; \ (a)[7]=(b)[7]; \ (a)[8]=(b)[8]; \ (a)[9]=(b)[9]; \ (a)[10]=(b)[10]; \ (a)[11]=(b)[11]; }while(0) // dVector3 // r=a+b #define ADD(a,b,r) do{ \ (r)[0]=(a)[0] + (b)[0]; \ (r)[1]=(a)[1] + (b)[1]; \ (r)[2]=(a)[2] + (b)[2]; }while(0) // dMatrix3, int, dVector3 // v=column a from m #define GETCOL(m,a,v) do{ \ (v)[0]=(m)[(a)+0]; \ (v)[1]=(m)[(a)+4]; \ (v)[2]=(m)[(a)+8]; }while(0) // dVector4, dVector3 // distance between plane p and point v #define POINTDISTANCE(p,v) \ ( p[0]*v[0] + p[1]*v[1] + p[2]*v[2] + p[3] ) // dVector4, dVector3, dReal // construct plane from normal and d #define CONSTRUCTPLANE(plane,normal,d) do{ \ plane[0]=normal[0];\ plane[1]=normal[1];\ plane[2]=normal[2];\ plane[3]=d; }while(0) // dVector3 // length of vector a #define LENGTHOF(a) \ dSqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]) struct sTrimeshBoxColliderData { sTrimeshBoxColliderData(): m_iBestAxis(0), m_iExitAxis(0), m_ctContacts(0) {} void SetupInitialContext(dxTriMesh *TriMesh, dxGeom *BoxGeom, int Flags, dContactGeom* Contacts, int Stride); int TestCollisionForSingleTriangle(int ctContacts0, 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); void _cldTestOneTriangle(const dVector3 &v0, const dVector3 &v1, const dVector3 &v2, int TriIndex); // 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= 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 dCROSS(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 = dDOT(vL,vD); fp1 = fp0; fp2 = fp0; fR=fa0*dFabs( dDOT(m_vN,vA0) ) + fa1 * dFabs( dDOT(m_vN,vA1) ) + fa2 * dFabs( dDOT(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 = dDOT(vL,m_vN)/fNLen; fp0 = dDOT(vL,vD); fp1 = fp0 + dDOT(vA0,m_vE0); fp2 = fp0 + dDOT(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 = dDOT(vL,m_vN)/fNLen; fp0 = dDOT(vL,vD); fp1 = fp0 + dDOT(vA1,m_vE0); fp2 = fp0 + dDOT(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 = dDOT(vL,m_vN)/fNLen; fp0 = dDOT(vL,vD); fp1 = fp0 + dDOT(vA2,m_vE0); fp2 = fp0 + dDOT(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 dCROSS(vL,=,vA0,m_vE0); fD = dDOT(vL,m_vN)/fNLen; fp0 = dDOT(vL,vD); fp1 = fp0; fp2 = fp0 + dDOT(vA0,m_vN); fR = fa1 * dFabs(dDOT(vA2,m_vE0)) + fa2 * dFabs(dDOT(vA1,m_vE0)); if (!_cldTestEdge(fp1, fp2, fR, fD, vL, 5)) { m_iExitAxis=5; return false; } // ************************************************ // ************************************************ // Axis 6 - Box X-Axis cross Edge1 dCROSS(vL,=,vA0,m_vE1); fD = dDOT(vL,m_vN)/fNLen; fp0 = dDOT(vL,vD); fp1 = fp0 - dDOT(vA0,m_vN); fp2 = fp0; fR = fa1 * dFabs(dDOT(vA2,m_vE1)) + fa2 * dFabs(dDOT(vA1,m_vE1)); if (!_cldTestEdge(fp0, fp1, fR, fD, vL, 6)) { m_iExitAxis=6; return false; } // ************************************************ // ************************************************ // Axis 7 - Box X-Axis cross Edge2 dCROSS(vL,=,vA0,m_vE2); fD = dDOT(vL,m_vN)/fNLen; fp0 = dDOT(vL,vD); fp1 = fp0 - dDOT(vA0,m_vN); fp2 = fp0 - dDOT(vA0,m_vN); fR = fa1 * dFabs(dDOT(vA2,m_vE2)) + fa2 * dFabs(dDOT(vA1,m_vE2)); if (!_cldTestEdge(fp0, fp1, fR, fD, vL, 7)) { m_iExitAxis=7; return false; } // ************************************************ // ************************************************ // Axis 8 - Box Y-Axis cross Edge0 dCROSS(vL,=,vA1,m_vE0); fD = dDOT(vL,m_vN)/fNLen; fp0 = dDOT(vL,vD); fp1 = fp0; fp2 = fp0 + dDOT(vA1,m_vN); fR = fa0 * dFabs(dDOT(vA2,m_vE0)) + fa2 * dFabs(dDOT(vA0,m_vE0)); if (!_cldTestEdge(fp0, fp2, fR, fD, vL, 8)) { m_iExitAxis=8; return false; } // ************************************************ // ************************************************ // Axis 9 - Box Y-Axis cross Edge1 dCROSS(vL,=,vA1,m_vE1); fD = dDOT(vL,m_vN)/fNLen; fp0 = dDOT(vL,vD); fp1 = fp0 - dDOT(vA1,m_vN); fp2 = fp0; fR = fa0 * dFabs(dDOT(vA2,m_vE1)) + fa2 * dFabs(dDOT(vA0,m_vE1)); if (!_cldTestEdge(fp0, fp1, fR, fD, vL, 9)) { m_iExitAxis=9; return false; } // ************************************************ // ************************************************ // Axis 10 - Box Y-Axis cross Edge2 dCROSS(vL,=,vA1,m_vE2); fD = dDOT(vL,m_vN)/fNLen; fp0 = dDOT(vL,vD); fp1 = fp0 - dDOT(vA1,m_vN); fp2 = fp0 - dDOT(vA1,m_vN); fR = fa0 * dFabs(dDOT(vA2,m_vE2)) + fa2 * dFabs(dDOT(vA0,m_vE2)); if (!_cldTestEdge(fp0, fp1, fR, fD, vL, 10)) { m_iExitAxis=10; return false; } // ************************************************ // ************************************************ // Axis 11 - Box Z-Axis cross Edge0 dCROSS(vL,=,vA2,m_vE0); fD = dDOT(vL,m_vN)/fNLen; fp0 = dDOT(vL,vD); fp1 = fp0; fp2 = fp0 + dDOT(vA2,m_vN); fR = fa0 * dFabs(dDOT(vA1,m_vE0)) + fa1 * dFabs(dDOT(vA0,m_vE0)); if (!_cldTestEdge(fp0, fp2, fR, fD, vL, 11)) { m_iExitAxis=11; return false; } // ************************************************ // ************************************************ // Axis 12 - Box Z-Axis cross Edge1 dCROSS(vL,=,vA2,m_vE1); fD = dDOT(vL,m_vN)/fNLen; fp0 = dDOT(vL,vD); fp1 = fp0 - dDOT(vA2,m_vN); fp2 = fp0; fR = fa0 * dFabs(dDOT(vA1,m_vE1)) + fa1 * dFabs(dDOT(vA0,m_vE1)); if (!_cldTestEdge(fp0, fp1, fR, fD, vL, 12)) { m_iExitAxis=12; return false; } // ************************************************ // ************************************************ // Axis 13 - Box Z-Axis cross Edge2 dCROSS(vL,=,vA2,m_vE2); fD = dDOT(vL,m_vN)/fNLen; fp0 = dDOT(vL,vD); fp1 = fp0 - dDOT(vA2,m_vN); fp2 = fp0 - dDOT(vA2,m_vN); fR = fa0 * dFabs(dDOT(vA1,m_vE2)) + fa1 * dFabs(dDOT(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 = dDOT(vLenVec1,vLenVec2); dReal fq1 = dDOT(vLenVec1,vp); dReal fq2 = -dDOT(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 = dDOT(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 #if 0 //#ifdef ORIG -- if to use conditional define, GenerateContact must be moved into #else dContactGeom* Contact = SAFECONTACT(m_iFlags, m_ContactGeoms, m_ctContacts, m_iStride); Contact->depth = m_fBestDepth; SET(Contact->normal,m_vBestNormal); SET(Contact->pos,vPntTmp); Contact->g1 = Geom1; Contact->g2 = Geom2; Contact->side1 = TriIndex; Contact->side2 = -1; m_ctContacts++; #endif GenerateContact(m_iFlags, m_ContactGeoms, m_iStride, m_Geom1, m_Geom2, TriIndex, vPntTmp, m_vBestNormal, m_fBestDepth, m_ctContacts); // 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); dCROSS(vTemp,=,m_vN,vTemp2); dNormalize3(vTemp); CONSTRUCTPLANE(plPlane,vTemp,0); _cldClipPolyToPlane( avTempArray1, iTempCnt1, avTempArray2, iTempCnt2, plPlane ); // Plane p1 SUBTRACT(v2,v1,vTemp2); dCROSS(vTemp,=,m_vN,vTemp2); dNormalize3(vTemp); SUBTRACT(v0,v2,vTemp2); CONSTRUCTPLANE(plPlane,vTemp,dDOT(vTemp2,vTemp)); _cldClipPolyToPlane( avTempArray2, iTempCnt2, avTempArray1, iTempCnt1, plPlane ); // Plane p2 SUBTRACT(v0,v2,vTemp2); dCROSS(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 0) { fTempDepth = 0; } dVector3 vPntTmp; ADD(avTempArray2[i],v0,vPntTmp); #if 0 //#ifdef ORIG -- if to use conditional define, GenerateContact must be moved into #else dContactGeom* Contact = SAFECONTACT(m_iFlags, m_ContactGeoms, m_ctContacts, m_iStride); Contact->depth = -fTempDepth; SET(Contact->normal,m_vBestNormal); SET(Contact->pos,vPntTmp); Contact->g1 = Geom1; Contact->g2 = Geom2; Contact->side1 = TriIndex; Contact->side2 = -1; m_ctContacts++; #endif GenerateContact(m_iFlags, m_ContactGeoms, m_iStride, m_Geom1, m_Geom2, TriIndex, vPntTmp, m_vBestNormal, -fTempDepth, m_ctContacts); 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 0) { fTempDepth = 0; } // generate contact data dVector3 vPntTmp; ADD(avTempArray1[i],m_vHullBoxPos,vPntTmp); #if 0 //#ifdef ORIG -- if to use conditional define, GenerateContact must be moved into #else dContactGeom* Contact = SAFECONTACT(m_iFlags, m_ContactGeoms, m_ctContacts, m_iStride); Contact->depth = -fTempDepth; SET(Contact->normal,m_vBestNormal); SET(Contact->pos,vPntTmp); Contact->g1 = Geom1; Contact->g2 = Geom2; Contact->side1 = TriIndex; Contact->side2 = -1; m_ctContacts++; #endif GenerateContact(m_iFlags, m_ContactGeoms, m_iStride, m_Geom1, m_Geom2, TriIndex, vPntTmp, m_vBestNormal, -fTempDepth, m_ctContacts); if ((m_ctContacts | CONTACTS_UNIMPORTANT) == (m_iFlags & (NUMC_MASK | CONTACTS_UNIMPORTANT))) { break; } } //dAASSERT(m_ctContacts>0); } } // test one mesh triangle on intersection with given box void 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; } // 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; } _cldClipping(v0, v1, v2, TriIndex); } 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; } int sTrimeshBoxColliderData::TestCollisionForSingleTriangle(int ctContacts0, int Triint, dVector3 dv[3], bool &bOutFinishSearching) { // test this triangle _cldTestOneTriangle(dv[0],dv[1],dv[2],Triint); // fill-in tri index for generated contacts for (; ctContacts0 < m_ctContacts; ctContacts0++) { dContactGeom* pContact = SAFECONTACT(m_iFlags, m_ContactGeoms, ctContacts0, m_iStride); pContact->side1 = Triint; pContact->side2 = -1; } /* 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() */ bOutFinishSearching = ((m_ctContacts | CONTACTS_UNIMPORTANT) == (m_iFlags & (NUMC_MASK | CONTACTS_UNIMPORTANT))); return ctContacts0; } // 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 source hull position, orientation and half size const dMatrix3& mRotBox=*(const dMatrix3*)dGeomGetRotation(BoxGeom); const dVector3& vPosBox=*(const dVector3*)dGeomGetPosition(BoxGeom); // Make OBB OBB Box; Box.mCenter.x = vPosBox[0]; Box.mCenter.y = vPosBox[1]; Box.mCenter.z = vPosBox[2]; // It is a potential issue to explicitly cast to float // if custom width floating point type is introduced in OPCODE. // It is necessary to make a typedef and cast to it // (e.g. typedef float opc_float;) // However I'm not sure in what header it should be added. Box.mExtents.x = /*(float)*/cData.m_vBoxHalfSize[0]; Box.mExtents.y = /*(float)*/cData.m_vBoxHalfSize[1]; Box.mExtents.z = /*(float)*/cData.m_vBoxHalfSize[2]; Box.mRot.m[0][0] = /*(float)*/mRotBox[0]; Box.mRot.m[1][0] = /*(float)*/mRotBox[1]; Box.mRot.m[2][0] = /*(float)*/mRotBox[2]; Box.mRot.m[0][1] = /*(float)*/mRotBox[4]; Box.mRot.m[1][1] = /*(float)*/mRotBox[5]; Box.mRot.m[2][1] = /*(float)*/mRotBox[6]; Box.mRot.m[0][2] = /*(float)*/mRotBox[8]; Box.mRot.m[1][2] = /*(float)*/mRotBox[9]; Box.mRot.m[2][2] = /*(float)*/mRotBox[10]; Matrix4x4 amatrix; Matrix4x4 BoxMatrix = MakeMatrix(vPosBox, mRotBox, amatrix); Matrix4x4 InvBoxMatrix; InvertPRMatrix(InvBoxMatrix, BoxMatrix); // get destination hull position and orientation const dMatrix3& mRotMesh=*(const dMatrix3*)dGeomGetRotation(TriMesh); const dVector3& vPosMesh=*(const dVector3*)dGeomGetPosition(TriMesh); // TC results if (TriMesh->doBoxTC) { dxTriMesh::BoxTC* BoxTC = 0; for (int i = 0; i < TriMesh->BoxTCCache.size(); i++){ if (TriMesh->BoxTCCache[i].Geom == BoxGeom){ BoxTC = &TriMesh->BoxTCCache[i]; break; } } if (!BoxTC){ TriMesh->BoxTCCache.push(dxTriMesh::BoxTC()); BoxTC = &TriMesh->BoxTCCache[TriMesh->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->Data->BVTree, null, &MakeMatrix(vPosMesh, mRotMesh, amatrix)); } else { Collider.SetTemporalCoherence(false); Collider.Collide(BoxCache, Box, TriMesh->Data->BVTree, null, &MakeMatrix(vPosMesh, mRotMesh, amatrix)); } } 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->_OBBCollider; dQueryBTLPotentialCollisionTriangles(Collider, cData, TriMesh, BoxGeom, pccColliderCache->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->ArrayCallback != null){ TriMesh->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); int ctContacts0 = 0; // loop through all intersecting triangles for (int i = 0; i < TriCount; i++){ const int Triint = Triangles[i]; if (!Callback(TriMesh, BoxGeom, Triint)) continue; dVector3 dv[3]; FetchTriangle(TriMesh, Triint, vPosMesh, mRotMesh, dv); bool bFinishSearching; ctContacts0 = cData.TestCollisionForSingleTriangle(ctContacts0, 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; test_aabb.minX = BoxGeom->aabb[0]; test_aabb.maxX = BoxGeom->aabb[1]; test_aabb.minY = BoxGeom->aabb[2]; test_aabb.maxY = BoxGeom->aabb[3]; test_aabb.minZ = BoxGeom->aabb[4]; test_aabb.maxZ = 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); int ctContacts0 = 0; for(unsigned int i=0;ipos[j]; if (dDOT(diff, diff) < dEpsilon) { // same normal? if (dFabs(dDOT(in_Normal, Contact->normal)) > (REAL(1.0)-dEpsilon)) { if (in_Depth > Contact->depth) Contact->depth = in_Depth; duplicate = true; /* NOTE by Oleh_Derevenko: There may be a case when two normals are close to each other but not 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_trimesh.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); Contact->pos[0] = in_ContactPos[0]; Contact->pos[1] = in_ContactPos[1]; Contact->pos[2] = in_ContactPos[2]; Contact->pos[3] = 0.0; Contact->normal[0] = in_Normal[0]; Contact->normal[1] = in_Normal[1]; Contact->normal[2] = in_Normal[2]; Contact->normal[3] = 0.0; Contact->depth = in_Depth; Contact->g1 = in_g1; Contact->g2 = in_g2; Contact->side1 = TriIndex; Contact->side2 = -1; OutTriCount++; } while (false); } #endif // dTRIMESH_ENABLED ode-0.11.1/ode/src/odetls.h0000644000076400007640000001041111156775756012314 00000000000000/************************************************************************* * * * Thread local storage access stub for Open Dynamics Engine, * * Copyright (C) 2008 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 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)(size_t)CThreadLocalStorage::GetStorageValue(m_ahtkStorageKeys[tkTLSKind], OTI_DATA_ALLOCATION_FLAGS); } static void SignalDataAllocationFlags(EODETLSKIND tkTLSKind, unsigned uFlagsMask) { unsigned uCurrentFlags = (unsigned)(size_t)CThreadLocalStorage::UnsafeGetStorageValue(m_ahtkStorageKeys[tkTLSKind], OTI_DATA_ALLOCATION_FLAGS); CThreadLocalStorage::UnsafeSetStorageValue(m_ahtkStorageKeys[tkTLSKind], OTI_DATA_ALLOCATION_FLAGS, (tlsvaluetype)(size_t)(uCurrentFlags | uFlagsMask)); } static void DropDataAllocationFlags(EODETLSKIND tkTLSKind, unsigned uFlagsMask) { unsigned uCurrentFlags = (unsigned)(size_t)CThreadLocalStorage::UnsafeGetStorageValue(m_ahtkStorageKeys[tkTLSKind], OTI_DATA_ALLOCATION_FLAGS); CThreadLocalStorage::UnsafeSetStorageValue(m_ahtkStorageKeys[tkTLSKind], OTI_DATA_ALLOCATION_FLAGS, (tlsvaluetype)(size_t)(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_ ode-0.11.1/ode/src/fastltsolve.c0000644000076400007640000001160307344535357013362 00000000000000/* generated code, do not edit. */ #include "ode/matrix.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 lskip. * b is an n*1 matrix that contains the right hand side. * b is overwritten with x. * this processes blocks of 4. */ void dSolveL1T (const dReal *L, dReal *B, int n, int lskip1) { /* declare variables - Z matrix, p and q vectors, etc */ dReal Z11,m11,Z21,m21,Z31,m31,Z41,m41,p1,q1,p2,p3,p4,*ex; const dReal *ell; int lskip2,lskip3,i,j; /* special handling for L and B because we're solving L1 *transpose* */ L = L + (n-1)*(lskip1+1); B = B + n-1; lskip1 = -lskip1; /* compute lskip values */ lskip2 = 2*lskip1; lskip3 = 3*lskip1; /* compute all 4 x 1 blocks of X */ for (i=0; i <= n-4; i+=4) { /* compute all 4 x 1 block of X, from rows i..i+4-1 */ /* set the Z matrix to 0 */ Z11=0; Z21=0; Z31=0; Z41=0; ell = L - i; ex = B; /* the inner loop that computes outer products and adds them to Z */ for (j=i-4; j >= 0; j -= 4) { /* load p and q values */ p1=ell[0]; q1=ex[0]; p2=ell[-1]; p3=ell[-2]; p4=ell[-3]; /* compute outer product and add it to the Z matrix */ m11 = p1 * q1; m21 = p2 * q1; m31 = p3 * q1; m41 = p4 * q1; ell += lskip1; Z11 += m11; Z21 += m21; Z31 += m31; Z41 += m41; /* load p and q values */ p1=ell[0]; q1=ex[-1]; p2=ell[-1]; p3=ell[-2]; p4=ell[-3]; /* compute outer product and add it to the Z matrix */ m11 = p1 * q1; m21 = p2 * q1; m31 = p3 * q1; m41 = p4 * q1; ell += lskip1; Z11 += m11; Z21 += m21; Z31 += m31; Z41 += m41; /* load p and q values */ p1=ell[0]; q1=ex[-2]; p2=ell[-1]; p3=ell[-2]; p4=ell[-3]; /* compute outer product and add it to the Z matrix */ m11 = p1 * q1; m21 = p2 * q1; m31 = p3 * q1; m41 = p4 * q1; ell += lskip1; Z11 += m11; Z21 += m21; Z31 += m31; Z41 += m41; /* load p and q values */ p1=ell[0]; q1=ex[-3]; p2=ell[-1]; p3=ell[-2]; p4=ell[-3]; /* compute outer product and add it to the Z matrix */ m11 = p1 * q1; m21 = p2 * q1; m31 = p3 * q1; m41 = p4 * q1; ell += lskip1; ex -= 4; Z11 += m11; Z21 += m21; Z31 += m31; Z41 += m41; /* end of inner loop */ } /* compute left-over iterations */ j += 4; for (; j > 0; j--) { /* load p and q values */ p1=ell[0]; q1=ex[0]; p2=ell[-1]; p3=ell[-2]; p4=ell[-3]; /* compute outer product and add it to the Z matrix */ m11 = p1 * q1; m21 = p2 * q1; m31 = p3 * q1; m41 = p4 * q1; ell += lskip1; ex -= 1; Z11 += m11; Z21 += m21; Z31 += m31; Z41 += m41; } /* finish computing the X(i) block */ Z11 = ex[0] - Z11; ex[0] = Z11; p1 = ell[-1]; Z21 = ex[-1] - Z21 - p1*Z11; ex[-1] = Z21; p1 = ell[-2]; p2 = ell[-2+lskip1]; Z31 = ex[-2] - Z31 - p1*Z11 - p2*Z21; ex[-2] = Z31; p1 = ell[-3]; p2 = ell[-3+lskip1]; p3 = ell[-3+lskip2]; Z41 = ex[-3] - Z41 - p1*Z11 - p2*Z21 - p3*Z31; ex[-3] = Z41; /* end of outer loop */ } /* compute rows at end that are not a multiple of block size */ for (; i < n; i++) { /* compute all 1 x 1 block of X, from rows i..i+1-1 */ /* set the Z matrix to 0 */ Z11=0; ell = L - i; ex = B; /* the inner loop that computes outer products and adds them to Z */ for (j=i-4; j >= 0; j -= 4) { /* load p and q values */ p1=ell[0]; q1=ex[0]; /* compute outer product and add it to the Z matrix */ m11 = p1 * q1; ell += lskip1; Z11 += m11; /* load p and q values */ p1=ell[0]; q1=ex[-1]; /* compute outer product and add it to the Z matrix */ m11 = p1 * q1; ell += lskip1; Z11 += m11; /* load p and q values */ p1=ell[0]; q1=ex[-2]; /* compute outer product and add it to the Z matrix */ m11 = p1 * q1; ell += lskip1; Z11 += m11; /* load p and q values */ p1=ell[0]; q1=ex[-3]; /* compute outer product and add it to the Z matrix */ m11 = p1 * q1; ell += lskip1; ex -= 4; Z11 += m11; /* end of inner loop */ } /* compute left-over iterations */ j += 4; for (; j > 0; j--) { /* load p and q values */ p1=ell[0]; q1=ex[0]; /* compute outer product and add it to the Z matrix */ m11 = p1 * q1; ell += lskip1; ex -= 1; Z11 += m11; } /* finish computing the X(i) block */ Z11 = ex[0] - Z11; ex[0] = Z11; } } ode-0.11.1/ode/src/odeou.h0000644000076400007640000000521311005162546012115 00000000000000/************************************************************************* * * * OU library interface file for Open Dynamics Engine, * * Copyright (C) 2008 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 #include #include #include #include #include #include #if dATOMICS_ENABLED #include #include #endif #if dTLS_ENABLED #include #endif using namespace _OU_NAMESPACE; class COdeOu { public: static bool DoOUCustomizations(); static void UndoOUCustomizations(); #if dATOMICS_ENABLED static bool InitializeAtomics() { return InitializeAtomicAPI(); } static void FinalizeAtomics() { FinalizeAtomicAPI(); } #endif }; #endif // dOU_ENABLED #endif // _ODE_ODEOU_H_ ode-0.11.1/ode/src/odeinit.cpp0000644000076400007640000002405411156775756013020 00000000000000/************************************************************************* * * * 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 #include #include #include "config.h" #include "collision_kernel.h" #include "collision_trimesh_internal.h" #include "odetls.h" #include "odeou.h" //**************************************************************************** // Initialization tracking variables static unsigned int g_uiODEInitCounter = 0; static unsigned int g_uiODEInitModes = 0; 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; } } #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(); } } #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; } #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); #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; #endif 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 dTRIMESH_ENABLED && dTRIMESH_OPCODE if (!Opcode::InitOpcode()) { break; } #endif #if dTRIMESH_ENABLED && dTRIMESH_GIMPACT gimpact_init(); #endif dInitColliders(); } bResult = true; } while (false); if (!bResult) { #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 } #if dTLS_ENABLED EODETLSKIND tkTLSKindToFinalize = g_atkTLSKindsByInitMode[imInitMode]; COdeTls::Finalize(tkTLSKindToFinalize); #endif if (!bAnyModeStillInitialized) { #if dATOMICS_ENABLED COdeOu::FinalizeAtomics(); #endif #if dOU_ENABLED COdeOu::UndoOUCustomizations(); #endif } } //**************************************************************************** // initialization and shutdown routines - allocate and initialize data, // cleanup before exiting void dInitODE() { int bInitResult = dInitODE2(0); dIASSERT(bInitResult); dVARIABLEUSED(bInitResult); int ibAllocResult = dAllocateODEDataForThread(dAllocateMaskAll); dIASSERT(ibAllocResult); dVARIABLEUSED(ibAllocResult); } int dInitODE2(unsigned int uiInitFlags/*=0*/) { 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; } int dAllocateODEDataForThread(unsigned int uiAllocateFlags) { dIASSERT(g_uiODEInitCounter != 0); // Call dInitODE2 first 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; } void dCleanupODEAllDataForThread() { dIASSERT(g_uiODEInitCounter != 0); // Call dInitODE2 first or delay dCloseODE until all threads exit #if dTLS_ENABLED COdeTls::CleanupForThread(); #endif } void dCloseODE() { dIASSERT(g_uiODEInitCounter != 0); // dCloseODE must not be called without dInitODE2 or if dInitODE2 fails 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); } } } ode-0.11.1/ode/src/array.cpp0000644000076400007640000000522310765152110012452 00000000000000/************************************************************************* * * * 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 #include "config.h" #include #include #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; } ode-0.11.1/ode/src/convex.cpp0000644000076400007640000014266311165470224012654 00000000000000/************************************************************************* * * * 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 #include #include #include #include #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, dReal *_planes, unsigned int _planecount, dReal *_points, unsigned int _pointcount, 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. unsigned int *points_in_poly=polygons; unsigned int *index=polygons+1; for(unsigned int i=0;i 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() { unsigned int *points_in_poly=polygons; unsigned int *index=polygons+1; if (edges!=NULL) delete[] edges; edgecount = 0; edge e; bool isinset; for(unsigned int i=0;i Arcs,std::vector 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 A; A.reserve(edgecount); for(unsigned int i=0;iGetFacesSharedByEdge(i,A[i].normals); A[i].edge = i; } std::vector S; S.reserve(pointcount); for(unsigned int i=0;iGetFacesSharedByVertex(i,S[i].normals); S[i].vertex=i; } this->tree = CreateNode(A,S); } void dxConvex::GetFacesSharedByVertex(int i, std::vector f) { } void dxConvex::GetFacesSharedByEdge(int i, int* f) { } void dxConvex::GetFaceNormal(int i, dVector3 normal) { } #endif dGeomID dCreateConvex (dSpaceID space,dReal *_planes,unsigned int _planecount, dReal *_points, unsigned int _pointcount, unsigned int *_polygons) { //fprintf(stdout,"dxConvex dCreateConvex\n"); return new dxConvex(space,_planes, _planecount, _points, _pointcount, _polygons); } void dGeomSetConvex (dGeomID g,dReal *_planes,unsigned int _planecount, dReal *_points, unsigned int _pointcount, 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] - dDOT(p,a)) / dDOT(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 = dDOT(Direction1 , Direction1); dReal b = dDOT(Direction1 , Direction2); dReal c = dDOT(Direction2 , Direction2); dReal d = dDOT(Direction1 , w); dReal e = dDOT(Direction2 , w); dReal denominator = (a*c)-(b*b); if(denominator==0.0f) { return false; } t = ((a*e)-(b*d))/denominator; return true; } /*! \brief Clamp n to lie within the range [min, max] */ inline float Clamp(float n, float min, float max) { if (n < min) return min; if (n > max) return max; return n; } /*! \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 float 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 float s; float 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]}; float a = dDOT(d1, d1); float e = dDOT(d2, d2); float f = dDOT(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 (c1[0] - c2[0])*(c1[0] - c2[0])+ (c1[1] - c2[1])*(c1[1] - c2[1])+ (c1[2] - c2[2])*(c1[2] - c2[2]); } 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 = Clamp(t, 0.0f, 1.0f); } else { float c = dDOT(d1, r); if (e <= dEpsilon) { // Second segment degenerates into a point t = 0.0f; s = Clamp(-c / a, 0.0f, 1.0f); // t = 0 => s = (b*t - c) / a = -c / a } else { // The general non degenerate case starts here float b = dDOT(d1, d2); float 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 = Clamp((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 = Clamp(-c / a, 0.0f, 1.0f); } else if (t > 1.0f) { t = 1.0f; s = Clamp((b - c) / a, 0.0f, 1.0f); } #else float tnom = b*s + f; if (tnom < 0.0f) { t = 0.0f; s = Clamp(-c / a, 0.0f, 1.0f); } else if (tnom > e) { t = 1.0f; s = Clamp((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; return (c1[0] - c2[0])*(c1[0] - c2[0])+ (c1[1] - c2[1])*(c1[1] - c2[1])+ (c1[2] - c2[2])*(c1[2] - c2[2]); } #if 0 float tnom = b*s + f; if (tnom < 0.0f) { t = 0.0f; s = Clamp(-c / a, 0.0f, 1.0f); } else if (tnom > e) { t = 1.0f; s = Clamp((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 dCROSS(d,=,p1,p2); // If d is (near) zero, the planes are parallel (and separated) // or coincident, so they're not considered intersecting dReal denom = dDOT(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 dCROSS(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;iplanecount;++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, unsigned int *polygon, 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. size_t pointcount=polygon[0]; dVector3 a; dVector3 b; dVector3 c; dVector3 ab; dVector3 ac; dVector3 ap; dVector3 bp; dReal d1; dReal d2; dReal d3; dReal d4; dReal vc; polygon++; // skip past pointcount for(size_t i=0;ifinal_posr->R,&convex->points[(polygon[i]*3)]); a[0]=convex->final_posr->pos[0]+a[0]; a[1]=convex->final_posr->pos[1]+a[1]; a[2]=convex->final_posr->pos[2]+a[2]; dMULTIPLY0_331 (b,convex->final_posr->R, &convex->points[(polygon[(i+1)%pointcount]*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]; dMULTIPLY0_331 (c,convex->final_posr->R, &convex->points[(polygon[(i+2)%pointcount]*3)]); c[0]=convex->final_posr->pos[0]+c[0]; c[1]=convex->final_posr->pos[1]+c[1]; c[2]=convex->final_posr->pos[2]+c[2]; ab[0] = b[0] - a[0]; ab[1] = b[1] - a[1]; ab[2] = b[2] - a[2]; ac[0] = c[0] - a[0]; ac[1] = c[1] - a[1]; ac[2] = c[2] - a[2]; ap[0] = p[0] - a[0]; ap[1] = p[1] - a[1]; ap[2] = p[2] - a[2]; d1 = dDOT(ab,ap); d2 = dDOT(ac,ap); if (d1 <= 0.0 && d2 <= 0.0) { out[0]=a[0]; out[1]=a[1]; out[2]=a[2]; return false; } bp[0] = p[0] - b[0]; bp[1] = p[1] - b[1]; bp[2] = p[2] - b[2]; d3 = dDOT(ab,bp); d4 = dDOT(ac,bp); if (d3 >= 0.0f && d4 <= d3) { out[0]=b[0]; out[1]=b[1]; out[2]=b[2]; return false; } vc = d1*d4 - d3*d2; if (vc < 0.0 && d1 > 0.0 && d3 < 0.0) { dReal v = d1 / (d1 - d3); out[0] = a[0] + (ab[0]*v); out[1] = a[1] + (ab[1]*v); out[2] = a[2] + (ab[2]*v); 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;ipointcount;++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; 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;iplanecount;++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(distradius) { // if we get here we know the sphere surface penetrates // the plane if(IsPointInPolygon(Sphere->final_posr->pos,pPoly,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 = dDOT(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=dDOT(point,axis)-axis[3];//(*) if(valuemax) { 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;iR,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]; unsigned int* pPoly=cvx2.polygons; for(size_t j=0;jR,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,&cvx2,q)) { target->depth = dInfinity; for(size_t k=0;kR,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)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;iR,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(max2R,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;jR,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]; dCROSS(plane,=,e1,e2); if(dDOT(plane,plane)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 = dDOT(nis,ccso.g2->planes); for(unsigned int i=1;iplanecount;++i) { Dot = dDOT(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 = dDOT(dics,cvx.planes); for(unsigned int i=1;iSavedDot) { 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; ccso.min_depth=dInfinity; // Min not min at all ccso.depth_type=0; // no type // precompute distance vector ccso.dist[0] = cvx2.final_posr->pos[0]-cvx1.final_posr->pos[0]; ccso.dist[1] = cvx2.final_posr->pos[1]-cvx1.final_posr->pos[1]; ccso.dist[2] = cvx2.final_posr->pos[2]-cvx1.final_posr->pos[2]; 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; unsigned int* pIncidentPoly; unsigned int* pIncidentPoints; unsigned int reference_side; unsigned int* pReferencePoly; 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); dist[0]=-dist[0]; dist[1]=-dist[1]; dist[2]=-dist[2]; 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;iR,&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;iR,&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;j0) { 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) { dVector3Copy(p,SAFECONTACT(flags, contact, contacts, skip)->pos); dVector3Copy(rplane,SAFECONTACT(flags, contact, contacts, skip)->normal); SAFECONTACT(flags, contact, contacts, skip)->g1=&cvx1; SAFECONTACT(flags, contact, contacts, skip)->g2=&cvx2; SAFECONTACT(flags, contact, contacts, skip)->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) { dVector3Copy(i1,SAFECONTACT(flags, contact, contacts, skip)->pos); dVector3Copy(rplane,SAFECONTACT(flags, contact, contacts, skip)->normal); SAFECONTACT(flags, contact, contacts, skip)->g1=&cvx1; SAFECONTACT(flags, contact, contacts, skip)->g2=&cvx2; SAFECONTACT(flags, contact, contacts, skip)->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;iR,&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=0){out = true;break;}; } if(!out) { // check that the point is not a duplicate outside = false; for(int j=0;jpos[0]==i1[0])&& (SAFECONTACT(flags, contact, j, skip)->pos[1]==i1[1])&& (SAFECONTACT(flags, contact, j, skip)->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) { dVector3Copy(i1,SAFECONTACT(flags, contact, contacts, skip)->pos); dVector3Copy(rplane,SAFECONTACT(flags, contact, contacts, skip)->normal); SAFECONTACT(flags, contact, contacts, skip)->g1=&cvx1; SAFECONTACT(flags, contact, contacts, skip)->g2=&cvx2; SAFECONTACT(flags, contact, contacts, skip)->depth=d; ++contacts; if (contacts==maxc) return contacts; } } } } } else if(ccso.depth_type==2) // edge-edge { dVector3 c1,c2; //float s,t; SAFECONTACT(flags, contact, contacts, skip)->depth = dSqrt(ClosestPointBetweenSegments(ccso.e1a,ccso.e1b,ccso.e2a,ccso.e2b,c1,c2)); SAFECONTACT(flags, contact, contacts, skip)->g1=&cvx1; SAFECONTACT(flags, contact, contacts, skip)->g2=&cvx2; dVector3Copy(c1,SAFECONTACT(flags, contact, contacts, skip)->pos); SAFECONTACT(flags, contact, contacts, skip)->normal[0] = c2[0]-c1[0]; SAFECONTACT(flags, contact, contacts, skip)->normal[1] = c2[1]-c1[1]; SAFECONTACT(flags, contact, contacts, skip)->normal[2] = c2[2]-c1[2]; dNormalize3(SAFECONTACT(flags, contact, contacts, skip)->normal); 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;iplanecount;++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,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; // // Compute some useful info // flag = 0; // Assume start point is behind all planes. for ( unsigned int i = 0; i < convex->planecount; ++i ) { // Alias this plane. dReal* plane = convex->planes + ( i * 4 ); // If alpha >= 0 then start point is outside of plane. alpha = dDOT( plane, ray->final_posr->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. dReal* plane = convex->planes + ( i * 4 ); // If alpha >= 0 then point is outside of plane. alpha = nsign * ( dDOT( plane, ray->final_posr->pos ) - plane[3] ); // Compute [ plane-normal DOT ray-normal ], (/flip) beta = dDOT13( plane, ray->final_posr->R+2 ) * 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->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]; flag = 0; // For all _other_ planes. for ( unsigned int j = 0; j < convex->planecount; ++j ) { if ( i == j ) continue; // Skip self. // Alias this plane. dReal* planej = convex->planes + ( j * 4 ); // If beta >= 0 then start is outside of plane. beta = dDOT( planej, contact->pos ) - plane[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? return ( contact->depth <= ray->length ); } #endif //<-- Convex Collision ode-0.11.1/ode/src/collision_space_internal.h0000644000076400007640000000647310414557751016066 00000000000000/************************************************************************* * * * 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) #define CHECK_NOT_LOCKED(space) \ dUASSERT ((space)==0 || (space)->lock_count==0, \ "invalid operation for locked space"); // 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 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 ode-0.11.1/ode/src/collision_trimesh_colliders.h0000644000076400007640000000522311001077376016573 00000000000000/************************************************************************* * * * 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); 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_ ode-0.11.1/ode/src/collision_trimesh_opcode.cpp0000644000076400007640000005547611156775756016460 00000000000000/************************************************************************* * * * 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 #include #include #include #include "collision_util.h" #include "collision_trimesh_internal.h" #if dTRIMESH_ENABLED #if dTRIMESH_OPCODE void TrimeshCollidersCache::InitOPCODECaches() { _RayCollider.SetDestination(&Faces); /* -- not used _PlanesCollider.SetTemporalCoherence(true); */ _SphereCollider.SetTemporalCoherence(true); _SphereCollider.SetPrimitiveTests(false); _OBBCollider.SetTemporalCoherence(true); // no first-contact test (i.e. return full contact info) _AABBTreeCollider.SetFirstContact( false ); // temporal coherence only works with "first contact" tests _AABBTreeCollider.SetTemporalCoherence(false); // Perform full BV-BV tests (true) or SAT-lite tests (false) _AABBTreeCollider.SetFullBoxBoxTest( true ); // Perform full Primitive-BV tests (true) or SAT-lite tests (false) _AABBTreeCollider.SetFullPrimBoxTest( true ); const char* msg; if ((msg =_AABBTreeCollider.ValidateSettings())) dDebug (d_ERR_UASSERT, msg, " (%s:%d)", __FILE__,__LINE__); /* -- not used _LSSCollider.SetTemporalCoherence(false); _LSSCollider.SetPrimitiveTests(false); _LSSCollider.SetFirstContact(false); */ } // Trimesh data dxTriMeshData::dxTriMeshData() : UseFlags( NULL ) { #if !dTRIMESH_ENABLED dUASSERT(false, "dTRIMESH_ENABLED is not defined. Trimesh geoms will not work"); #endif } dxTriMeshData::~dxTriMeshData() { if ( UseFlags ) delete [] UseFlags; } void dxTriMeshData::Build(const void* Vertices, int VertexStide, int VertexCount, const void* Indices, int IndexCount, int TriStride, const void* in_Normals, bool Single) { #if dTRIMESH_ENABLED Mesh.SetNbTriangles(IndexCount / 3); Mesh.SetNbVertices(VertexCount); Mesh.SetPointers((IndexedTriangle*)Indices, (Point*)Vertices); Mesh.SetStrides(TriStride, VertexStide); Mesh.SetSingle(Single); // Build tree BuildSettings Settings; // recommended in Opcode User Manual //Settings.mRules = SPLIT_COMPLETE | SPLIT_SPLATTERPOINTS | SPLIT_GEOMCENTER; // used in ODE, why? //Settings.mRules = SPLIT_BEST_AXIS; // best compromise? Settings.mRules = SPLIT_BEST_AXIS | SPLIT_SPLATTER_POINTS | SPLIT_GEOM_CENTER; OPCODECREATE TreeBuilder; TreeBuilder.mIMesh = &Mesh; TreeBuilder.mSettings = Settings; TreeBuilder.mNoLeaf = true; TreeBuilder.mQuantized = false; TreeBuilder.mKeepOriginal = false; TreeBuilder.mCanRemap = false; BVTree.Build(TreeBuilder); // compute model space AABB dVector3 AABBMax, AABBMin; AABBMax[0] = AABBMax[1] = AABBMax[2] = (dReal) -dInfinity; AABBMin[0] = AABBMin[1] = AABBMin[2] = (dReal) dInfinity; if( Single ) { const char* verts = (const char*)Vertices; for( int i = 0; i < VertexCount; ++i ) { const float* v = (const float*)verts; if( v[0] > AABBMax[0] ) AABBMax[0] = v[0]; if( v[1] > AABBMax[1] ) AABBMax[1] = v[1]; if( v[2] > AABBMax[2] ) AABBMax[2] = v[2]; if( v[0] < AABBMin[0] ) AABBMin[0] = v[0]; if( v[1] < AABBMin[1] ) AABBMin[1] = v[1]; if( v[2] < AABBMin[2] ) AABBMin[2] = v[2]; verts += VertexStide; } } else { const char* verts = (const char*)Vertices; for( int i = 0; i < VertexCount; ++i ) { const double* v = (const double*)verts; if( v[0] > AABBMax[0] ) AABBMax[0] = (dReal) v[0]; if( v[1] > AABBMax[1] ) AABBMax[1] = (dReal) v[1]; if( v[2] > AABBMax[2] ) AABBMax[2] = (dReal) v[2]; if( v[0] < AABBMin[0] ) AABBMin[0] = (dReal) v[0]; if( v[1] < AABBMin[1] ) AABBMin[1] = (dReal) v[1]; if( v[2] < AABBMin[2] ) AABBMin[2] = (dReal) v[2]; verts += VertexStide; } } AABBCenter[0] = (AABBMin[0] + AABBMax[0]) * REAL(0.5); AABBCenter[1] = (AABBMin[1] + AABBMax[1]) * REAL(0.5); AABBCenter[2] = (AABBMin[2] + AABBMax[2]) * REAL(0.5); AABBExtents[0] = AABBMax[0] - AABBCenter[0]; AABBExtents[1] = AABBMax[1] - AABBCenter[1]; AABBExtents[2] = AABBMax[2] - AABBCenter[2]; // user data (not used by OPCODE) Normals = (dReal *) in_Normals; UseFlags = 0; #endif // dTRIMESH_ENABLED } struct EdgeRecord { int VertIdx1; // Index into vertex array for this edges vertices int VertIdx2; int TriIdx; // Index into triangle array for triangle this edge belongs to uint8 EdgeFlags; uint8 Vert1Flags; uint8 Vert2Flags; bool Concave; }; // Edge comparison function for qsort static int EdgeCompare(const void* edge1, const void* edge2) { EdgeRecord* e1 = (EdgeRecord*)edge1; EdgeRecord* e2 = (EdgeRecord*)edge2; if (e1->VertIdx1 == e2->VertIdx1) return e1->VertIdx2 - e2->VertIdx2; else return e1->VertIdx1 - e2->VertIdx1; } void SetupEdge(EdgeRecord* edge, int edgeIdx, int triIdx, const dTriIndex* vertIdxs) { if (edgeIdx == 0) { edge->EdgeFlags = dxTriMeshData::kEdge0; edge->Vert1Flags = dxTriMeshData::kVert0; edge->Vert2Flags = dxTriMeshData::kVert1; edge->VertIdx1 = vertIdxs[0]; edge->VertIdx2 = vertIdxs[1]; } else if (edgeIdx == 1) { edge->EdgeFlags = dxTriMeshData::kEdge1; edge->Vert1Flags = dxTriMeshData::kVert1; edge->Vert2Flags = dxTriMeshData::kVert2; edge->VertIdx1 = vertIdxs[1]; edge->VertIdx2 = vertIdxs[2]; } else if (edgeIdx == 2) { edge->EdgeFlags = dxTriMeshData::kEdge2; edge->Vert1Flags = dxTriMeshData::kVert2; edge->Vert2Flags = dxTriMeshData::kVert0; edge->VertIdx1 = vertIdxs[2]; edge->VertIdx2 = vertIdxs[0]; } // Make sure vert index 1 is less than index 2 (for easier sorting) if (edge->VertIdx1 > edge->VertIdx2) { unsigned int tempIdx = edge->VertIdx1; edge->VertIdx1 = edge->VertIdx2; edge->VertIdx2 = tempIdx; uint8 tempFlags = edge->Vert1Flags; edge->Vert1Flags = edge->Vert2Flags; edge->Vert2Flags = tempFlags; } edge->TriIdx = triIdx; edge->Concave = false; } #if dTRIMESH_ENABLED // Get the vertex opposite this edge in the triangle inline Point GetOppositeVert(EdgeRecord* edge, const Point* vertices[]) { if ((edge->Vert1Flags == dxTriMeshData::kVert0 && edge->Vert2Flags == dxTriMeshData::kVert1) || (edge->Vert1Flags == dxTriMeshData::kVert1 && edge->Vert2Flags == dxTriMeshData::kVert0)) { return *vertices[2]; } else if ((edge->Vert1Flags == dxTriMeshData::kVert1 && edge->Vert2Flags == dxTriMeshData::kVert2) || (edge->Vert1Flags == dxTriMeshData::kVert2 && edge->Vert2Flags == dxTriMeshData::kVert1)) { return *vertices[0]; } else return *vertices[1]; } #endif // dTRIMESH_ENABLED void dxTriMeshData::Preprocess() { #if dTRIMESH_ENABLED // If this mesh has already been preprocessed, exit if (UseFlags) return; udword numTris = Mesh.GetNbTriangles(); udword numEdges = numTris * 3; UseFlags = new uint8[numTris]; memset(UseFlags, 0, sizeof(uint8) * numTris); EdgeRecord* records = new EdgeRecord[numEdges]; // Make a list of every edge in the mesh const IndexedTriangle* tris = Mesh.GetTris(); for (unsigned int i = 0; i < numTris; i++) { SetupEdge(&records[i*3], 0, i, tris->mVRef); SetupEdge(&records[i*3+1], 1, i, tris->mVRef); SetupEdge(&records[i*3+2], 2, i, tris->mVRef); tris = (const IndexedTriangle*)(((uint8*)tris) + Mesh.GetTriStride()); } // Sort the edges, so the ones sharing the same verts are beside each other qsort(records, numEdges, sizeof(EdgeRecord), EdgeCompare); // Go through the sorted list of edges and flag all the edges and vertices that we need to use for (unsigned int i = 0; i < numEdges; i++) { EdgeRecord* rec1 = &records[i]; EdgeRecord* rec2 = 0; if (i < numEdges - 1) rec2 = &records[i+1]; if (rec2 && rec1->VertIdx1 == rec2->VertIdx1 && rec1->VertIdx2 == rec2->VertIdx2) { VertexPointers vp; ConversionArea vc; Mesh.GetTriangle(vp, rec1->TriIdx, vc); // Get the normal of the first triangle Point triNorm = (*vp.Vertex[2] - *vp.Vertex[1]) ^ (*vp.Vertex[0] - *vp.Vertex[1]); triNorm.Normalize(); // Get the vert opposite this edge in the first triangle Point oppositeVert1 = GetOppositeVert(rec1, vp.Vertex); // Get the vert opposite this edge in the second triangle Mesh.GetTriangle(vp, rec2->TriIdx, vc); Point oppositeVert2 = GetOppositeVert(rec2, vp.Vertex); float dot = triNorm.Dot((oppositeVert2 - oppositeVert1).Normalize()); // We let the dot threshold for concavity get slightly negative to allow for rounding errors static const float kConcaveThresh = -0.000001f; // This is a concave edge, leave it for the next pass if (dot >= kConcaveThresh) rec1->Concave = true; // If this is a convex edge, mark its vertices and edge as used else UseFlags[rec1->TriIdx] |= rec1->Vert1Flags | rec1->Vert2Flags | rec1->EdgeFlags; // Skip the second edge i++; } // This is a boundary edge else { UseFlags[rec1->TriIdx] |= rec1->Vert1Flags | rec1->Vert2Flags | rec1->EdgeFlags; } } // Go through the list once more, and take any edge we marked as concave and // clear it's vertices flags in any triangles they're used in for (unsigned int i = 0; i < numEdges; i++) { EdgeRecord& er = records[i]; if (er.Concave) { for (unsigned int j = 0; j < numEdges; j++) { EdgeRecord& curER = records[j]; if (curER.VertIdx1 == er.VertIdx1 || curER.VertIdx1 == er.VertIdx2) UseFlags[curER.TriIdx] &= ~curER.Vert1Flags; if (curER.VertIdx2 == er.VertIdx1 || curER.VertIdx2 == er.VertIdx2) UseFlags[curER.TriIdx] &= ~curER.Vert2Flags; } } } delete [] records; #endif // dTRIMESH_ENABLED } dTriMeshDataID dGeomTriMeshDataCreate(){ return new dxTriMeshData(); } void dGeomTriMeshDataDestroy(dTriMeshDataID g){ delete g; } void dGeomTriMeshSetLastTransform( dxGeom* g, dMatrix4 last_trans ) { dAASSERT(g) dUASSERT(g->type == dTriMeshClass, "geom not trimesh"); for (int i=0; i<16; i++) (((dxTriMesh*)g)->last_trans)[ i ] = last_trans[ i ]; return; } dReal* dGeomTriMeshGetLastTransform( dxGeom* g ) { dAASSERT(g) dUASSERT(g->type == dTriMeshClass, "geom not trimesh"); return (dReal*)(((dxTriMesh*)g)->last_trans); } void dGeomTriMeshDataSet(dTriMeshDataID g, int data_id, void* in_data) { dUASSERT(g, "argument not trimesh data"); switch (data_id) { case TRIMESH_FACE_NORMALS: g->Normals = (dReal *) in_data; break; default: dUASSERT(data_id, "invalid data type"); break; } return; } void* dGeomTriMeshDataGet(dTriMeshDataID g, int data_id) { dUASSERT(g, "argument not trimesh data"); switch (data_id) { case TRIMESH_FACE_NORMALS: return (void *) g->Normals; break; default: dUASSERT(data_id, "invalid data type"); break; } return NULL; } void dGeomTriMeshDataBuildSingle1(dTriMeshDataID g, const void* Vertices, int VertexStride, int VertexCount, const void* Indices, int IndexCount, int TriStride, const void* Normals) { dUASSERT(g, "argument not trimesh data"); g->Build(Vertices, VertexStride, VertexCount, Indices, IndexCount, TriStride, Normals, true); } 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, (void*)NULL); } void dGeomTriMeshDataBuildDouble1(dTriMeshDataID g, const void* Vertices, int VertexStride, int VertexCount, const void* Indices, int IndexCount, int TriStride, const void* Normals) { dUASSERT(g, "argument not trimesh data"); g->Build(Vertices, VertexStride, VertexCount, Indices, IndexCount, TriStride, Normals, false); } 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); } 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 } void dGeomTriMeshDataBuildSimple(dTriMeshDataID g, const dReal* Vertices, int VertexCount, const dTriIndex* Indices, int IndexCount) { dGeomTriMeshDataBuildSimple1(g, Vertices, VertexCount, Indices, IndexCount, (const int*)NULL); } void dGeomTriMeshDataPreprocess(dTriMeshDataID g) { dUASSERT(g, "argument not trimesh data"); g->Preprocess(); } void dGeomTriMeshDataGetBuffer(dTriMeshDataID g, unsigned char** buf, int* bufLen) { dUASSERT(g, "argument not trimesh data"); #if dTRIMESH_ENABLED *buf = g->UseFlags; *bufLen = g->Mesh.GetNbTriangles(); #endif // dTRIMESH_ENABLED } void dGeomTriMeshDataSetBuffer(dTriMeshDataID g, unsigned char* buf) { dUASSERT(g, "argument not trimesh data"); g->UseFlags = buf; } dxTriMesh::dxTriMesh(dSpaceID Space, dTriMeshDataID Data) : dxGeom(Space, 1) { type = dTriMeshClass; Callback = NULL; ArrayCallback = NULL; RayCallback = NULL; TriMergeCallback = NULL; // Not initialized in dCreateTriMesh this->Data = Data; /* TC has speed/space 'issues' that don't make it a clear win by default on spheres/boxes. */ this->doSphereTC = false; this->doBoxTC = false; this->doCapsuleTC = false; for (int i=0; i<16; i++) last_trans[i] = REAL( 0.0 ); } dxTriMesh::~dxTriMesh(){ // } // Cleanup for allocations when shutting down ODE /*extern */void opcode_collider_cleanup() { #if !dTLS_ENABLED #if dTRIMESH_ENABLED // Clear TC caches TrimeshCollidersCache *pccColliderCache = GetTrimeshCollidersCache(0); pccColliderCache->Faces.Empty(); pccColliderCache->defaultSphereCache.TouchedPrimitives.Empty(); pccColliderCache->defaultBoxCache.TouchedPrimitives.Empty(); pccColliderCache->defaultCapsuleCache.TouchedPrimitives.Empty(); #endif // dTRIMESH_ENABLED #endif // dTLS_ENABLED } void dxTriMesh::ClearTCCache() { #if dTRIMESH_ENABLED /* 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 = SphereTCCache.size(); for( i = 0; i < n; ++i ) { SphereTCCache[i].~SphereTC(); } SphereTCCache.setSize(0); n = BoxTCCache.size(); for( i = 0; i < n; ++i ) { BoxTCCache[i].~BoxTC(); } BoxTCCache.setSize(0); n = CapsuleTCCache.size(); for( i = 0; i < n; ++i ) { CapsuleTCCache[i].~CapsuleTC(); } CapsuleTCCache.setSize(0); #endif // dTRIMESH_ENABLED } int dxTriMesh::AABBTest(dxGeom* g, dReal aabb[6]){ return 1; } void dxTriMesh::computeAABB() { const dxTriMeshData* d = Data; dVector3 c; const dMatrix3& R = final_posr->R; const dVector3& pos = final_posr->pos; dMULTIPLY0_331( c, R, d->AABBCenter ); dReal xrange = dFabs(R[0] * Data->AABBExtents[0]) + dFabs(R[1] * Data->AABBExtents[1]) + dFabs(R[2] * Data->AABBExtents[2]); dReal yrange = dFabs(R[4] * Data->AABBExtents[0]) + dFabs(R[5] * Data->AABBExtents[1]) + dFabs(R[6] * Data->AABBExtents[2]); dReal zrange = dFabs(R[8] * Data->AABBExtents[0]) + dFabs(R[9] * Data->AABBExtents[1]) + dFabs(R[10] * Data->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 dxTriMeshData::UpdateData() { #if dTRIMESH_ENABLED BVTree.Refit(); #endif // dTRIMESH_ENABLED } dGeomID dCreateTriMesh(dSpaceID space, dTriMeshDataID Data, dTriCallback* Callback, dTriArrayCallback* ArrayCallback, dTriRayCallback* RayCallback) { dxTriMesh* Geom = new dxTriMesh(space, Data); Geom->Callback = Callback; Geom->ArrayCallback = ArrayCallback; Geom->RayCallback = RayCallback; return Geom; } void dGeomTriMeshSetCallback(dGeomID g, dTriCallback* Callback) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); ((dxTriMesh*)g)->Callback = Callback; } dTriCallback* dGeomTriMeshGetCallback(dGeomID g) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); return ((dxTriMesh*)g)->Callback; } void dGeomTriMeshSetArrayCallback(dGeomID g, dTriArrayCallback* ArrayCallback) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); ((dxTriMesh*)g)->ArrayCallback = ArrayCallback; } dTriArrayCallback* dGeomTriMeshGetArrayCallback(dGeomID g) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); return ((dxTriMesh*)g)->ArrayCallback; } void dGeomTriMeshSetRayCallback(dGeomID g, dTriRayCallback* Callback) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); ((dxTriMesh*)g)->RayCallback = Callback; } dTriRayCallback* dGeomTriMeshGetRayCallback(dGeomID g) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); return ((dxTriMesh*)g)->RayCallback; } void dGeomTriMeshSetTriMergeCallback(dGeomID g, dTriTriMergeCallback* Callback) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); ((dxTriMesh*)g)->TriMergeCallback = Callback; } dTriTriMergeCallback* dGeomTriMeshGetTriMergeCallback(dGeomID g) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); return ((dxTriMesh*)g)->TriMergeCallback; } void dGeomTriMeshSetData(dGeomID g, dTriMeshDataID Data) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); ((dxTriMesh*)g)->Data = Data; // I changed my data -- I know nothing about my own AABB anymore. ((dxTriMesh*)g)->gflags |= (GEOM_DIRTY|GEOM_AABB_BAD); } dTriMeshDataID dGeomTriMeshGetData(dGeomID g) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); return ((dxTriMesh*)g)->Data; } void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); switch (geomClass) { case dSphereClass: ((dxTriMesh*)g)->doSphereTC = (1 == enable); break; case dBoxClass: ((dxTriMesh*)g)->doBoxTC = (1 == enable); break; case dCapsuleClass: ((dxTriMesh*)g)->doCapsuleTC = (1 == enable); break; } } int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass) { dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); switch (geomClass) { case dSphereClass: if (((dxTriMesh*)g)->doSphereTC) return 1; break; case dBoxClass: if (((dxTriMesh*)g)->doBoxTC) return 1; break; case dCapsuleClass: if (((dxTriMesh*)g)->doCapsuleTC) return 1; break; } return 0; } void dGeomTriMeshClearTCCache(dGeomID g){ dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); dxTriMesh* Geom = (dxTriMesh*)g; Geom->ClearTCCache(); } /* * returns the TriMeshDataID */ dTriMeshDataID dGeomTriMeshGetTriMeshDataID(dGeomID g) { dxTriMesh* Geom = (dxTriMesh*) g; return Geom->Data; } // Getting data void dGeomTriMeshGetTriangle(dGeomID g, int Index, dVector3* v0, dVector3* v1, dVector3* v2){ dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); dxTriMesh* Geom = (dxTriMesh*)g; const dVector3& Position = *(const dVector3*)dGeomGetPosition(g); const dMatrix3& Rotation = *(const dMatrix3*)dGeomGetRotation(g); dVector3 v[3]; FetchTriangle(Geom, Index, Position, Rotation, v); if (v0){ (*v0)[0] = v[0][0]; (*v0)[1] = v[0][1]; (*v0)[2] = v[0][2]; (*v0)[3] = v[0][3]; } if (v1){ (*v1)[0] = v[1][0]; (*v1)[1] = v[1][1]; (*v1)[2] = v[1][2]; (*v1)[3] = v[1][3]; } if (v2){ (*v2)[0] = v[2][0]; (*v2)[1] = v[2][1]; (*v2)[2] = v[2][2]; (*v2)[3] = v[2][3]; } } void dGeomTriMeshGetPoint(dGeomID g, int Index, dReal u, dReal v, dVector3 Out){ dUASSERT(g && g->type == dTriMeshClass, "argument not a trimesh"); dxTriMesh* Geom = (dxTriMesh*)g; const dVector3& Position = *(const dVector3*)dGeomGetPosition(g); const dMatrix3& Rotation = *(const dMatrix3*)dGeomGetRotation(g); dVector3 dv[3]; FetchTriangle(Geom, Index, Position, Rotation, dv); GetPointFromBarycentric(dv, u, v, Out); } int dGeomTriMeshGetTriangleCount (dGeomID g) { dxTriMesh* Geom = (dxTriMesh*)g; return FetchTriangleCount(Geom); } void dGeomTriMeshDataUpdate(dTriMeshDataID g) { dUASSERT(g, "argument not trimesh data"); g->UpdateData(); } #endif // dTRIMESH_OPCODE #endif // dTRIMESH_ENABLED ode-0.11.1/ode/src/collision_trimesh_disabled.cpp0000644000076400007640000001337611142520432016715 00000000000000/************************************************************************* * * * 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 #include #include "config.h" #if !dTRIMESH_ENABLED #include "collision_util.h" #include "collision_trimesh_internal.h" dxTriMesh::dxTriMesh(dSpaceID Space, dTriMeshDataID Data) : dxGeom(Space, 1) { type = dTriMeshClass; } dxTriMesh::~dxTriMesh(){} int dxTriMesh::AABBTest(dxGeom* g, dReal aabb[6]) { return 0; } void dxTriMesh::computeAABB() { dSetZero (aabb,6); } static 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 ) }; // Stub functions for trimesh calls dTriMeshDataID dGeomTriMeshDataCreate(void) { return 0; } void dGeomTriMeshDataDestroy(dTriMeshDataID g) {} void dGeomTriMeshDataSet(dTriMeshDataID g, int data_id, void* in_data) {} void* dGeomTriMeshDataGet(dTriMeshDataID g, int data_id) { return 0; } ODE_API void dGeomTriMeshSetLastTransform( dGeomID g, dMatrix4 last_trans ) {} ODE_API dReal* dGeomTriMeshGetLastTransform( dGeomID g ) { return identity; } dGeomID dCreateTriMesh(dSpaceID space, dTriMeshDataID Data, dTriCallback* Callback, dTriArrayCallback* ArrayCallback, dTriRayCallback* RayCallback) { dxTriMesh* Geom = new dxTriMesh(space, Data); Geom->Callback = Callback; Geom->ArrayCallback = ArrayCallback; Geom->RayCallback = RayCallback; return Geom; } void dGeomTriMeshSetData(dGeomID g, dTriMeshDataID Data) {} dTriMeshDataID dGeomTriMeshGetData(dGeomID g) { return 0; } void dGeomTriMeshDataBuildSingle(dTriMeshDataID g, const void* Vertices, int VertexStride, int VertexCount, const void* Indices, int IndexCount, int TriStride) { } void dGeomTriMeshDataBuildSingle1(dTriMeshDataID g, const void* Vertices, int VertexStride, int VertexCount, const void* Indices, int IndexCount, int TriStride, const void* Normals) { } void dGeomTriMeshDataBuildDouble(dTriMeshDataID g, const void* Vertices, int VertexStride, int VertexCount, const void* Indices, int IndexCount, int TriStride) { } void dGeomTriMeshDataBuildDouble1(dTriMeshDataID g, const void* Vertices, int VertexStride, int VertexCount, const void* Indices, int IndexCount, int TriStride, const void* Normals) { } void dGeomTriMeshDataBuildSimple(dTriMeshDataID g, const dReal* Vertices, int VertexCount, const dTriIndex* Indices, int IndexCount) { } void dGeomTriMeshDataBuildSimple1(dTriMeshDataID g, const dReal* Vertices, int VertexCount, const dTriIndex* Indices, int IndexCount, const int* Normals) { } void dGeomTriMeshDataPreprocess(dTriMeshDataID g) { } void dGeomTriMeshDataGetBuffer(dTriMeshDataID g, unsigned char** buf, int* bufLen) { *buf = NULL; *bufLen=0; } void dGeomTriMeshDataSetBuffer(dTriMeshDataID g, unsigned char* buf) {} void dGeomTriMeshSetCallback(dGeomID g, dTriCallback* Callback) { } dTriCallback* dGeomTriMeshGetCallback(dGeomID g) { return 0; } void dGeomTriMeshSetArrayCallback(dGeomID g, dTriArrayCallback* ArrayCallback) { } dTriArrayCallback* dGeomTriMeshGetArrayCallback(dGeomID g) { return 0; } void dGeomTriMeshSetRayCallback(dGeomID g, dTriRayCallback* Callback) { } dTriRayCallback* dGeomTriMeshGetRayCallback(dGeomID g) { return 0; } void dGeomTriMeshSetTriMergeCallback(dGeomID g, dTriTriMergeCallback* Callback) { } dTriTriMergeCallback* dGeomTriMeshGetTriMergeCallback(dGeomID g) { return 0; } void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable) {} int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass) { return 0; } void dGeomTriMeshClearTCCache(dGeomID g) {} dTriMeshDataID dGeomTriMeshGetTriMeshDataID(dGeomID g) { return 0; } int dGeomTriMeshGetTriangleCount (dGeomID g) { return 0; } void dGeomTriMeshDataUpdate(dTriMeshDataID g) {} #endif // !dTRIMESH_ENABLED ode-0.11.1/ode/src/collision_trimesh_ray.cpp0000644000076400007640000001600111156775756015757 00000000000000/************************************************************************* * * * 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 #include #include #include #include "config.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 dVector3& TLPosition = *(const dVector3*)dGeomGetPosition(TriMesh); const dMatrix3& TLRotation = *(const dMatrix3*)dGeomGetRotation(TriMesh); const unsigned uiTLSKind = TriMesh->getParentSpaceTLSKind(); dIASSERT(uiTLSKind == RayGeom->getParentSpaceTLSKind()); // The colliding spaces must use matching cleanup method TrimeshCollidersCache *pccColliderCache = GetTrimeshCollidersCache(uiTLSKind); RayCollider& Collider = pccColliderCache->_RayCollider; dReal Length = dGeomRayGetLength(RayGeom); int FirstContact, BackfaceCull; dGeomRayGetParams(RayGeom, &FirstContact, &BackfaceCull); int ClosestHit = dGeomRayGetClosestHit(RayGeom); Collider.SetFirstContact(FirstContact != 0); Collider.SetClosestHit(ClosestHit != 0); Collider.SetCulling(BackfaceCull != 0); Collider.SetMaxDist(Length); dVector3 Origin, Direction; dGeomRayGet(RayGeom, Origin, Direction); /* Make Ray */ Ray WorldRay; WorldRay.mOrig.x = Origin[0]; WorldRay.mOrig.y = Origin[1]; WorldRay.mOrig.z = Origin[2]; WorldRay.mDir.x = Direction[0]; WorldRay.mDir.y = Direction[1]; WorldRay.mDir.z = Direction[2]; /* Intersect */ Matrix4x4 amatrix; int TriCount = 0; if (Collider.Collide(WorldRay, TriMesh->Data->BVTree, &MakeMatrix(TLPosition, TLRotation, amatrix))) { TriCount = pccColliderCache->Faces.GetNbFaces(); } if (TriCount == 0) { return 0; } const CollisionFace* Faces = pccColliderCache->Faces.GetFaces(); int OutTriCount = 0; for (int i = 0; i < TriCount; i++) { if (TriMesh->RayCallback == null || TriMesh->RayCallback(TriMesh, RayGeom, Faces[i].mFaceID, Faces[i].mU, Faces[i].mV)) { const int& TriIndex = Faces[i].mFaceID; if (!Callback(TriMesh, RayGeom, TriIndex)) { continue; } dContactGeom* Contact = SAFECONTACT(Flags, Contacts, OutTriCount, Stride); dVector3 dv[3]; FetchTriangle(TriMesh, TriIndex, TLPosition, TLRotation, dv); 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); dCROSS(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, BackfaceCull; dGeomRayGetParams(RayGeom, &FirstContact, &BackfaceCull); 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->RayCallback || TriMesh->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 ode-0.11.1/ode/src/timer.cpp0000644000076400007640000002270411032104026012446 00000000000000/************************************************************************* * * * 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 #include #include "config.h" #include "util.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 #include 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 #include 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 (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 (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; size_t 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 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 #include "config.h" #include #include #include #include #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 || 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 || 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 max) max = diff; } } return max; } ode-0.11.1/ode/src/lcp.cpp0000644000076400007640000015012411011472041012104 00000000000000/************************************************************************* * * * 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= 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 #include "config.h" #include "lcp.h" #include #include #include "mat.h" // for testing #include // for testing #include "util.h" //*************************************************************************** // code generation parameters // LCP debugging (mosty for fast dLCP) - this slows things down a lot //#define DEBUG_LCP //#define dLCP_SLOW // use slow dLCP object #define dLCP_FAST // use fast dLCP object // option 1 : matrix row pointers (less data copying) #define ROWPTRS #define ATYPE dReal ** #define AROW(i) (A[i]) // option 2 : no matrix row pointers (slightly faster inner loops) //#define NOROWPTRS //#define ATYPE dReal * //#define AROW(i) (A+(i)*nskip) // use protected, non-stack memory allocation system #ifdef dUSE_MALLOC_FOR_ALLOCA extern unsigned int dMemoryFlag; #define ALLOCA(t,v,s) t* v = (t*) malloc(s) #define UNALLOCA(t) free(t) #else #define ALLOCA(t,v,s) t* v =(t*)dALLOCA16(s) #define UNALLOCA(t) /* nothing */ #endif #define NUB_OPTIMIZATIONS //*************************************************************************** // 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, int n, int i1, int i2, int nskip, int do_fast_row_swaps) { int i; dAASSERT (A && n > 0 && i1 >= 0 && i2 >= 0 && i1 < n && i2 < n && nskip >= n && i1 < i2); # ifdef ROWPTRS for (i=i1+1; i 0) { memcpy (tmprow,A+i1*nskip,i1*sizeof(dReal)); memcpy (A+i1*nskip,A+i2*nskip,i1*sizeof(dReal)); memcpy (A+i2*nskip,tmprow,i1*sizeof(dReal)); } for (i=i1+1; i0 && i1 >=0 && i2 >= 0 && i1 < n && i2 < n && nskip >= n && i1 <= i2); if (i1==i2) return; swapRowsAndCols (A,n,i1,i2,nskip,do_fast_row_swaps); #ifdef dUSE_MALLOC_FOR_ALLOCA if (dMemoryFlag == d_MEMORY_OUT_OF_MEMORY) return; #endif tmp = x[i1]; x[i1] = x[i2]; x[i2] = tmp; tmp = b[i1]; b[i1] = b[i2]; b[i2] = tmp; tmp = w[i1]; w[i1] = w[i2]; w[i2] = tmp; tmp = lo[i1]; lo[i1] = lo[i2]; lo[i2] = tmp; tmp = hi[i1]; hi[i1] = hi[i2]; hi[i2] = tmp; tmpi = p[i1]; p[i1] = p[i2]; p[i2] = tmpi; tmpi = state[i1]; state[i1] = state[i2]; state[i2] = tmpi; if (findex) { tmpi = findex[i1]; findex[i1] = findex[i2]; findex[i2] = tmpi; } } // 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, int nC, int *C, int nskip) { int 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 1e-8) dDebug (0,"L*D*L' check, maximum difference = %.6e\n",diff); } #endif // for debugging #ifdef DEBUG_LCP static void checkPermutations (int i, int n, int nC, int nN, int *p, int *C) { int j,k; dIASSERT (nC>=0 && nN>=0 && (nC+nN)==i && i < n); for (k=0; k= 0 && p[k] < i); for (k=i; k C,N; // index sets int last_i_for_solve1; // last i value given to solve1 dLCP (int _n, int _nub, dReal *_Adata, dReal *_x, dReal *_b, dReal *_w, dReal *_lo, dReal *_hi, dReal *_L, dReal *_d, dReal *_Dell, dReal *_ell, dReal *_tmp, int *_state, int *_findex, int *_p, int *_C, dReal **Arows); // the constructor is given an initial problem description (A,x,b,w) and // space for other working data (which the caller may allocate on the stack). // some of this data is specific to the fast dLCP implementation. // the matrices A and L have size n*n, vectors have size n*1. // A represents a symmetric matrix but only the lower triangle is valid. // `nub' is the number of unbounded indexes at the start. all the indexes // 0..nub-1 will be put into C. ~dLCP(); int getNub() { return nub; } // return the value of `nub'. the constructor may want to change it, // so the caller should find out its new value. // transfer functions: transfer index i to the given set (C or N). indexes // less than `nub' can never be given. A,x,b,w,etc may be permuted by these // functions, the caller must be robust to this. void transfer_i_to_C (int i); // this assumes C and N span 1:i-1. this also assumes that solve1() has // been recently called for the same i without any other transfer // functions in between (thereby allowing some data reuse for the fast // implementation). void transfer_i_to_N (int i); // this assumes C and N span 1:i-1. void transfer_i_from_N_to_C (int i); void transfer_i_from_C_to_N (int i); int numC(); int numN(); // return the number of indexes in set C/N int indexC (int i); int indexN (int i); // return index i in set C/N. // accessor and arithmetic functions. Aij translates as A(i,j), etc. // make sure that only the lower triangle of A is ever referenced. dReal Aii (int i); dReal AiC_times_qC (int i, dReal *q); dReal AiN_times_qN (int i, dReal *q); // for all Nj void pN_equals_ANC_times_qC (dReal *p, dReal *q); // for all Nj void pN_plusequals_ANi (dReal *p, int i, int sign=1); // for all Nj. sign = +1,-1. assumes i > maximum index in N. void pC_plusequals_s_times_qC (dReal *p, dReal s, dReal *q); void pN_plusequals_s_times_qN (dReal *p, dReal s, dReal *q); // for all Nj void solve1 (dReal *a, int i, int dir=1, int only_transfer=0); // get a(C) = - dir * A(C,C) \ A(C,i). dir must be +/- 1. // the fast version of this function computes some data that is needed by // transfer_i_to_C(). if only_transfer is nonzero then this function // *only* computes that data, it does not set a(C). void unpermute(); // call this at the end of the LCP function. if the x/w values have been // permuted then this will unscramble them. }; dLCP::dLCP (int _n, int _nub, dReal *_Adata, dReal *_x, dReal *_b, dReal *_w, dReal *_lo, dReal *_hi, dReal *_L, dReal *_d, dReal *_Dell, dReal *_ell, dReal *_tmp, int *_state, int *_findex, int *_p, int *_C, dReal **Arows) { dUASSERT (_findex==0,"slow dLCP object does not support findex array"); n = _n; nub = _nub; Adata = _Adata; A = 0; x = _x; b = _b; w = _w; lo = _lo; hi = _hi; nskip = dPAD(n); dSetZero (x,n); last_i_for_solve1 = -1; int i,j; C.setSize (n); N.setSize (n); for (i=0; i0, put all indexes 0..nub-1 into C and solve for x if (nub > 0) { for (i=0; i= i) dDebug (0,"N assumption violated"); if (sign > 0) { for (k=0; k 0) { for (ii=0; ii nub if (nub < n) { for (k=0; k<100; k++) { int i1,i2; do { i1 = dRandInt(n-nub)+nub; i2 = dRandInt(n-nub)+nub; } while (i1 > i2); //printf ("--> %d %d\n",i1,i2); swapProblem (A,x,b,w,lo,hi,p,state,findex,n,i1,i2,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. for (k=nub; k= 0) continue; if (lo[k]==-dInfinity && hi[k]==dInfinity) { swapProblem (A,x,b,w,lo,hi,p,state,findex,n,nub,k,nskip,0); 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 (nub > 0) { for (k=0; k nub such that all findex variables are at the end if (findex) { int num_at_end = 0; for (k=n-1; k >= nub; k--) { if (findex[k] >= 0) { swapProblem (A,x,b,w,lo,hi,p,state,findex,n,k,n-1-num_at_end,nskip,1); num_at_end++; } } } // print info about indexes /* for (k=0; k 0) { // ell,Dell were computed by solve1(). note, ell = D \ L1solve (L,A(i,C)) for (j=0; j 0) { dReal *aptr = AROW(i); # ifdef NUB_OPTIMIZATIONS // if nub>0, initial part of aptr unpermuted for (j=0; j 0) { for (int i=0; i 0) { dReal *aptr = AROW(i); # ifdef NUB_OPTIMIZATIONS // if nub>0, initial part of aptr[] is guaranteed unpermuted for (j=0; j 0) { for (j=0; j0 && A && x && b && w && nub == 0); int i,k; int nskip = dPAD(n); ALLOCA (dReal,L,n*nskip*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (L == NULL) { dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,d,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (d == NULL) { UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,delta_x,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (delta_x == NULL) { UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,delta_w,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (delta_w == NULL) { UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,Dell,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (Dell == NULL) { UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,ell,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (ell == NULL) { UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,tmp,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (tmp == NULL) { UNALLOCA(ell); UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal*,Arows,n*sizeof(dReal*)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (Arows == NULL) { UNALLOCA(tmp); UNALLOCA(ell); UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (int,p,n*sizeof(int)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (p == NULL) { UNALLOCA(Arows); UNALLOCA(tmp); UNALLOCA(ell); UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (int,C,n*sizeof(int)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (C == NULL) { UNALLOCA(p); UNALLOCA(Arows); UNALLOCA(tmp); UNALLOCA(ell); UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (int,dummy,n*sizeof(int)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (dummy == NULL) { UNALLOCA(C); UNALLOCA(p); UNALLOCA(Arows); UNALLOCA(tmp); UNALLOCA(ell); UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif dLCP lcp (n,0,A,x,b,w,tmp,tmp,L,d,Dell,ell,tmp,dummy,dummy,p,C,Arows); nub = lcp.getNub(); for (i=0; i= 0) { lcp.transfer_i_to_N (i); } else { for (;;) { // compute: delta_x(C) = -A(C,C)\A(C,i) dSetZero (delta_x,n); lcp.solve1 (delta_x,i); #ifdef dUSE_MALLOC_FOR_ALLOCA if (dMemoryFlag == d_MEMORY_OUT_OF_MEMORY) { UNALLOCA(dummy); UNALLOCA(C); UNALLOCA(p); UNALLOCA(Arows); UNALLOCA(tmp); UNALLOCA(ell); UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); return; } #endif delta_x[i] = 1; // compute: delta_w = A*delta_x dSetZero (delta_w,n); lcp.pN_equals_ANC_times_qC (delta_w,delta_x); lcp.pN_plusequals_ANi (delta_w,i); delta_w[i] = lcp.AiC_times_qC (i,delta_x) + lcp.Aii(i); // find index to switch int si = i; // si = switch index int si_in_N = 0; // set to 1 if si in N dReal s = -w[i]/delta_w[i]; if (s <= 0) { dMessage (d_ERR_LCP, "LCP internal error, s <= 0 (s=%.4e)",s); if (i < (n-1)) { dSetZero (x+i,n-i); dSetZero (w+i,n-i); } goto done; } for (k=0; k < lcp.numN(); k++) { if (delta_w[lcp.indexN(k)] < 0) { dReal s2 = -w[lcp.indexN(k)] / delta_w[lcp.indexN(k)]; if (s2 < s) { s = s2; si = lcp.indexN(k); si_in_N = 1; } } } for (k=0; k < lcp.numC(); k++) { if (delta_x[lcp.indexC(k)] < 0) { dReal s2 = -x[lcp.indexC(k)] / delta_x[lcp.indexC(k)]; if (s2 < s) { s = s2; si = lcp.indexC(k); si_in_N = 0; } } } // apply x = x + s * delta_x lcp.pC_plusequals_s_times_qC (x,s,delta_x); x[i] += s; lcp.pN_plusequals_s_times_qN (w,s,delta_w); w[i] += s * delta_w[i]; // switch indexes between sets if necessary if (si==i) { w[i] = 0; lcp.transfer_i_to_C (i); break; } if (si_in_N) { w[si] = 0; lcp.transfer_i_from_N_to_C (si); } else { x[si] = 0; lcp.transfer_i_from_C_to_N (si); } } } } done: lcp.unpermute(); UNALLOCA (L); UNALLOCA (d); UNALLOCA (delta_x); UNALLOCA (delta_w); UNALLOCA (Dell); UNALLOCA (ell); UNALLOCA (tmp); UNALLOCA (Arows); UNALLOCA (p); UNALLOCA (C); UNALLOCA (dummy); } //*************************************************************************** // an optimized Dantzig LCP driver routine for the lo-hi LCP problem. void dSolveLCP (int n, dReal *A, dReal *x, dReal *b, dReal *w, int nub, dReal *lo, dReal *hi, int *findex) { dAASSERT (n>0 && A && x && b && w && lo && hi && nub >= 0 && nub <= n); int i,k,hit_first_friction_index = 0; int nskip = dPAD(n); // if all the variables are unbounded then we can just factor, solve, // and return if (nub >= n) { dFactorLDLT (A,w,n,nskip); // use w for d dSolveLDLT (A,w,b,n,nskip); memcpy (x,b,n*sizeof(dReal)); dSetZero (w,n); return; } # ifndef dNODEBUG // check restrictions on lo and hi for (k=0; k= 0); # endif ALLOCA (dReal,L,n*nskip*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (L == NULL) { dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,d,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (d == NULL) { UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,delta_x,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (delta_x == NULL) { UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,delta_w,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (delta_w == NULL) { UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,Dell,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (Dell == NULL) { UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,ell,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (ell == NULL) { UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal*,Arows,n*sizeof(dReal*)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (Arows == NULL) { UNALLOCA(ell); UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (int,p,n*sizeof(int)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (p == NULL) { UNALLOCA(Arows); UNALLOCA(ell); UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (int,C,n*sizeof(int)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (C == NULL) { UNALLOCA(p); UNALLOCA(Arows); UNALLOCA(ell); UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif int dir; dReal dirf; // for i in N, state[i] is 0 if x(i)==lo(i) or 1 if x(i)==hi(i) ALLOCA (int,state,n*sizeof(int)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (state == NULL) { UNALLOCA(C); UNALLOCA(p); UNALLOCA(Arows); UNALLOCA(ell); UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif // 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=new dLCP(n,nub,A,x,b,w,lo,hi,L,d,Dell,ell,delta_w,state,findex,p,C,Arows); nub = lcp->getNub(); // loop over all indexes 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. for (i=nub; i= 0) { // un-permute x into delta_w, which is not being used at the moment for (k=0; kAiC_times_qC (i,x) + lcp->AiN_times_qN (i,x) - b[i]; // if lo=hi=0 (which can happen for tangential friction when normals are // 0) then the index will be assigned to set N with some state. however, // set C's line has zero size, so the index will always remain in set N. // with the "normal" switching logic, if w changed sign then the index // would have to switch to set C and then back to set N with an inverted // state. this is pointless, and also computationally expensive. to // prevent this from happening, we use the rule that indexes with lo=hi=0 // will never be checked for set changes. this means that the state for // these indexes may be incorrect, but that doesn't matter. // see if x(i),w(i) is in a valid region if (lo[i]==0 && w[i] >= 0) { lcp->transfer_i_to_N (i); state[i] = 0; } else if (hi[i]==0 && w[i] <= 0) { lcp->transfer_i_to_N (i); state[i] = 1; } 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,0,1); #ifdef dUSE_MALLOC_FOR_ALLOCA if (dMemoryFlag == d_MEMORY_OUT_OF_MEMORY) { UNALLOCA(state); UNALLOCA(C); UNALLOCA(p); UNALLOCA(Arows); UNALLOCA(ell); UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); return; } #endif lcp->transfer_i_to_C (i); } else { // we must push x(i) and w(i) for (;;) { // find direction to push on x(i) if (w[i] <= 0) { dir = 1; dirf = REAL(1.0); } else { dir = -1; dirf = REAL(-1.0); } // compute: delta_x(C) = -dir*A(C,C)\A(C,i) lcp->solve1 (delta_x,i,dir); #ifdef dUSE_MALLOC_FOR_ALLOCA if (dMemoryFlag == d_MEMORY_OUT_OF_MEMORY) { UNALLOCA(state); UNALLOCA(C); UNALLOCA(p); UNALLOCA(Arows); UNALLOCA(ell); UNALLOCA(Dell); UNALLOCA(delta_w); UNALLOCA(delta_x); UNALLOCA(d); UNALLOCA(L); return; } #endif // note that delta_x[i] = dirf, but we wont bother to set it // compute: delta_w = A*delta_x ... note we only care about // delta_w(N) and delta_w(i), the rest is ignored lcp->pN_equals_ANC_times_qC (delta_w,delta_x); lcp->pN_plusequals_ANi (delta_w,i,dir); delta_w[i] = lcp->AiC_times_qC (i,delta_x) + lcp->Aii(i)*dirf; // find largest step we can take (size=s), either to drive x(i),w(i) // to the valid LCP region or to drive an already-valid variable // outside the valid region. int cmd = 1; // index switching command int si = 0; // si = index to switch if cmd>3 dReal s = -w[i]/delta_w[i]; if (dir > 0) { if (hi[i] < dInfinity) { dReal s2 = (hi[i]-x[i])/dirf; // step to x(i)=hi(i) if (s2 < s) { s = s2; cmd = 3; } } } else { if (lo[i] > -dInfinity) { dReal s2 = (lo[i]-x[i])/dirf; // step to x(i)=lo(i) if (s2 < s) { s = s2; cmd = 2; } } } for (k=0; k < lcp->numN(); k++) { if ((state[lcp->indexN(k)]==0 && delta_w[lcp->indexN(k)] < 0) || (state[lcp->indexN(k)]!=0 && delta_w[lcp->indexN(k)] > 0)) { // don't bother checking if lo=hi=0 if (lo[lcp->indexN(k)] == 0 && hi[lcp->indexN(k)] == 0) continue; dReal s2 = -w[lcp->indexN(k)] / delta_w[lcp->indexN(k)]; if (s2 < s) { s = s2; cmd = 4; si = lcp->indexN(k); } } } for (k=nub; k < lcp->numC(); k++) { if (delta_x[lcp->indexC(k)] < 0 && lo[lcp->indexC(k)] > -dInfinity) { dReal s2 = (lo[lcp->indexC(k)]-x[lcp->indexC(k)]) / delta_x[lcp->indexC(k)]; if (s2 < s) { s = s2; cmd = 5; si = lcp->indexC(k); } } if (delta_x[lcp->indexC(k)] > 0 && hi[lcp->indexC(k)] < dInfinity) { dReal s2 = (hi[lcp->indexC(k)]-x[lcp->indexC(k)]) / delta_x[lcp->indexC(k)]; if (s2 < s) { s = s2; cmd = 6; si = lcp->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 <= 0) { dMessage (d_ERR_LCP, "LCP internal error, s <= 0 (s=%.4e)",s); if (i < (n-1)) { dSetZero (x+i,n-i); dSetZero (w+i,n-i); } goto done; } // apply x = x + s * delta_x lcp->pC_plusequals_s_times_qC (x,s,delta_x); x[i] += s * dirf; // apply w = w + s * delta_w lcp->pN_plusequals_s_times_qN (w,s,delta_w); w[i] += s * delta_w[i]; // switch indexes between sets if necessary switch (cmd) { case 1: // done w[i] = 0; lcp->transfer_i_to_C (i); break; case 2: // done x[i] = lo[i]; state[i] = 0; lcp->transfer_i_to_N (i); break; case 3: // done x[i] = hi[i]; state[i] = 1; lcp->transfer_i_to_N (i); break; case 4: // keep going w[si] = 0; lcp->transfer_i_from_N_to_C (si); break; case 5: // keep going x[si] = lo[si]; state[si] = 0; lcp->transfer_i_from_C_to_N (si); break; case 6: // keep going x[si] = hi[si]; state[si] = 1; lcp->transfer_i_from_C_to_N (si); break; } if (cmd <= 3) break; } } } done: lcp->unpermute(); delete lcp; UNALLOCA (L); UNALLOCA (d); UNALLOCA (delta_x); UNALLOCA (delta_w); UNALLOCA (Dell); UNALLOCA (ell); UNALLOCA (Arows); UNALLOCA (p); UNALLOCA (C); UNALLOCA (state); } //*************************************************************************** // accuracy and timing test extern "C" ODE_API void dTestSolveLCP() { int n = 100; int 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"); ALLOCA (dReal,A,n*nskip*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (A == NULL) { dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,x,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (x == NULL) { UNALLOCA (A); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,b,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (b == NULL) { UNALLOCA (x); UNALLOCA (A); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,w,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (w == NULL) { UNALLOCA (b); UNALLOCA (x); UNALLOCA (A); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,lo,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (lo == NULL) { UNALLOCA (w); UNALLOCA (b); UNALLOCA (x); UNALLOCA (A); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,hi,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (hi == NULL) { UNALLOCA (lo); UNALLOCA (w); UNALLOCA (b); UNALLOCA (x); UNALLOCA (A); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,A2,n*nskip*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (A2 == NULL) { UNALLOCA (hi); UNALLOCA (lo); UNALLOCA (w); UNALLOCA (b); UNALLOCA (x); UNALLOCA (A); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,b2,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (b2 == NULL) { UNALLOCA (A2); UNALLOCA (hi); UNALLOCA (lo); UNALLOCA (w); UNALLOCA (b); UNALLOCA (x); UNALLOCA (A); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,lo2,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (lo2 == NULL) { UNALLOCA (b2); UNALLOCA (A2); UNALLOCA (hi); UNALLOCA (lo); UNALLOCA (w); UNALLOCA (b); UNALLOCA (x); UNALLOCA (A); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,hi2,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (hi2 == NULL) { UNALLOCA (lo2); UNALLOCA (b2); UNALLOCA (A2); UNALLOCA (hi); UNALLOCA (lo); UNALLOCA (w); UNALLOCA (b); UNALLOCA (x); UNALLOCA (A); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,tmp1,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (tmp1 == NULL) { UNALLOCA (hi2); UNALLOCA (lo2); UNALLOCA (b2); UNALLOCA (A2); UNALLOCA (hi); UNALLOCA (lo); UNALLOCA (w); UNALLOCA (b); UNALLOCA (x); UNALLOCA (A); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif ALLOCA (dReal,tmp2,n*sizeof(dReal)); #ifdef dUSE_MALLOC_FOR_ALLOCA if (tmp2 == NULL) { UNALLOCA (tmp1); UNALLOCA (hi2); UNALLOCA (lo2); UNALLOCA (b2); UNALLOCA (A2); UNALLOCA (hi); UNALLOCA (lo); UNALLOCA (w); UNALLOCA (b); UNALLOCA (x); UNALLOCA (A); dMemoryFlag = d_MEMORY_OUT_OF_MEMORY; return; } #endif double total_time = 0; for (int count=0; count < 1000; count++) { // 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 tol ? "FAILED" : "passed"); if (diff > tol) dDebug (0,"A*x = b+w, maximum difference = %.6e",diff); int n1=0,n2=0,n3=0; for (i=0; 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); } UNALLOCA (A); UNALLOCA (x); UNALLOCA (b); UNALLOCA (w); UNALLOCA (lo); UNALLOCA (hi); UNALLOCA (A2); UNALLOCA (b2); UNALLOCA (lo2); UNALLOCA (hi2); UNALLOCA (tmp1); UNALLOCA (tmp2); } ode-0.11.1/ode/src/fastlsolve.c0000644000076400007640000001765607271364673013214 00000000000000/* generated code, do not edit. */ #include "ode/matrix.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. */ void dSolveL1 (const dReal *L, dReal *B, int n, int lskip1) { /* declare variables - Z matrix, p and q vectors, etc */ dReal Z11,Z21,Z31,Z41,p1,q1,p2,p3,p4,*ex; const dReal *ell; int lskip2,lskip3,i,j; /* compute lskip values */ lskip2 = 2*lskip1; lskip3 = 3*lskip1; /* compute all 4 x 1 blocks of X */ for (i=0; i <= n-4; i+=4) { /* compute all 4 x 1 block of X, from rows i..i+4-1 */ /* set the Z matrix to 0 */ Z11=0; Z21=0; Z31=0; Z41=0; ell = L + i*lskip1; ex = B; /* the inner loop that computes outer products and adds them to Z */ for (j=i-12; j >= 0; j -= 12) { /* load p and q values */ p1=ell[0]; q1=ex[0]; p2=ell[lskip1]; p3=ell[lskip2]; p4=ell[lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* load p and q values */ p1=ell[1]; q1=ex[1]; p2=ell[1+lskip1]; p3=ell[1+lskip2]; p4=ell[1+lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* load p and q values */ p1=ell[2]; q1=ex[2]; p2=ell[2+lskip1]; p3=ell[2+lskip2]; p4=ell[2+lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* load p and q values */ p1=ell[3]; q1=ex[3]; p2=ell[3+lskip1]; p3=ell[3+lskip2]; p4=ell[3+lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* load p and q values */ p1=ell[4]; q1=ex[4]; p2=ell[4+lskip1]; p3=ell[4+lskip2]; p4=ell[4+lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* load p and q values */ p1=ell[5]; q1=ex[5]; p2=ell[5+lskip1]; p3=ell[5+lskip2]; p4=ell[5+lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* load p and q values */ p1=ell[6]; q1=ex[6]; p2=ell[6+lskip1]; p3=ell[6+lskip2]; p4=ell[6+lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* load p and q values */ p1=ell[7]; q1=ex[7]; p2=ell[7+lskip1]; p3=ell[7+lskip2]; p4=ell[7+lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* load p and q values */ p1=ell[8]; q1=ex[8]; p2=ell[8+lskip1]; p3=ell[8+lskip2]; p4=ell[8+lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* load p and q values */ p1=ell[9]; q1=ex[9]; p2=ell[9+lskip1]; p3=ell[9+lskip2]; p4=ell[9+lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* load p and q values */ p1=ell[10]; q1=ex[10]; p2=ell[10+lskip1]; p3=ell[10+lskip2]; p4=ell[10+lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* load p and q values */ p1=ell[11]; q1=ex[11]; p2=ell[11+lskip1]; p3=ell[11+lskip2]; p4=ell[11+lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* advance pointers */ ell += 12; ex += 12; /* end of inner loop */ } /* compute left-over iterations */ j += 12; for (; j > 0; j--) { /* load p and q values */ p1=ell[0]; q1=ex[0]; p2=ell[lskip1]; p3=ell[lskip2]; p4=ell[lskip3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; Z21 += p2 * q1; Z31 += p3 * q1; Z41 += p4 * q1; /* advance pointers */ ell += 1; ex += 1; } /* finish computing the X(i) block */ Z11 = ex[0] - Z11; ex[0] = Z11; p1 = ell[lskip1]; Z21 = ex[1] - Z21 - p1*Z11; ex[1] = Z21; p1 = ell[lskip2]; p2 = ell[1+lskip2]; Z31 = ex[2] - Z31 - p1*Z11 - p2*Z21; ex[2] = Z31; p1 = ell[lskip3]; p2 = ell[1+lskip3]; p3 = ell[2+lskip3]; Z41 = ex[3] - Z41 - p1*Z11 - p2*Z21 - p3*Z31; ex[3] = Z41; /* end of outer loop */ } /* compute rows at end that are not a multiple of block size */ for (; i < n; i++) { /* compute all 1 x 1 block of X, from rows i..i+1-1 */ /* set the Z matrix to 0 */ Z11=0; ell = L + i*lskip1; ex = B; /* the inner loop that computes outer products and adds them to Z */ for (j=i-12; j >= 0; j -= 12) { /* load p and q values */ p1=ell[0]; q1=ex[0]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* load p and q values */ p1=ell[1]; q1=ex[1]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* load p and q values */ p1=ell[2]; q1=ex[2]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* load p and q values */ p1=ell[3]; q1=ex[3]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* load p and q values */ p1=ell[4]; q1=ex[4]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* load p and q values */ p1=ell[5]; q1=ex[5]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* load p and q values */ p1=ell[6]; q1=ex[6]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* load p and q values */ p1=ell[7]; q1=ex[7]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* load p and q values */ p1=ell[8]; q1=ex[8]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* load p and q values */ p1=ell[9]; q1=ex[9]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* load p and q values */ p1=ell[10]; q1=ex[10]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* load p and q values */ p1=ell[11]; q1=ex[11]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* advance pointers */ ell += 12; ex += 12; /* end of inner loop */ } /* compute left-over iterations */ j += 12; for (; j > 0; j--) { /* load p and q values */ p1=ell[0]; q1=ex[0]; /* compute outer product and add it to the Z matrix */ Z11 += p1 * q1; /* advance pointers */ ell += 1; ex += 1; } /* finish computing the X(i) block */ Z11 = ex[0] - Z11; ex[0] = Z11; } } ode-0.11.1/ode/src/testing.h0000644000076400007640000000542610726322630012466 00000000000000/************************************************************************* * * * 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. * * * *************************************************************************/ /* stuff used for testing */ #ifndef _ODE_TESTING_H_ #define _ODE_TESTING_H_ #include #include "array.h" // compare a sequence of named matrices/vectors, i.e. to make sure that two // different pieces of code are giving the same results. class dMatrixComparison { struct dMatInfo; dArray 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 }; #endif ode-0.11.1/ode/src/step.h0000644000076400007640000000340007506200314011746 00000000000000/************************************************************************* * * * 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 void dInternalStepIsland (dxWorld *world, dxBody * const *body, int nb, dxJoint * const *joint, int nj, dReal stepsize); #endif ode-0.11.1/ode/src/ode.cpp0000644000076400007640000013221111206274560012106 00000000000000/************************************************************************* * * * 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 "objects.h" #include #include "joints/joints.h" #include #include #include "step.h" #include "quickstep.h" #include "util.h" #include #include // misc defines #define ALLOCA dALLOCA16 //**************************************************************************** // utility dObject::dObject(dxWorld *w) { world = w; next = 0; tome = 0; userdata = 0; tag = 0; } // 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 = 0; obj->tome = 0; } // 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 = 0; 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 = 0; j->node[0].next = 0; j->node[1].body = 0; j->node[1].next = 0; } //**************************************************************************** // 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 = 0; b->flags = 0; b->geom = 0; b->average_lvel_buffer = 0; b->average_avel_buffer = 0; 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 = 0; // 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 = 0; 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 = 0; 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 = 0; dxJointNode *next = n->next; n->next = 0; 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 = 0; } if(b->average_avel_buffer) { delete[] (b->average_avel_buffer); b->average_avel_buffer = 0; } 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)); dOrthogonalizeR(b->posr.R); 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." ) memcpy (&b->mass,mass,sizeof(dMass)); if (dInvertPDMatrix (b->mass.I,b->invI,3)==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); memcpy (mass,&b->mass,sizeof(dMass)); } 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]; dCROSS (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]; dCROSS (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]; dCROSS (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]; dCROSS (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]; dCROSS (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]; dCROSS (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 = 0; } if(b->average_avel_buffer) { delete[] b->average_avel_buffer; b->average_avel_buffer = 0; } 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 = 0; b->average_avel_buffer = 0; } // 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 dxJoint* createJoint(dWorldID w, dJointGroupID group) { dxJoint *j; if (group) { j = (dxJoint*) group->stack.alloc(sizeof(T)); group->num++; } else j = (dxJoint*) dAlloc(sizeof(T)); new(j) T(w); if (group) j->flags |= dJOINT_INGROUP; return j; } dxJoint * dJointCreateBall (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint(w,group); } dxJoint * dJointCreateHinge (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint(w,group); } dxJoint * dJointCreateSlider (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint(w,group); } dxJoint * dJointCreateContact (dWorldID w, dJointGroupID group, const dContact *c) { dAASSERT (w && c); dxJointContact *j = (dxJointContact *) createJoint (w,group); j->contact = *c; return j; } dxJoint * dJointCreateHinge2 (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint (w,group); } dxJoint * dJointCreateUniversal (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint (w,group); } dxJoint * dJointCreatePR (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint (w,group); } dxJoint * dJointCreatePU (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint (w,group); } dxJoint * dJointCreatePiston (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint (w,group); } dxJoint * dJointCreateFixed (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint (w,group); } dxJoint * dJointCreateNull (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint (w,group); } dxJoint * dJointCreateAMotor (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint (w,group); } dxJoint * dJointCreateLMotor (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint (w,group); } dxJoint * dJointCreatePlane2D (dWorldID w, dJointGroupID group) { dAASSERT (w); return createJoint (w,group); } void dJointDestroy (dxJoint *j) { dAASSERT (j); size_t sz = j->size(); if (j->flags & dJOINT_INGROUP) return; removeJointReferencesFromAttachedBodies (j); removeObjectFromList (j); j->world->nj--; j->~dxJoint(); dFree (j, sz); } dJointGroupID dJointGroupCreate (int max_size) { // not any more ... dUASSERT (max_size > 0,"max size must be > 0"); dxJointGroup *group = new dxJointGroup; group->num = 0; return group; } void dJointGroupDestroy (dJointGroupID group) { dAASSERT (group); dJointGroupEmpty (group); delete group; } void dJointGroupEmpty (dJointGroupID group) { // 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. // if any group joints have their world pointer set to 0, their world was // previously destroyed. no special handling is required for these joints. dAASSERT (group); int i; dxJoint **jlist = (dxJoint**) ALLOCA (group->num * sizeof(dxJoint*)); dxJoint *j = (dxJoint*) group->stack.rewind(); for (i=0; i < group->num; i++) { jlist[i] = j; j = (dxJoint*) (group->stack.next (j->size())); } for (i=group->num-1; i >= 0; i--) { if (jlist[i]->world) { removeJointReferencesFromAttachedBodies (jlist[i]); removeObjectFromList (jlist[i]); jlist[i]->world->nj--; jlist[i]->~dxJoint(); } } group->num = 0; group->stack.freeAll(); } 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 == 0 || body1 != body2,"can't have body1==body2"); dxWorld *world = joint->world; dUASSERT ( (!body1 || body1->world == world) && (!body2 || 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 != 0) ^ (body2 != 0))), "joint can not be attached to just one body"); // remove any existing body attachments if (joint->node[0].body || joint->node[1].body) { removeJointReferencesFromAttachedBodies (joint); } // if a body is zero, make sure that it is body2, so 0 --> node[1].body if (body1==0) { body1 = body2; body2 = 0; 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) { joint->node[1].next = body1->firstjoint; body1->firstjoint = &joint->node[1]; } else joint->node[1].next = 0; if (body2) { joint->node[0].next = body2->firstjoint; body2->firstjoint = &joint->node[0]; } else { joint->node[0].next = 0; } // 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 || body2) 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); // 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); // 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; w->firstbody = 0; w->firstjoint = 0; w->nb = 0; w->nj = 0; dSetZero (w->gravity,4); w->global_erp = REAL(0.2); #if defined(dSINGLE) w->global_cfm = 1e-5f; #elif defined(dDOUBLE) w->global_cfm = 1e-10; #else #error dSINGLE or dDOUBLE must be defined #endif w->body_flags = 0; // everything disabled w->adis.idle_steps = 10; w->adis.idle_time = 0; w->adis.average_samples = 1; // Default is 1 sample => Instantaneous velocity w->adis.angular_average_threshold = REAL(0.01)*REAL(0.01); // (magnitude squared) w->adis.linear_average_threshold = REAL(0.01)*REAL(0.01); // (magnitude squared) w->qs.num_iterations = 20; w->qs.w = REAL(1.3); w->contactp.max_vel = dInfinity; w->contactp.min_depth = 0; w->dampingp.linear_scale = 0; w->dampingp.angular_scale = 0; w->dampingp.linear_threshold = REAL(0.01) * REAL(0.01); w->dampingp.angular_threshold = REAL(0.01) * REAL(0.01); w->max_angular_speed = dInfinity; return w; } void dWorldDestroy (dxWorld *w) { // delete all bodies and joints dAASSERT (w); dxBody *nextb, *b = w->firstbody; while (b) { nextb = (dxBody*) b->next; // TODO: remove those 2 ifs if(b->average_lvel_buffer) { delete[] (b->average_lvel_buffer); b->average_lvel_buffer = 0; } if(b->average_avel_buffer) { delete[] (b->average_avel_buffer); b->average_avel_buffer = 0; } 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 = 0; j->node[0].body = 0; j->node[0].next = 0; j->node[1].body = 0; j->node[1].next = 0; dMessage (0,"warning: destroying world containing grouped joints"); } else { size_t sz = j->size(); j->~dxJoint(); dFree (j,sz); } j = nextj; } delete w; } 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 dWorldStep (dWorldID w, dReal stepsize) { dUASSERT (w,"bad world argument"); dUASSERT (stepsize > 0,"stepsize must be > 0"); dxProcessIslands (w,stepsize,&dInternalStepIsland); } void dWorldQuickStep (dWorldID w, dReal stepsize) { dUASSERT (w,"bad world argument"); dUASSERT (stepsize > 0,"stepsize must be > 0"); dxProcessIslands (w,stepsize,&dxQuickStepper); } 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 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 #ifdef dUSE_MALLOC_FOR_ALLOCA REGISTER_EXTENSION( ODE_EXT_malloc_not_alloca ) #endif #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 //********************************** // 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 size_t 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: ode-0.11.1/ode/src/testing.cpp0000644000076400007640000001463610765152110013021 00000000000000/************************************************************************* * * * 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 #include "config.h" #include #include #include "testing.h" #ifdef dDOUBLE static const dReal tol = 1.0e-9; #else static const dReal tol = 1.0e-5f; #endif // matrix header on the stack 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); if (strlen(mi->name) >= sizeof (mi->name)) dDebug (0,"name too long"); mat.push (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); 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; idata,mat[i]->size); dFree (mat[i],sizeof(dMatInfo)); } mat.setSize (0); afterfirst = 0; index = 0; } void dMatrixComparison::dump() { for (int i=0; iname,mat[i]->n,mat[i]->m); } //**************************************************************************** // unit test #include 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" ODE_API 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); } ode-0.11.1/ode/src/mat.h0000644000076400007640000000616007506200314011562 00000000000000/************************************************************************* * * * 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 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 (char *fmt = "%10.4f ", FILE *f=stdout); dReal maxDifference (const dMatrix &); }; #endif ode-0.11.1/ode/src/sphere.cpp0000644000076400007640000001764511142520432012631 00000000000000/************************************************************************* * * * 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 #include #include #include #include #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] = dDOT14(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] = dDOT14(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] = dDOT14(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(dDOT(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 = dDOT (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; } ode-0.11.1/ode/src/odemath.cpp0000644000076400007640000001236011102036010012737 00000000000000/************************************************************************* * * * 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 #include // get some math functions under windows #ifdef WIN32 #include #ifndef CYGWIN // added by andy for cygwin #undef copysign #define copysign(a,b) ((dReal)_copysign(a,b)) #endif // added by andy for cygwin #endif #undef dSafeNormalize3 #undef dSafeNormalize4 #undef dNormalize3 #undef dNormalize4 // 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. int _dSafeNormalize3 (dVector3 a) { dAASSERT (a); int idx; dReal aa[3], l; aa[0] = dFabs(a[0]); aa[1] = dFabs(a[1]); aa[2] = dFabs(a[2]); if (aa[1] > aa[0]) { if (aa[2] > aa[1]) { // aa[2] is largest idx = 2; } else { // aa[1] is largest idx = 1; } } else { if (aa[2] > aa[0]) {// aa[2] is largest idx = 2; } else { // aa[0] might be the largest if (aa[0] <= 0) { // aa[0] might is largest a[0] = 1; // if all a's are zero, this is where we'll end up. a[1] = 0; // return a default unit length vector. a[2] = 0; return 0; } else { idx = 0; } } } a[0] /= aa[idx]; a[1] /= aa[idx]; a[2] /= aa[idx]; l = dRecipSqrt (a[0]*a[0] + a[1]*a[1] + a[2]*a[2]); a[0] *= l; a[1] *= l; a[2] *= l; return 1; } /* OLD VERSION */ /* void dNormalize3 (dVector3 a) { dIASSERT (a); dReal l = dDOT(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; } } */ int dSafeNormalize3 (dVector3 a) { return _dSafeNormalize3(a); } void dNormalize3(dVector3 a) { _dNormalize3(a); } int _dSafeNormalize4 (dVector4 a) { dAASSERT (a); dReal l = dDOT(a,a)+a[3]*a[3]; if (l > 0) { l = dRecipSqrt(l); a[0] *= l; a[1] *= l; a[2] *= l; a[3] *= l; return 1; } else { a[0] = 1; a[1] = 0; a[2] = 0; a[3] = 0; return 0; } } int dSafeNormalize4 (dVector4 a) { return _dSafeNormalize4(a); } void dNormalize4(dVector4 a) { _dNormalize4(a); } void dPlaneSpace (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. */ void dOrthogonalizeR(dMatrix3 m) { dReal n0 = dLENGTHSQUARED(m); if (n0 != 1) dSafeNormalize3(m); // project row[0] on row[1], should be zero dReal proj = dDOT(m, m+4); if (proj != 0) { // Gram-Schmidt step on row[1] m[4] -= proj * m[0]; m[5] -= proj * m[1]; m[6] -= proj * m[2]; } dReal n1 = dLENGTHSQUARED(m+4); if (n1 != 1) dSafeNormalize3(m+4); /* just overwrite row[2], this makes sure the matrix is not a reflection */ dCROSS(m+8, =, m, m+4); m[3] = m[4+3] = m[8+3] = 0; } ode-0.11.1/ode/src/Makefile.am0000644000076400007640000001070211035613362012664 00000000000000SUBDIRS = joints AM_CPPFLAGS = -I$(top_srcdir)/include # convenience library to simulate per object cflags noinst_LTLIBRARIES = libfast.la libfast_la_CFLAGS = -O1 -Wall libfast_la_SOURCES = fastldlt.c fastltsolve.c fastdot.c fastlsolve.c lib_LTLIBRARIES = libode.la libode_la_LDFLAGS = @EXTRA_LIBTOOL_LDFLAGS@ @ODE_VERSION_INFO@ libode_la_LIBADD = libfast.la joints/libjoints.la # please, let's keep the filenames sorted libode_la_SOURCES = 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_util.cpp collision_util.h \ convex.cpp \ cylinder.cpp \ error.cpp \ export-dif.cpp \ heightfield.cpp heightfield.h \ lcp.cpp lcp.h \ mass.cpp \ mat.cpp mat.h \ matrix.cpp \ memory.cpp \ misc.cpp \ objects.h \ obstack.cpp obstack.h \ ode.cpp \ odeinit.cpp \ odemath.cpp \ odeou.h \ odetls.h \ plane.cpp \ quickstep.cpp quickstep.h \ ray.cpp \ rotation.cpp \ sphere.cpp \ step.cpp step.h \ stepfast.cpp \ testing.cpp testing.h \ timer.cpp \ 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_SOURCES+= collision_trimesh_gimpact.cpp libode_la_LIBADD += $(top_builddir)/GIMPACT/src/libGIMPACT.la libode_la_SOURCES += collision_trimesh_trimesh.cpp \ collision_trimesh_sphere.cpp \ collision_trimesh_ray.cpp \ collision_trimesh_opcode.cpp \ collision_trimesh_box.cpp \ collision_trimesh_ccylinder.cpp \ collision_trimesh_distance.cpp \ collision_trimesh_internal.h \ collision_cylinder_trimesh.cpp \ collision_trimesh_plane.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_trimesh.cpp \ collision_trimesh_trimesh_new.cpp \ collision_trimesh_sphere.cpp \ collision_trimesh_ray.cpp \ collision_trimesh_opcode.cpp \ collision_trimesh_box.cpp \ collision_trimesh_ccylinder.cpp \ collision_trimesh_distance.cpp \ collision_trimesh_internal.h \ collision_cylinder_trimesh.cpp \ collision_trimesh_plane.cpp endif ode-0.11.1/ode/src/capsule.cpp0000644000076400007640000003214111142520432012763 00000000000000/************************************************************************* * * * 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 #include #include #include #include #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 = dDOT14(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); // 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 = dDOT (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 = dDOT (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 = (dDOT14 (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 = dDOT (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 = dDOT (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; } ode-0.11.1/ode/src/array.h0000644000076400007640000001267410765152110012127 00000000000000/************************************************************************* * * * 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 #include "config.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 dArray : public dArrayBase { public: void equals (const dArray &x) { setSize (x.size()); memcpy (_data,x._data,x._size * sizeof(T)); } dArray () { constructor(); } dArray (const dArray &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 &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 &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 ode-0.11.1/ode/src/lcp.h0000644000076400007640000000516607557424167011610 00000000000000/************************************************************************* * * * 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_ void dSolveLCP (int n, dReal *A, dReal *x, dReal *b, dReal *w, int nub, dReal *lo, dReal *hi, int *findex); #endif ode-0.11.1/ode/src/ray.cpp0000644000076400007640000005330711142520432012131 00000000000000/************************************************************************* * * * 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 #include #include #include #include #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"); if (FirstContact){ g->gflags |= RAY_FIRSTCONTACT; } else g->gflags &= ~RAY_FIRSTCONTACT; if (BackfaceCull){ g->gflags |= RAY_BACKFACECULL; } else g->gflags &= ~RAY_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); } 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 = dDOT14(q,ray->final_posr->R+2); dReal C = dDOT(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 = dDOT41(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 = dDOT(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 = dDOT44(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 = dDOT(r,r); dReal B = 2*dDOT(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 = dDOT14(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] - dDOT (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 = dDOT14(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 David Walters (June 2006) 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 ); // // Compute some useful info // dVector3 q, r; dReal d, C, k; // Vector 'r', line segment from C to R (ray start) ( r = R - C ) r[ 0 ] = ray->final_posr->pos[0] - cyl->final_posr->pos[0]; r[ 1 ] = ray->final_posr->pos[1] - cyl->final_posr->pos[1]; r[ 2 ] = ray->final_posr->pos[2] - cyl->final_posr->pos[2]; // Distance that ray start is along cyl axis ( Z-axis direction ) d = dDOT41( cyl->final_posr->R + 2, r ); // // Compute vector 'q' representing the shortest line from R to the cylinder z-axis (Cz). // // Point on axis ( in world space ): cp = ( d * Cz ) + C // // Line 'q' from R to cp: q = cp - R // q = ( d * Cz ) + C - R // q = ( d * Cz ) - ( R - C ) q[ 0 ] = ( d * cyl->final_posr->R[0*4+2] ) - r[ 0 ]; q[ 1 ] = ( d * cyl->final_posr->R[1*4+2] ) - r[ 1 ]; q[ 2 ] = ( d * cyl->final_posr->R[2*4+2] ) - r[ 2 ]; // Compute square length of 'q'. Subtract from radius squared to // get square distance 'C' between the line q and the radius. // if C < 0 then ray start position is within infinite extension of cylinder C = dDOT( q, q ) - ( cyl->radius * cyl->radius ); // Compute the projection of ray direction normal onto cylinder direction normal. dReal uv = dDOT44( cyl->final_posr->R+2, ray->final_posr->R+2 ); // // Find ray collision with infinite cylinder // // Compute vector from end of ray direction normal to projection on cylinder direction normal. r[ 0 ] = ( uv * cyl->final_posr->R[0*4+2] ) - ray->final_posr->R[0*4+2]; r[ 1 ] = ( uv * cyl->final_posr->R[1*4+2] ) - ray->final_posr->R[1*4+2]; r[ 2 ] = ( uv * cyl->final_posr->R[2*4+2] ) - ray->final_posr->R[2*4+2]; // Quadratic Formula Magic // Compute discriminant 'k': // k < 0 : No intersection // k = 0 : Tangent // k > 0 : Intersection dReal A = dDOT( r, r ); dReal B = 2 * dDOT( q, r ); k = B*B - 4*A*C; // // Collision with Flat Caps ? // // No collision with cylinder edge. ( Use epsilon here or we miss some obvious cases ) if ( k < dEpsilon && C <= 0 ) { // The ray does not intersect the edge of the infinite cylinder, // but the ray start is inside and so must run parallel to the axis. // It may yet intersect an end cap. The following cases are valid: // -ve-cap , -half centre +half , +ve-cap // <<================|-------------------|------------->>>---|================>> // | | // | d-------------------> 1. // 2. d------------------> | // 3. <------------------d | // | <-------------------d 4. // | | // <<================|-------------------|------------->>>---|===============>> // Negative if the ray and cylinder axes point in opposite directions. const dReal uvsign = ( uv < 0 ) ? REAL( -1.0 ) : REAL( 1.0 ); // Negative if the ray start is inside the cylinder const dReal internal = ( d >= -half_length && d <= +half_length ) ? REAL( -1.0 ) : REAL( 1.0 ); // Ray and Cylinder axes run in the same direction ( cases 1, 2 ) // Ray and Cylinder axes run in opposite directions ( cases 3, 4 ) if ( ( ( uv > 0 ) && ( d + ( uvsign * ray->length ) < half_length * internal ) ) || ( ( uv < 0 ) && ( d + ( uvsign * ray->length ) > half_length * internal ) ) ) { return 0; // No intersection with caps or curved surface. } // Compute depth (distance from ray to cylinder) contact->depth = ( ( -uvsign * d ) - ( internal * half_length ) ); // Compute contact point. contact->pos[0] = ray->final_posr->pos[0] + ( contact->depth * ray->final_posr->R[0*4+2] ); contact->pos[1] = ray->final_posr->pos[1] + ( contact->depth * ray->final_posr->R[1*4+2] ); contact->pos[2] = ray->final_posr->pos[2] + ( contact->depth * ray->final_posr->R[2*4+2] ); // Compute reflected contact normal. contact->normal[0] = uvsign * ( cyl->final_posr->R[0*4+2] ); contact->normal[1] = uvsign * ( cyl->final_posr->R[1*4+2] ); contact->normal[2] = uvsign * ( cyl->final_posr->R[2*4+2] ); // Contact! return 1; } // // Collision with Curved Edge ? // if ( k > 0 ) { // Finish off quadratic formula to get intersection co-efficient k = dSqrt( k ); A = dRecip( 2 * A ); // Compute distance along line to contact point. dReal alpha = ( -B - k ) * A; if ( alpha < 0 ) { // Flip in the other direction. alpha = ( -B + k ) * A; } // Intersection point is within ray length? if ( alpha >= 0 && alpha <= ray->length ) { // The ray intersects the infinite cylinder! // Compute contact point. 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 is the vector from the cylinder centre to the contact point. q[0] = contact->pos[0] - cyl->final_posr->pos[0]; q[1] = contact->pos[1] - cyl->final_posr->pos[1]; q[2] = contact->pos[2] - cyl->final_posr->pos[2]; // Compute the distance along the cylinder axis of this contact point. d = dDOT14( q, cyl->final_posr->R+2 ); // Check to see if the intersection point is between the flat end caps if ( d >= -half_length && d <= +half_length ) { // Flip the normal if the start point is inside the cylinder. const dReal nsign = ( C < 0 ) ? REAL( -1.0 ) : REAL( 1.0 ); // Compute contact normal. contact->normal[0] = nsign * (contact->pos[0] - (cyl->final_posr->pos[0] + d*cyl->final_posr->R[0*4+2])); contact->normal[1] = nsign * (contact->pos[1] - (cyl->final_posr->pos[1] + d*cyl->final_posr->R[1*4+2])); contact->normal[2] = nsign * (contact->pos[2] - (cyl->final_posr->pos[2] + d*cyl->final_posr->R[2*4+2])); dNormalize3( contact->normal ); // Store depth. contact->depth = alpha; // Contact! return 1; } } } // No contact with anything. return 0; } ode-0.11.1/ode/src/collision_cylinder_sphere.cpp0000644000076400007640000002263711116517541016602 00000000000000/************************************************************************* * * * 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 #include #include #include #include #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; } ode-0.11.1/ode/src/joints/0000777000076400007640000000000011206343457012227 500000000000000ode-0.11.1/ode/src/joints/joints.h0000644000076400007640000000363411022071001013603 00000000000000/************************************************************************* * * * 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 #include "joint.h" #include "ball.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 ode-0.11.1/ode/src/joints/null.cpp0000644000076400007640000000411111021624601013602 00000000000000/************************************************************************* * * * 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 "null.h" #include "joint_internal.h" //**************************************************************************** // null joint dxJointNull::dxJointNull( dxWorld *w ) : dxJoint( w ) { } void dxJointNull::getInfo1( dxJoint::Info1 *info ) { info->m = 0; info->nub = 0; } void dxJointNull::getInfo2( dxJoint::Info2 *info ) { dDebug( 0, "this should never get called" ); } dJointType dxJointNull::type() const { return dJointTypeNull; } size_t dxJointNull::size() const { return sizeof( *this ); } ode-0.11.1/ode/src/joints/universal.cpp0000644000076400007640000005644411136406244014670 00000000000000/************************************************************************* * * * 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 "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::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( dxJoint::Info2 *info ) { // set the three ball-and-socket rows setBall( this, info, 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; dVector3 ax2_temp; // length 1 vector perpendicular to ax1 and ax2. Neither body can rotate // about this. dVector3 p; dReal k; // 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 ); k = dDOT( ax1, ax2 ); ax2_temp[0] = ax2[0] - k * ax1[0]; ax2_temp[1] = ax2[1] - k * ax1[1]; ax2_temp[2] = ax2[2] - k * ax1[2]; dCROSS( p, = , ax1, ax2_temp ); dNormalize3( p ); int s3 = 3 * info->rowskip; info->J1a[s3+0] = p[0]; info->J1a[s3+1] = p[1]; info->J1a[s3+2] = p[2]; if ( node[1].body ) { info->J2a[s3+0] = -p[0]; info->J2a[s3+1] = -p[1]; info->J2a[s3+2] = -p[2]; } // 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) info->c[3] = info->fps * info->erp * - k; // if the first angle is powered, or has joint limits, add in the stuff int row = 4 + limot1.addLimot( this, info, 4, ax1, 1 ); // if the second angle is powered, or has joint limits, add in more stuff limot2.addLimot( this, info, row, 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 = dDOT( axis, joint->node[0].body->avel ); if ( joint->node[1].body ) rate -= dDOT( 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 = dDOT( axis, joint->node[0].body->avel ); if ( joint->node[1].body ) rate -= dDOT( 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; } size_t 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(); } ode-0.11.1/ode/src/joints/lmotor.cpp0000644000076400007640000001270211021624601014151 00000000000000/************************************************************************* * * * 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 "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::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( dxJoint::Info2 *info ) { int row = 0; dVector3 ax[3]; computeGlobalAxes( ax ); for ( int i = 0;i < num;i++ ) { row += limot[i].addLimot( this, info, row, ax[i], 0 ); } } 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; } size_t dxJointLMotor::size() const { return sizeof( *this ); } ode-0.11.1/ode/src/joints/pr.h0000644000076400007640000000736511075411332012740 00000000000000/************************************************************************* * * * 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 *
 *                                        +-------------+
 *                                        |      x      |
 *                                        +------------\+
 * Prismatic articulation                   ..     ..
 *                       |                ..     ..
 *                      \/              ..      ..
 * +--------------+    --|        __..      ..  anchor2
 * |      x       | .....|.......(__)     ..
 * +--------------+    --|         ^     <
 *        |----------------------->|
 *            Offset               |--- Rotoide articulation
 * 
*/ 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 getInfo1( Info1* info ); virtual void getInfo2( Info2* info ); virtual dJointType type() const; virtual size_t size() const; virtual void setRelativeValues(); }; #endif ode-0.11.1/ode/src/joints/piston.cpp0000644000076400007640000005461411110612212014153 00000000000000/************************************************************************* * * * 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 "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 dDOT ( 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 ( dDOT ( ax, joint->node[0].body->lvel ) - dDOT ( ax, joint->node[1].body->lvel ) ); } else { dReal rate = dDOT ( 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 = dDOT ( axis, joint->node[0].body->avel ); if ( joint->node[1].body ) rate -= dDOT ( axis, joint->node[1].body->avel ); if ( joint->flags & dJOINT_REVERSE ) rate = - rate; return rate; } else return 0; } 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 ( dxJoint::Info2 *info ) { const int s0 = 0; const int s1 = info->rowskip; const int s2 = 2 * s1, s3 = 3 * s1 /*, s4=4*s1*/; const dReal k = info->fps * info->erp; // Pull out pos and R for both bodies. also get the `connection' // vector pos2-pos1. dReal *pos1, *pos2, *R1, *R2=0; 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 }; pos1 = node[0].body->posr.pos; R1 = node[0].body->posr.R; if ( node[1].body ) { pos2 = node[1].body->posr.pos; R2 = node[1].body->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 ) { dist[0] = pos1[0] - anchor2[0]; // Invert the value dist[1] = pos1[1] - anchor2[1]; dist[2] = pos1[2] - anchor2[2]; } else { dist[0] = anchor2[0] - pos1[0]; dist[1] = anchor2[1] - pos1[1]; dist[2] = anchor2[2] - pos1[2]; } } // ====================================================================== // 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 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 dOPE ( ( info->J1a ) + s0, = , p ); dOPE ( ( info->J1a ) + s1, = , q ); dVector3 b; if ( node[1].body ) { // LHS // info->J2a[s0+i] = -p[i] dOPE ( ( info->J2a ) + s0, = -, p ); dOPE ( ( info->J2a ) + s1, = -, q ); // Some math for the RHS dVector3 ax2; dMULTIPLY0_331 ( ax2, R2, axis2 ); dCROSS ( b, = , ax1, ax2 ); } else { // Some math for the RHS dCROSS ( b, = , ax1, axis2 ); } // RHS info->c[0] = k * dDOT ( p, b ); info->c[1] = k * dDOT ( 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 dCROSS ( ( info->J1a ) + s2, = , dist, p ); dCROSS ( ( info->J1a ) + s3, = , dist, q ); dOPE ( ( info->J1l ) + s2, = , p ); dOPE ( ( info->J1l ) + s3, = , q ); if ( node[1].body ) { // q x anchor2 instead of anchor2 x q since we want the negative value dCROSS ( ( info->J2a ) + s2, = , p, lanchor2 ); // The cross product is in reverse order since we want the negative value dCROSS ( ( info->J2a ) + s3, = , q, lanchor2 ); // info->J2l[s2+i] = -p[i]; dOPE ( ( info->J2l ) + s2, = -, p ); dOPE ( ( info->J2l ) + s3, = -, q ); } // 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 ); dOPE2 ( err, = , dist, -, err ); info->c[2] = k * dDOT ( p, err ); info->c[3] = k * dDOT ( q, err ); int row = 4; if ( node[1].body ) { row += limotP.addLimot ( this, info, 4, ax1, 0 ); } else if (flags & dJOINT_REVERSE ) { dVector3 rAx1; rAx1[0] = -ax1[0]; rAx1[1] = -ax1[1]; rAx1[2] = -ax1[2]; row += limotP.addLimot ( this, info, 4, rAx1, 0 ); } else row += limotP.addLimot ( this, info, 4, ax1, 0 ); limotR.addLimot ( this, info, row, 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 ) { 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 dOPEC ( 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 ); dCROSS ( 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 ); dCROSS ( ltd, = , c, axis ); dBodyAddTorque ( joint->node[1].body, ltd[0], ltd[1], ltd[2] ); } } dJointType dxJointPiston::type() const { return dJointTypePiston; } size_t 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 } } } ode-0.11.1/ode/src/joints/amotor.h0000644000076400007640000000503611021624601013605 00000000000000/************************************************************************* * * * 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 struct dxJointAMotor : public dxJoint { int num; // number of axes (0..3) int mode; // a dAMotorXXX constant int rel[3]; // what the axes are relative to (global,b1,b2) dVector3 axis[3]; // three axes dxJointLimitMotor limot[3]; // limit+motor info for axes dReal angle[3]; // user-supplied angles for axes // these vectors are used for calculating euler angles dVector3 reference1; // original axis[2], relative to body 1 dVector3 reference2; // original axis[0], relative to body 2 void computeGlobalAxes( dVector3 ax[3] ); void computeEulerAngles( dVector3 ax[3] ); void setEulerReferenceVectors(); dxJointAMotor( dxWorld *w ); virtual void getInfo1( Info1* info ); virtual void getInfo2( Info2* info ); virtual dJointType type() const; virtual size_t size() const; }; #endif ode-0.11.1/ode/src/joints/ball.h0000644000076400007640000000424111075411332013217 00000000000000/************************************************************************* * * * 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 getInfo1( Info1* info ); virtual void getInfo2( Info2* info ); virtual dJointType type() const; virtual size_t size() const; virtual void setRelativeValues(); }; #endif ode-0.11.1/ode/src/joints/contact.h0000644000076400007640000000370711021624601013742 00000000000000/************************************************************************* * * * 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 getInfo1( Info1* info ); virtual void getInfo2( Info2* info ); virtual dJointType type() const; virtual size_t size() const; }; #endif ode-0.11.1/ode/src/joints/lmotor.h0000644000076400007640000000375411021624601013625 00000000000000/************************************************************************* * * * 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 getInfo1( Info1* info ); virtual void getInfo2( Info2* info ); virtual dJointType type() const; virtual size_t size() const; }; #endif ode-0.11.1/ode/src/joints/plane2d.h0000644000076400007640000000415411021624601013631 00000000000000/************************************************************************* * * * 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 getInfo1( Info1* info ); virtual void getInfo2( Info2* info ); virtual dJointType type() const; virtual size_t size() const; }; #endif ode-0.11.1/ode/src/joints/ball.cpp0000644000076400007640000001105611075411332013554 00000000000000/************************************************************************* * * * 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 "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::getInfo1( dxJoint::Info1 *info ) { info->m = 3; info->nub = 3; } void dxJointBall::getInfo2( dxJoint::Info2 *info ) { info->erp = erp; info->cfm[0] = cfm; info->cfm[1] = cfm; info->cfm[2] = cfm; setBall( this, info, 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; } size_t dxJointBall::size() const { return sizeof( *this ); } void dxJointBall::setRelativeValues() { dVector3 anchor; dJointGetBallAnchor(this, anchor); setAnchors( this, anchor[0], anchor[1], anchor[2], anchor1, anchor2 ); } ode-0.11.1/ode/src/joints/piston.h0000644000076400007640000001214711075411332013625 00000000000000/************************************************************************* * * * 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 ///
///                              |- Anchor point
///      Body_1                  |                       Body_2
///      +---------------+       V                       +------------------+
///     /               /|                             /                  /|
///    /               / +       |--      ______      /                  / +
///   /      x        /./........x.......(_____()..../         x        /.......> axis
///  +---------------+ /         |--                +------------------+ /
///  |               |/                             |                  |/
///  +---------------+                              +------------------+
///          |                                                 |
///          |                                                 |
///          |------------------> <----------------------------|
///              anchor1                  anchor2
///
///
/// 
/// /// When the prismatic joint as been elongated (i.e. dJointGetPistonPosition) /// return a value > 0 ///
///                                   |- Anchor point
///      Body_1                       |                       Body_2
///      +---------------+            V                       +------------------+
///     /               /|                                  /                  /|
///    /               / +            |--      ______      /                  / +
///   /      x        /./........_____x.......(_____()..../         x        /.......> axis
///  +---------------+ /              |--                +------------------+ /
///  |               |/                                  |                  |/
///  +---------------+                                   +------------------+
///          |                                                      |
///          |                                                      |
///          |------------------>      <----------------------------|
///              anchor1         |----|         anchor2
///                                ^
///                                |-- This is what dJointGetPistonPosition will
///                                    return
/// 
//////////////////////////////////////////////////////////////////////////////// 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 getInfo1( Info1* info ); virtual void getInfo2( Info2* info ); virtual dJointType type() const; virtual size_t size() const; virtual void setRelativeValues(); void computeInitialRelativeRotation(); }; #endif ode-0.11.1/ode/src/joints/pu.cpp0000644000076400007640000006406711135652511013303 00000000000000/************************************************************************* * * * 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 "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 dDOT( 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; dOP( 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; dCROSS( lvel1, = , r, joint->node[0].body->avel ); // lvel1 += joint->node[0].body->lvel; dOPE( 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; dCROSS( lvel2, = , anchor2, joint->node[1].body->avel ); // lvel1 -= lvel2 + joint->node[1].body->lvel; dOPE2( lvel1, -= , lvel2, + , joint->node[1].body->lvel ); return dDOT( axP1, lvel1 ); } else { dReal rate = dDOT( axP1, lvel1 ); return ( (joint->flags & dJOINT_REVERSE) ? -rate : rate); } } return 0.0; } 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( dxJoint::Info2 *info ) { const int s0 = 0; const int s1 = info->rowskip; const int s2 = 2 * s1; const dReal k = info->fps * info->erp; // pull out pos and R for both bodies. also get the `connection' // vector pos2-pos1. dReal *pos1, *pos2 = 0, *R1, *R2 = 0; pos1 = node[0].body->posr.pos; R1 = node[0].body->posr.R; if ( node[1].body ) { pos2 = node[1].body->posr.pos; R2 = node[1].body->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 dist; dVector3 wanchor2 = {0,0,0}; if ( node[1].body ) { 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 ) { // Invert the sign of dist dist[0] = pos1[0] - anchor2[0]; dist[1] = pos1[1] - anchor2[1]; dist[2] = pos1[2] - anchor2[2]; } else { dist[0] = anchor2[0] - pos1[0]; dist[1] = anchor2[1] - pos1[1]; dist[2] = anchor2[2] - pos1[2]; } } dVector3 q; // Temporary axis vector // Will be used at 2 places with 2 different meaning // ====================================================================== // Work on the angular part (i.e. row 0) // // The axis perpendicular to both axis1 and axis2 should be the only unconstrained // rotational axis, the angular velocity of the two bodies perpendicular to // the rotoide axes should be equal. Thus the constraint equations are // p*w1 - p*w2 = 0 // where p is a unit vector perpendicular to both axis1 and axis2 // and w1 and w2 are the angular velocity vectors of the two bodies. dVector3 ax1, ax2; getAxes( ax1, ax2 ); dReal val = dDOT( ax1, ax2 ); q[0] = ax2[0] - val * ax1[0]; q[1] = ax2[1] - val * ax1[1]; q[2] = ax2[2] - val * ax1[2]; dVector3 p; dCROSS( p, = , ax1, q ); dNormalize3( p ); // info->J1a[s0+i] = p[i]; dOPE(( info->J1a ) + s0, = , p ); if ( node[1].body ) { // info->J2a[s0+i] = -p[i]; dOPE(( info->J2a ) + s0, = -, 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) info->c[0] = k * - val; // ========================================================================== // Work on the linear part (i.e rows 1 and 2) // // 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 axisP is disregarded. // // p1 + R1 dist' = p2 + R2 anchor2' // v1 + w1 x R1 dist' + v_p = v2 + w2 x R2 anchor2' // v_p is speed of prismatic joint (i.e. elongation rate) // Since the constraints are perpendicular to v_p we have: // e1 dot v_p = 0 and e2 dot v_p = 0 // e1 dot ( v1 + w1 x dist = v2 + w2 x anchor2 ) // e2 dot ( v1 + w1 x dist = v2 + w2 x anchor2 ) // == // e1 . v1 + e1 . w1 x dist = e1 . v2 + e1 . w2 x anchor2 // since a . (b x c) = - b . (a x c) = - (a x c) . b // and a x b = - b x a // e1 . v1 - e1 x dist . w1 - e1 . v2 - (- e1 x anchor2 . w2) = 0 // e1 . v1 + dist x e1 . w1 - e1 . v2 - anchor2 x e1 . w2 = 0 // Coeff for 1er line of: J1l => e1, J2l => -e1 // Coeff for 2er line of: J1l => e2, J2l => -ax2 // Coeff for 1er line of: J1a => dist x e1, J2a => - anchor2 x e1 // Coeff for 2er line of: J1a => dist x e2, J2a => - anchor2 x e2 // e1 and e2 are perpendicular to axP // so e1 = ax1 and e2 = ax1 x axP // N.B. ax2 is not always perpendicular to axP since it is attached to body 2 dCROSS( q , = , ax1, axP ); dMULTIPLY0_331( axP, R1, axisP1 ); dCROSS(( info->J1a ) + s1, = , dist, ax1 ); dCROSS(( info->J1a ) + s2, = , dist, q ); // info->J1l[s1+i] = ax[i]; dOPE(( info->J1l ) + s1, = , ax1 ); // info->J1l[s2+i] = q[i]; dOPE(( info->J1l ) + s2, = , q ); if ( node[1].body ) { // Calculate anchor2 in world coordinate // q x anchor2 instead of anchor2 x q since we want the negative value dCROSS(( info->J2a ) + s1, = , ax1, wanchor2 ); // The cross product is in reverse order since we want the negative value dCROSS(( info->J2a ) + s2, = , q, wanchor2 ); // info->J2l[s1+i] = -ax1[i]; dOPE(( info->J2l ) + s1, = -, ax1 ); // info->J2l[s2+i] = -ax1[i]; dOPE(( info->J2l ) + s2, = -, q ); } // 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 1 and 2 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, anchor1 ); // err[i] = dist[i] - err[i]; dOPE2( err, = , dist, -, err ); info->c[1] = k * dDOT( ax1, err ); info->c[2] = k * dDOT( q, err ); int row = 3 + limot1.addLimot( this, info, 3, ax1, 1 ); if ( node[1].body || !(flags & dJOINT_REVERSE) ) limotP.addLimot( this, info, row, axP, 0 ); else { axP[0] = -axP[0]; axP[1] = -axP[1]; axP[2] = -axP[2]; limotP.addLimot ( this, info, row, axP, 0 ); } } 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: *
 * 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
 * 
* @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: *
 * 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
 * 
* @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 = dDOT( axis, joint->node[0].body->avel ); if ( joint->node[1].body ) rate -= dDOT( 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 = dDOT( axis, joint->node[0].body->avel ); if ( joint->node[1].body ) rate -= dDOT( 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]; dOPE( 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; } size_t 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], NULL, axisP1 ); computeInitialRelativeRotations(); } ode-0.11.1/ode/src/joints/slider.cpp0000644000076400007640000002735711110567764014152 00000000000000/************************************************************************* * * * 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 "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 dDot 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 dDOT ( 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 dDOT ( ax1, joint->node[0].body->lvel ) - dDOT ( ax1, joint->node[1].body->lvel ); } else { dReal rate = dDOT ( ax1, joint->node[0].body->lvel ); if ( joint->flags & dJOINT_REVERSE ) rate = - rate; return rate; } } 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 ( dxJoint::Info2 *info ) { int i, s = info->rowskip; int s3 = 3 * s, s4 = 4 * s; // pull out pos and R for both bodies. also get the `connection' // vector pos2-pos1. dReal *pos1, *pos2, *R1, *R2; dVector3 c; pos1 = node[0].body->posr.pos; R1 = node[0].body->posr.R; if ( node[1].body ) { pos2 = node[1].body->posr.pos; R2 = node[1].body->posr.R; for ( i = 0; i < 3; i++ ) c[i] = pos2[i] - pos1[i]; } else { pos2 = 0; R2 = 0; } // 3 rows to make body rotations equal setFixedOrientation ( this, info, qrel, 0 ); // 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. 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 ); if ( node[1].body ) { dVector3 tmp; dCROSS ( tmp, = REAL ( 0.5 ) * , c, p ); for ( i = 0; i < 3; i++ ) info->J1a[s3+i] = tmp[i]; for ( i = 0; i < 3; i++ ) info->J2a[s3+i] = tmp[i]; dCROSS ( tmp, = REAL ( 0.5 ) * , c, q ); for ( i = 0; i < 3; i++ ) info->J1a[s4+i] = tmp[i]; for ( i = 0; i < 3; i++ ) info->J2a[s4+i] = tmp[i]; for ( i = 0; i < 3; i++ ) info->J2l[s3+i] = -p[i]; for ( i = 0; i < 3; i++ ) info->J2l[s4+i] = -q[i]; } for ( i = 0; i < 3; i++ ) info->J1l[s3+i] = p[i]; for ( i = 0; i < 3; i++ ) info->J1l[s4+i] = q[i]; // 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 = info->fps * info->erp; if ( node[1].body ) { dVector3 ofs; // offset point in global coordinates dMULTIPLY0_331 ( ofs, R2, offset ); for ( i = 0; i < 3; i++ ) c[i] += ofs[i]; info->c[3] = k * dDOT ( p, c ); info->c[4] = k * dDOT ( q, c ); } else { dVector3 ofs; // offset point in global coordinates for ( i = 0; i < 3; i++ ) ofs[i] = offset[i] - pos1[i]; info->c[3] = k * dDOT ( p, ofs ); info->c[4] = k * dDOT ( q, ofs ); if ( flags & dJOINT_REVERSE ) for ( i = 0; i < 3; ++i ) ax1[i] = -ax1[i]; } // if the slider is powered, or has joint limits, add in the extra row limot.addLimot ( this, info, 5, 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] ); dCROSS ( 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; } size_t 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]; } } ode-0.11.1/ode/src/joints/pr.cpp0000644000076400007640000004415511111066476013277 00000000000000/************************************************************************* * * * 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 "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 dDOT( 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 dDOT( ax1, joint->node[0].body->lvel ) - dDOT( ax1, lv2 ); } else { dReal rate = dDOT( 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 = dDOT( axis, joint->node[0].body->avel ); if ( joint->node[1].body ) rate -= dDOT( axis, joint->node[1].body->avel ); if ( joint->flags & dJOINT_REVERSE ) rate = -rate; return rate; } else return 0; } 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( dxJoint::Info2 *info ) { int s = info->rowskip; int s2 = 2 * s; int s3 = 3 * s; //int s4= 4*s; dReal k = info->fps * info->erp; 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 *pos1, *pos2 = 0, *R1, *R2 = 0; pos1 = node[0].body->posr.pos; R1 = node[0].body->posr.R; if ( node[1].body ) { pos2 = node[1].body->posr.pos; R2 = node[1].body->posr.R; } 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 } 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 ( node[1].body ) { // 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 ) { dist[0] = pos1[0] - anchor2[0]; // Invert the value dist[1] = pos1[1] - anchor2[1]; dist[2] = pos1[2] - anchor2[2]; } else { dist[0] = anchor2[0] - pos1[0]; dist[1] = anchor2[1] - pos1[1]; dist[2] = anchor2[2] - pos1[2]; } } // ====================================================================== // 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 ax1; dMULTIPLY0_331( ax1, node[0].body->posr.R, axisR1 ); dCROSS( q , = , ax1, axP ); info->J1a[0] = axP[0]; info->J1a[1] = axP[1]; info->J1a[2] = axP[2]; info->J1a[s+0] = q[0]; info->J1a[s+1] = q[1]; info->J1a[s+2] = q[2]; if ( node[1].body ) { info->J2a[0] = -axP[0]; info->J2a[1] = -axP[1]; info->J2a[2] = -axP[2]; info->J2a[s+0] = -q[0]; info->J2a[s+1] = -q[1]; info->J2a[s+2] = -q[2]; } // 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. dVector3 ax2; if ( node[1].body ) { dMULTIPLY0_331( ax2, R2, axisR2 ); } else { ax2[0] = axisR2[0]; ax2[1] = axisR2[1]; ax2[2] = axisR2[2]; } dVector3 b; dCROSS( b, = , ax1, ax2 ); info->c[0] = k * dDOT( b, axP ); info->c[1] = k * dDOT( 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 dCROSS(( info->J1a ) + s2, = , dist, ax1 ); dCROSS(( info->J1a ) + s3, = , dist, q ); info->J1l[s2+0] = ax1[0]; info->J1l[s2+1] = ax1[1]; info->J1l[s2+2] = ax1[2]; info->J1l[s3+0] = q[0]; info->J1l[s3+1] = q[1]; info->J1l[s3+2] = q[2]; if ( node[1].body ) { // ax2 x anchor2 instead of anchor2 x ax2 since we want the negative value dCROSS(( info->J2a ) + s2, = , ax2, wanchor2 ); // since ax1 == ax2 // The cross product is in reverse order since we want the negative value dCROSS(( info->J2a ) + s3, = , q, wanchor2 ); info->J2l[s2+0] = -ax1[0]; info->J2l[s2+1] = -ax1[1]; info->J2l[s2+2] = -ax1[2]; info->J2l[s3+0] = -q[0]; info->J2l[s3+1] = -q[1]; info->J2l[s3+2] = -q[2]; } // 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 ); err[0] = dist[0] - err[0]; err[1] = dist[1] - err[1]; err[2] = dist[2] - err[2]; info->c[2] = k * dDOT( ax1, err ); info->c[3] = k * dDOT( q, err ); int row = 4; if ( node[1].body || !(flags & dJOINT_REVERSE) ) { row += limotP.addLimot ( this, info, 4, axP, 0 ); } else { dVector3 rAxP; rAxP[0] = -axP[0]; rAxP[1] = -axP[1]; rAxP[2] = -axP[2]; row += limotP.addLimot ( this, info, 4, rAxP, 0 ); } limotR.addLimot ( this, info, row, 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; } size_t 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(); } ode-0.11.1/ode/src/joints/joint.cpp0000644000076400007640000005661611123307602013776 00000000000000/************************************************************************* * * * 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 #include #include #include #include "joint.h" #include "joint_internal.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() { } bool dxJoint::isEnabled() const { return ( (flags & dJOINT_DISABLED) == 0 && (node[0].body->invMass > 0 || (node[1].body && node[1].body->invMass > 0)) ); } //**************************************************************************** // 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, dxJoint::Info2 *info, dVector3 anchor1, dVector3 anchor2 ) { // anchor points in global coordinates with respect to body PORs. dVector3 a1, a2; int s = info->rowskip; // set jacobian info->J1l[0] = 1; info->J1l[s+1] = 1; info->J1l[2*s+2] = 1; dMULTIPLY0_331( a1, joint->node[0].body->posr.R, anchor1 ); dCROSSMAT( info->J1a, a1, s, -, + ); if ( joint->node[1].body ) { info->J2l[0] = -1; info->J2l[s+1] = -1; info->J2l[2*s+2] = -1; dMULTIPLY0_331( a2, joint->node[1].body->posr.R, anchor2 ); dCROSSMAT( info->J2a, a2, s, + , - ); } // set right hand side dReal k = info->fps * info->erp; if ( joint->node[1].body ) { for ( int j = 0; j < 3; j++ ) { info->c[j] = k * ( a2[j] + joint->node[1].body->posr.pos[j] - a1[j] - joint->node[0].body->posr.pos[j] ); } } else { for ( int j = 0; j < 3; j++ ) { info->c[j] = k * ( anchor2[j] - a1[j] - joint->node[0].body->posr.pos[j] ); } } } // 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, dxJoint::Info2 *info, dVector3 anchor1, dVector3 anchor2, dVector3 axis, dReal erp1 ) { // anchor points in global coordinates with respect to body PORs. dVector3 a1, a2; int i, s = info->rowskip; // 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 for ( i = 0; i < 3; i++ ) info->J1l[i] = axis[i]; for ( i = 0; i < 3; i++ ) info->J1l[s+i] = q1[i]; for ( i = 0; i < 3; i++ ) info->J1l[2*s+i] = q2[i]; dMULTIPLY0_331( a1, joint->node[0].body->posr.R, anchor1 ); dCROSS( info->J1a, = , a1, axis ); dCROSS( info->J1a + s, = , a1, q1 ); dCROSS( info->J1a + 2*s, = , a1, q2 ); if ( joint->node[1].body ) { for ( i = 0; i < 3; i++ ) info->J2l[i] = -axis[i]; for ( i = 0; i < 3; i++ ) info->J2l[s+i] = -q1[i]; for ( i = 0; i < 3; i++ ) info->J2l[2*s+i] = -q2[i]; dMULTIPLY0_331( a2, joint->node[1].body->posr.R, anchor2 ); dCROSS( info->J2a, = -, a2, axis ); dCROSS( info->J2a + s, = -, a2, q1 ); dCROSS( info->J2a + 2*s, = -, a2, q2 ); } // set right hand side - measure error along (axis,q1,q2) dReal k1 = info->fps * erp1; dReal k = info->fps * info->erp; for ( i = 0; i < 3; i++ ) a1[i] += joint->node[0].body->posr.pos[i]; if ( joint->node[1].body ) { for ( i = 0; i < 3; i++ ) a2[i] += joint->node[1].body->posr.pos[i]; info->c[0] = k1 * ( dDOT( axis, a2 ) - dDOT( axis, a1 ) ); info->c[1] = k * ( dDOT( q1, a2 ) - dDOT( q1, a1 ) ); info->c[2] = k * ( dDOT( q2, a2 ) - dDOT( q2, a1 ) ); } else { info->c[0] = k1 * ( dDOT( axis, anchor2 ) - dDOT( axis, a1 ) ); info->c[1] = k * ( dDOT( q1, anchor2 ) - dDOT( q1, a1 ) ); info->c[2] = k * ( dDOT( q2, anchor2 ) - dDOT( q2, a1 ) ); } } // set three orientation rows in the constraint equation, and the // corresponding right hand side. void setFixedOrientation( dxJoint *joint, dxJoint::Info2 *info, dQuaternion qrel, int start_row ) { int s = info->rowskip; int start_index = start_row * s; // 3 rows to make body rotations equal info->J1a[start_index] = 1; info->J1a[start_index + s + 1] = 1; info->J1a[start_index + s*2+2] = 1; if ( joint->node[1].body ) { info->J2a[start_index] = -1; info->J2a[start_index + s+1] = -1; info->J2a[start_index + s*2+2] = -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; if ( joint->node[1].body ) { dQuaternion qq; dQMultiply1( qq, joint->node[0].body->q, joint->node[1].body->q ); dQMultiply2( qerr, qq, qrel ); } else { dQMultiply3( qerr, joint->node[0].body->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, joint->node[0].body->posr.R, qerr + 1 ); // @@@ bad SIMD padding! dReal k = info->fps * info->erp; info->c[start_row] = 2 * k * e[0]; info->c[start_row+1] = 2 * k * e[1]; info->c[start_row+2] = 2 * k * e[2]; } // compute anchor points relative to bodies void setAnchors( dxJoint *j, dReal x, dReal y, dReal z, dVector3 anchor1, dVector3 anchor2 ) { if ( j->node[0].body ) { dReal q[4]; q[0] = x - j->node[0].body->posr.pos[0]; q[1] = y - j->node[0].body->posr.pos[1]; q[2] = z - j->node[0].body->posr.pos[2]; q[3] = 0; dMULTIPLY1_331( anchor1, j->node[0].body->posr.R, q ); if ( j->node[1].body ) { q[0] = x - j->node[1].body->posr.pos[0]; q[1] = y - j->node[1].body->posr.pos[1]; q[2] = z - j->node[1].body->posr.pos[2]; q[3] = 0; dMULTIPLY1_331( anchor2, j->node[1].body->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 ) { if ( j->node[0].body ) { dReal q[4]; q[0] = x; q[1] = y; q[2] = z; q[3] = 0; dNormalize3( q ); if ( axis1 ) { dMULTIPLY1_331( axis1, j->node[0].body->posr.R, q ); axis1[3] = 0; } if ( axis2 ) { if ( j->node[1].body ) { dMULTIPLY1_331( axis2, j->node[1].body->posr.R, q ); } else { axis2[0] = x; axis2[1] = y; axis2[2] = z; } axis2[3] = 0; } } } void getAnchor( dxJoint *j, dVector3 result, dVector3 anchor1 ) { if ( j->node[0].body ) { dMULTIPLY0_331( result, j->node[0].body->posr.R, anchor1 ); result[0] += j->node[0].body->posr.pos[0]; result[1] += j->node[0].body->posr.pos[1]; result[2] += j->node[0].body->posr.pos[2]; } } void getAnchor2( dxJoint *j, dVector3 result, dVector3 anchor2 ) { if ( j->node[1].body ) { dMULTIPLY0_331( result, j->node[1].body->posr.R, anchor2 ); result[0] += j->node[1].body->posr.pos[0]; result[1] += j->node[1].body->posr.pos[1]; result[2] += j->node[1].body->posr.pos[2]; } else { result[0] = anchor2[0]; result[1] = anchor2[1]; result[2] = anchor2[2]; } } void getAxis( dxJoint *j, dVector3 result, dVector3 axis1 ) { if ( j->node[0].body ) { dMULTIPLY0_331( result, j->node[0].body->posr.R, axis1 ); } } void getAxis2( dxJoint *j, dVector3 result, dVector3 axis2 ) { if ( j->node[1].body ) { dMULTIPLY0_331( result, j->node[1].body->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 = ( dDOT( 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 ) { 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; } } int dxJointLimitMotor::testRotationalLimit( dReal angle ) { if ( angle <= lostop ) { limit = 1; limit_err = angle - lostop; return 1; } else if ( angle >= histop ) { limit = 2; limit_err = angle - histop; return 1; } else { limit = 0; return 0; } } int dxJointLimitMotor::addLimot( dxJoint *joint, dxJoint::Info2 *info, int row, const dVector3 ax1, int rotational ) { int srow = row * info->rowskip; // if the joint is powered, or has joint limits, add in the extra row int powered = fmax > 0; if ( powered || limit ) { dReal *J1 = rotational ? info->J1a : info->J1l; dReal *J2 = rotational ? info->J2a : info->J2l; J1[srow+0] = ax1[0]; J1[srow+1] = ax1[1]; J1[srow+2] = ax1[2]; if ( joint->node[1].body ) { J2[srow+0] = -ax1[0]; J2[srow+1] = -ax1[1]; J2[srow+2] = -ax1[2]; } // 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 && joint->node[1].body ) { 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] ); dCROSS( ltd, = , c, ax1 ); info->J1a[srow+0] = ltd[0]; info->J1a[srow+1] = ltd[1]; info->J1a[srow+2] = ltd[2]; info->J2a[srow+0] = ltd[0]; info->J2a[srow+1] = ltd[1]; info->J2a[srow+2] = ltd[2]; } // if we're limited low and high simultaneously, the joint motor is // ineffective if ( limit && ( lostop == histop ) ) powered = 0; if ( powered ) { info->cfm[row] = normal_cfm; if ( ! limit ) { info->c[row] = vel; info->lo[row] = -fmax; info->hi[row] = 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; if ( rotational ) { dBodyAddTorque( joint->node[0].body, -fm*ax1[0], -fm*ax1[1], -fm*ax1[2] ); if ( joint->node[1].body ) dBodyAddTorque( joint->node[1].body, fm*ax1[0], fm*ax1[1], fm*ax1[2] ); } else { dBodyAddForce( joint->node[0].body, -fm*ax1[0], -fm*ax1[1], -fm*ax1[2] ); if ( joint->node[1].body ) { dBodyAddForce( joint->node[1].body, fm*ax1[0], fm*ax1[1], fm*ax1[2] ); // linear limot torque decoupling step: refer to above discussion dBodyAddTorque( joint->node[0].body, -fm*ltd[0], -fm*ltd[1], -fm*ltd[2] ); dBodyAddTorque( joint->node[1].body, -fm*ltd[0], -fm*ltd[1], -fm*ltd[2] ); } } } } if ( limit ) { dReal k = info->fps * stop_erp; info->c[row] = -k * limit_err; info->cfm[row] = stop_cfm; if ( lostop == histop ) { // limited low and high simultaneously info->lo[row] = -dInfinity; info->hi[row] = dInfinity; } else { if ( limit == 1 ) { // low limit info->lo[row] = 0; info->hi[row] = dInfinity; } else { // high limit info->lo[row] = -dInfinity; info->hi[row] = 0; } // deal with bounce if ( bounce > 0 ) { // calculate joint velocity dReal vel; if ( rotational ) { vel = dDOT( joint->node[0].body->avel, ax1 ); if ( joint->node[1].body ) vel -= dDOT( joint->node[1].body->avel, ax1 ); } else { vel = dDOT( joint->node[0].body->lvel, ax1 ); if ( joint->node[1].body ) vel -= dDOT( 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 > info->c[row] ) info->c[row] = newc; } } else { // high limit - all those computations are reversed if ( vel > 0 ) { dReal newc = -bounce * vel; if ( newc < info->c[row] ) info->c[row] = newc; } } } } } return 1; } else return 0; } // Local Variables: // mode:c++ // c-basic-offset:4 // End: ode-0.11.1/ode/src/joints/universal.h0000644000076400007640000000514711075411332014323 00000000000000/************************************************************************* * * * 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 getInfo1( Info1* info ); virtual void getInfo2( Info2* info ); virtual dJointType type() const; virtual size_t size() const; virtual void setRelativeValues(); }; #endif ode-0.11.1/ode/src/joints/Makefile.in0000644000076400007640000003740411206343412014207 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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/src/joints DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ode/src/config.h CONFIG_CLEAN_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libjoints_la_LIBADD = am_libjoints_la_OBJECTS = joint.lo ball.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) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libjoints_la_SOURCES) DIST_SOURCES = $(libjoints_la_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ 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@ 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@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODE_PRECISION = @ODE_PRECISION@ ODE_RELEASE = @ODE_RELEASE@ 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_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ 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@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ 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 noinst_LTLIBRARIES = libjoints.la libjoints_la_SOURCES = joints.h \ joint.h joint.cpp \ joint_internal.h \ ball.h ball.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'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign ode/src/joints/Makefile .PRECIOUS: 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 clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libjoints.la: $(libjoints_la_OBJECTS) $(libjoints_la_DEPENDENCIES) $(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)/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)/universal.Plo@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-am info-am: install-data-am: install-dvi: install-dvi-am 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 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 all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES ctags 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 uninstall uninstall-am # 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: ode-0.11.1/ode/src/joints/joint.h0000644000076400007640000001515211123307602013431 00000000000000/************************************************************************* * * * 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 "../objects.h" #include #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 }; // 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 { int m, nub; }; // info returned by getInfo2 function struct Info2 { // integrator parameters: frames per second (1/stepsize), default error // reduction parameter (0..1). dReal fps, erp; // for the first and second body, pointers to two (linear and angular) // n*3 jacobian sub matrices, stored by rows. these matrices will have // been initialized to 0 on entry. if the second body is zero then the // J2xx pointers may be 0. dReal *J1l, *J1a, *J2l, *J2a; // elements to jump from one row to the next in J's int rowskip; // 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 *c, *cfm; // lo and hi limits for variables (set to -/+ infinity on entry). dReal *lo, *hi; // 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; }; 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(); virtual void getInfo1( Info1* info ) = 0; virtual void getInfo2( Info2* info ) = 0; virtual dJointType type() const = 0; virtual size_t 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 { int num; // number of joints on the stack dObStack 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 ); int testRotationalLimit( dReal angle ); int addLimot( dxJoint *joint, dxJoint::Info2 *info, int row, const dVector3 ax1, int rotational ); }; #endif // Local Variables: // mode:c++ // c-basic-offset:4 // End: ode-0.11.1/ode/src/joints/joint_internal.h0000644000076400007640000000547711021624601015334 00000000000000/************************************************************************* * * * 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_NTERNAL_H_ #define _ODE_JOINT_INTERNAL_H_ #include "config.h" #include #include #include #include #define checktype(j,t) dUASSERT(j->type() == dJointType##t, \ "joint type is not " #t) void setBall( dxJoint *joint, dxJoint::Info2 *info, dVector3 anchor1, dVector3 anchor2 ); void setBall2( dxJoint *joint, dxJoint::Info2 *info, dVector3 anchor1, dVector3 anchor2, dVector3 axis, dReal erp1 ); 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 ); void setFixedOrientation( dxJoint *joint, dxJoint::Info2 *info, dQuaternion qrel, int start_row ); #endif ode-0.11.1/ode/src/joints/pu.h0000644000076400007640000000735511075411332012742 00000000000000/************************************************************************* * * * 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. *
 *                                                 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)
 * 
*/ 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 getInfo1( Info1* info ); virtual void getInfo2( Info2* info ); virtual dJointType type() const; virtual size_t size() const; virtual void setRelativeValues(); }; #endif ode-0.11.1/ode/src/joints/fixed.cpp0000644000076400007640000001260211025774723013752 00000000000000/************************************************************************* * * * 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 "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::getInfo1 ( dxJoint::Info1 *info ) { info->m = 6; info->nub = 6; } void dxJointFixed::getInfo2 ( dxJoint::Info2 *info ) { int s = info->rowskip; // Three rows for orientation setFixedOrientation ( this, info, qrel, 3 ); // Three rows for position. // set jacobian info->J1l[0] = 1; info->J1l[s+1] = 1; info->J1l[2*s+2] = 1; info->erp = erp; info->cfm[0] = cfm; info->cfm[1] = cfm; info->cfm[2] = cfm; dVector3 ofs; dMULTIPLY0_331 ( ofs, node[0].body->posr.R, offset ); if ( node[1].body ) { dCROSSMAT ( info->J1a, ofs, s, + , - ); info->J2l[0] = -1; info->J2l[s+1] = -1; info->J2l[2*s+2] = -1; } // set right hand side for the first three rows (linear) dReal k = info->fps * info->erp; if ( node[1].body ) { for ( int j = 0; j < 3; j++ ) info->c[j] = k * ( node[1].body->posr.pos[j] - node[0].body->posr.pos[j] + ofs[j] ); } else { for ( int j = 0; j < 3; j++ ) info->c[j] = k * ( offset[j] - node[0].body->posr.pos[j] ); } } 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; } size_t 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]; } } } ode-0.11.1/ode/src/joints/hinge2.cpp0000644000076400007640000003310611075411332014016 00000000000000/************************************************************************* * * * 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 "hinge2.h" #include "joint_internal.h" //**************************************************************************** // hinge 2. note that this joint must be attached to two bodies for it to work dReal dxJointHinge2::measureAngle() const { dVector3 a1, a2; dMULTIPLY0_331( a1, node[1].body->posr.R, axis2 ); dMULTIPLY1_331( a2, node[0].body->posr.R, a1 ); dReal x = dDOT( v1, a2 ); dReal y = dDOT( v2, a2 ); 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::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 = measureAngle(); 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); dCROSS (axCross,=,ax1,ax2); sin_angle = dSqrt (axCross[0]*axCross[0] + axCross[1]*axCross[1] + axCross[2]*axCross[2]); cos_angle = dDOT (ax1,ax2); } void dxJointHinge2::getInfo2( dxJoint::Info2 *info ) { // get information we need to set the hinge row dReal s, c; dVector3 q; const dxJointHinge2 *joint = this; dVector3 ax1, ax2; joint->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, info, anchor1, anchor2, ax1, susp_erp ); // set the hinge row int s3 = 3 * info->rowskip; info->J1a[s3+0] = q[0]; info->J1a[s3+1] = q[1]; info->J1a[s3+2] = q[2]; if ( joint->node[1].body ) { info->J2a[s3+0] = -q[0]; info->J2a[s3+1] = -q[1]; info->J2a[s3+2] = -q[2]; } // 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 = info->fps * info->erp; info->c[3] = k * ( c0 * s - joint->s0 * c ); // if the axis1 hinge is powered, or has joint limits, add in more stuff int row = 4 + limot1.addLimot( this, info, 4, ax1, 1 ); // if the axis2 hinge is powered, add in more stuff limot2.addLimot( this, info, row, ax2, 1 ); // set parameter for the suspension info->cfm[0] = susp_cfm; } // 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 ); // don't do anything if the axis1 or axis2 vectors are zero or the same if (( ax1[0] == 0 && ax1[1] == 0 && ax1[2] == 0 ) || ( ax2[0] == 0 && ax2[1] == 0 && ax2[2] == 0 ) || ( ax1[0] == ax2[0] && ax1[1] == ax2[1] && ax1[2] == ax2[2] ) ) return; // modify axis 2 so it's perpendicular to axis 1 dReal k = dDOT( ax1, ax2 ); for ( int i = 0; i < 3; i++ ) ax2[i] -= k * ax1[i]; dNormalize3( ax2 ); // make v1 = modified axis2, v2 = axis1 x (modified axis2) dCROSS( v, = , ax1, ax2 ); dMULTIPLY1_331( v1, node[0].body->posr.R, ax2 ); dMULTIPLY1_331( v2, node[0].body->posr.R, v ); } } 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(); } void dJointSetHinge2Axis1( dJointID j, dReal x, dReal y, dReal z ) { dxJointHinge2* joint = ( dxJointHinge2* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Hinge2 ); if ( joint->node[0].body ) { setAxes(joint, x, y, z, joint->axis1, NULL); // 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(); } void dJointSetHinge2Axis2( dJointID j, dReal x, dReal y, dReal z ) { dxJointHinge2* joint = ( dxJointHinge2* )j; dUASSERT( joint, "bad joint argument" ); checktype( joint, Hinge2 ); if ( joint->node[1].body ) { setAxes(joint, x, y, 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(); } 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 ); } } 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 ); } } 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 ); if ( joint->node[0].body ) return joint->measureAngle(); else return 0; } 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 = dDOT( axis, joint->node[0].body->avel ); if ( joint->node[1].body ) rate -= dDOT( 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 = dDOT( axis, joint->node[0].body->avel ); if ( joint->node[1].body ) rate -= dDOT( 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; } size_t 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(); } ode-0.11.1/ode/src/joints/fixed.h0000644000076400007640000000431311025774723013417 00000000000000/************************************************************************* * * * 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 getInfo1 ( Info1* info ); virtual void getInfo2 ( Info2* info ); virtual dJointType type() const; virtual size_t size() const; void computeInitialRelativeRotation(); }; #endif ode-0.11.1/ode/src/joints/slider.h0000644000076400007640000000457411075411332013600 00000000000000/************************************************************************* * * * 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 getInfo1 ( Info1* info ); virtual void getInfo2 ( Info2* info ); virtual dJointType type() const; virtual size_t size() const; virtual void setRelativeValues(); void computeInitialRelativeRotation(); void computeOffset(); }; #endif ode-0.11.1/ode/src/joints/hinge.h0000644000076400007640000000441511075411332013402 00000000000000/************************************************************************* * * * 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 getInfo1( Info1* info ); virtual void getInfo2( Info2* info ); virtual dJointType type() const; virtual size_t size() const; virtual void setRelativeValues(); void computeInitialRelativeRotation(); }; #endif ode-0.11.1/ode/src/joints/contact.cpp0000644000076400007640000002034211034354466014304 00000000000000/************************************************************************* * * * 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 "contact.h" #include "joint_internal.h" //**************************************************************************** // contact dxJointContact::dxJointContact( dxWorld *w ) : dxJoint( w ) { } 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; if ( contact.surface.mu < 0 ) contact.surface.mu = 0; if ( contact.surface.mode & dContactMu2 ) { if ( contact.surface.mu > 0 ) m++; if ( contact.surface.mu2 < 0 ) contact.surface.mu2 = 0; if ( contact.surface.mu2 > 0 ) m++; if ( contact.surface.mu == dInfinity ) nub ++; if ( contact.surface.mu2 == dInfinity ) nub ++; } else { if ( contact.surface.mu > 0 ) m += 2; if ( contact.surface.mu == dInfinity ) nub += 2; } the_m = m; info->m = m; info->nub = nub; } void dxJointContact::getInfo2( dxJoint::Info2 *info ) { int s = info->rowskip; int s2 = 2 * s; // get normal, with sign adjusted for body1/body2 polarity dVector3 normal; if ( flags & dJOINT_REVERSE ) { normal[0] = - contact.geom.normal[0]; normal[1] = - contact.geom.normal[1]; normal[2] = - contact.geom.normal[2]; } else { normal[0] = contact.geom.normal[0]; normal[1] = contact.geom.normal[1]; normal[2] = contact.geom.normal[2]; } normal[3] = 0; // @@@ hmmm // c1,c2 = contact points with respect to body PORs dVector3 c1, c2 = {0,0,0}; c1[0] = contact.geom.pos[0] - node[0].body->posr.pos[0]; c1[1] = contact.geom.pos[1] - node[0].body->posr.pos[1]; c1[2] = contact.geom.pos[2] - node[0].body->posr.pos[2]; // set jacobian for normal info->J1l[0] = normal[0]; info->J1l[1] = normal[1]; info->J1l[2] = normal[2]; dCROSS( info->J1a, = , c1, normal ); if ( node[1].body ) { c2[0] = contact.geom.pos[0] - node[1].body->posr.pos[0]; c2[1] = contact.geom.pos[1] - node[1].body->posr.pos[1]; c2[2] = contact.geom.pos[2] - node[1].body->posr.pos[2]; info->J2l[0] = -normal[0]; info->J2l[1] = -normal[1]; info->J2l[2] = -normal[2]; dCROSS( info->J2a, = -, c2, normal ); } // set right hand side and cfm value for normal dReal erp = info->erp; if ( contact.surface.mode & dContactSoftERP ) erp = contact.surface.soft_erp; dReal k = info->fps * erp; dReal depth = contact.geom.depth - world->contactp.min_depth; if ( depth < 0 ) depth = 0; if ( contact.surface.mode & dContactSoftCFM ) info->cfm[0] = contact.surface.soft_cfm; dReal motionN = 0; if ( contact.surface.mode & dContactMotionN ) motionN = contact.surface.motionN; const dReal pushout = k * depth + motionN; info->c[0] = pushout; // note: this cap should not limit bounce velocity const dReal maxvel = world->contactp.max_vel; if ( info->c[0] > maxvel ) info->c[0] = maxvel; // deal with bounce if ( contact.surface.mode & dContactBounce ) { // calculate outgoing velocity (-ve for incoming contact) dReal outgoing = dDOT( info->J1l, node[0].body->lvel ) + dDOT( info->J1a, node[0].body->avel ); if ( node[1].body ) { outgoing += dDOT( info->J2l, node[1].body->lvel ) + dDOT( info->J2a, node[1].body->avel ); } outgoing -= motionN; // only apply bounce if the outgoing velocity is greater than the // threshold, and if the resulting c[0] exceeds what we already have. if ( contact.surface.bounce_vel >= 0 && ( -outgoing ) > contact.surface.bounce_vel ) { dReal newc = - contact.surface.bounce * outgoing + motionN; if ( newc > info->c[0] ) info->c[0] = newc; } } // set LCP limits for normal info->lo[0] = 0; info->hi[0] = dInfinity; // now do jacobian for tangential forces dVector3 t1, t2; // two vectors tangential to normal // first friction direction if ( the_m >= 2 ) { if ( contact.surface.mode & dContactFDir1 ) // use fdir1 ? { t1[0] = contact.fdir1[0]; t1[1] = contact.fdir1[1]; t1[2] = contact.fdir1[2]; dCROSS( t2, = , normal, t1 ); } else { dPlaneSpace( normal, t1, t2 ); } info->J1l[s+0] = t1[0]; info->J1l[s+1] = t1[1]; info->J1l[s+2] = t1[2]; dCROSS( info->J1a + s, = , c1, t1 ); if ( node[1].body ) { info->J2l[s+0] = -t1[0]; info->J2l[s+1] = -t1[1]; info->J2l[s+2] = -t1[2]; dCROSS( info->J2a + s, = -, c2, t1 ); } // set right hand side if ( contact.surface.mode & dContactMotion1 ) { info->c[1] = contact.surface.motion1; } // set LCP bounds and friction index. this depends on the approximation // mode info->lo[1] = -contact.surface.mu; info->hi[1] = contact.surface.mu; if ( contact.surface.mode & dContactApprox1_1 ) info->findex[1] = 0; // set slip (constraint force mixing) if ( contact.surface.mode & dContactSlip1 ) info->cfm[1] = contact.surface.slip1; } // second friction direction if ( the_m >= 3 ) { info->J1l[s2+0] = t2[0]; info->J1l[s2+1] = t2[1]; info->J1l[s2+2] = t2[2]; dCROSS( info->J1a + s2, = , c1, t2 ); if ( node[1].body ) { info->J2l[s2+0] = -t2[0]; info->J2l[s2+1] = -t2[1]; info->J2l[s2+2] = -t2[2]; dCROSS( info->J2a + s2, = -, c2, t2 ); } // set right hand side if ( contact.surface.mode & dContactMotion2 ) { info->c[2] = contact.surface.motion2; } // set LCP bounds and friction index. this depends on the approximation // mode if ( contact.surface.mode & dContactMu2 ) { info->lo[2] = -contact.surface.mu2; info->hi[2] = contact.surface.mu2; } else { info->lo[2] = -contact.surface.mu; info->hi[2] = contact.surface.mu; } if ( contact.surface.mode & dContactApprox1_2 ) info->findex[2] = 0; // set slip (constraint force mixing) if ( contact.surface.mode & dContactSlip2 ) info->cfm[2] = contact.surface.slip2; } } dJointType dxJointContact::type() const { return dJointTypeContact; } size_t dxJointContact::size() const { return sizeof( *this ); } ode-0.11.1/ode/src/joints/Makefile.am0000644000076400007640000000146511021624601014171 00000000000000AM_CPPFLAGS = -I$(top_srcdir)/include noinst_LTLIBRARIES = libjoints.la libjoints_la_SOURCES = joints.h \ joint.h joint.cpp \ joint_internal.h \ ball.h ball.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 ode-0.11.1/ode/src/joints/amotor.cpp0000644000076400007640000003515211021624601014142 00000000000000/************************************************************************* * * * 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 "amotor.h" #include "joint_internal.h" //**************************************************************************** // angular motor dxJointAMotor::dxJointAMotor( dxWorld *w ) : dxJoint( w ) { int i; num = 0; mode = dAMotorUser; for ( i = 0; i < 3; i++ ) { rel[i] = 0; dSetZero( axis[i], 4 ); limot[i].init( world ); angle[i] = 0; } dSetZero( reference1, 4 ); dSetZero( reference2, 4 ); } // compute the 3 axes in global coordinates void dxJointAMotor::computeGlobalAxes( dVector3 ax[3] ) { if ( mode == dAMotorEuler ) { // special handling for euler mode dMULTIPLY0_331( ax[0], node[0].body->posr.R, axis[0] ); if ( node[1].body ) { dMULTIPLY0_331( ax[2], node[1].body->posr.R, axis[2] ); } else { ax[2][0] = axis[2][0]; ax[2][1] = axis[2][1]; ax[2][2] = axis[2][2]; } dCROSS( ax[1], = , ax[2], ax[0] ); dNormalize3( ax[1] ); } else { for ( int i = 0; i < num; i++ ) { if ( rel[i] == 1 ) { // relative to b1 dMULTIPLY0_331( ax[i], node[0].body->posr.R, axis[i] ); } else if ( rel[i] == 2 ) { // relative to b2 if ( node[1].body ) // jds: don't assert, just ignore { dMULTIPLY0_331( ax[i], node[1].body->posr.R, axis[i] ); } } else { // global - just copy it ax[i][0] = axis[i][0]; ax[i][1] = axis[i][1]; ax[i][2] = axis[i][2]; } } } } void dxJointAMotor::computeEulerAngles( dVector3 ax[3] ) { // 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 ref1, ref2; dMULTIPLY0_331( ref1, node[0].body->posr.R, reference1 ); if ( node[1].body ) { dMULTIPLY0_331( ref2, node[1].body->posr.R, reference2 ); } else { ref2[0] = reference2[0]; ref2[1] = reference2[1]; ref2[2] = reference2[2]; } // get q perpendicular to both ax[0] and ref1, get first euler angle dVector3 q; dCROSS( q, = , ax[0], ref1 ); angle[0] = -dAtan2( dDOT( ax[2], q ), dDOT( ax[2], ref1 ) ); // get q perpendicular to both ax[0] and ax[1], get second euler angle dCROSS( q, = , ax[0], ax[1] ); angle[1] = -dAtan2( dDOT( ax[2], ax[0] ), dDOT( ax[2], q ) ); // get q perpendicular to both ax[1] and ax[2], get third euler angle dCROSS( q, = , ax[1], ax[2] ); angle[2] = -dAtan2( dDOT( ref2, ax[1] ), dDOT( ref2, 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 ( node[0].body && node[1].body ) { dVector3 r; // axis[2] and axis[0] in global coordinates dMULTIPLY0_331( r, node[1].body->posr.R, axis[2] ); dMULTIPLY1_331( reference1, node[0].body->posr.R, r ); dMULTIPLY0_331( r, node[0].body->posr.R, axis[0] ); dMULTIPLY1_331( reference2, node[1].body->posr.R, r ); } else // jds { // else if (j->node[0].body) { // dMULTIPLY1_331 (j->reference1,j->node[0].body->posr.R,j->axis[2]); // dMULTIPLY0_331 (j->reference2,j->node[0].body->posr.R,j->axis[0]); // We want to handle angular motors attached to passive geoms dVector3 r; // axis[2] and axis[0] in global coordinates r[0] = axis[2][0]; r[1] = axis[2][1]; r[2] = axis[2][2]; r[3] = axis[2][3]; dMULTIPLY1_331( reference1, node[0].body->posr.R, r ); dMULTIPLY0_331( r, node[0].body->posr.R, axis[0] ); reference2[0] += r[0]; reference2[1] += r[1]; reference2[2] += r[2]; reference2[3] += r[3]; } } void dxJointAMotor::getInfo1( dxJoint::Info1 *info ) { info->m = 0; info->nub = 0; // compute the axes and angles, if in euler mode if ( mode == dAMotorEuler ) { dVector3 ax[3]; computeGlobalAxes( ax ); computeEulerAngles( ax ); } // see if we're powered or at a joint limit for each axis for ( int i = 0; i < num; i++ ) { if ( limot[i].testRotationalLimit( angle[i] ) || limot[i].fmax > 0 ) { info->m++; } } } void dxJointAMotor::getInfo2( dxJoint::Info2 *info ) { int i; // compute the axes (if not global) dVector3 ax[3]; 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[3]; axptr[0] = &ax[0]; axptr[1] = &ax[1]; axptr[2] = &ax[2]; dVector3 ax0_cross_ax1; dVector3 ax1_cross_ax2; if ( mode == dAMotorEuler ) { dCROSS( ax0_cross_ax1, = , ax[0], ax[1] ); axptr[2] = &ax0_cross_ax1; dCROSS( ax1_cross_ax2, = , ax[1], ax[2] ); axptr[0] = &ax1_cross_ax2; } int row = 0; for ( i = 0; i < num; i++ ) { row += limot[i].addLimot( this, info, row, *( axptr[i] ), 1 ); } } void dJointSetAMotorNumAxes( dJointID j, int num ) { dxJointAMotor* joint = ( dxJointAMotor* )j; dAASSERT( joint && num >= 0 && num <= 3 ); checktype( joint, AMotor ); if ( joint->mode == dAMotorEuler ) { joint->num = 3; } else { if ( num < 0 ) num = 0; if ( num > 3 ) num = 3; joint->num = num; } } void dJointSetAMotorAxis( dJointID j, int anum, int rel, dReal x, dReal y, dReal z ) { dxJointAMotor* joint = ( dxJointAMotor* )j; dAASSERT( joint && anum >= 0 && anum <= 2 && rel >= 0 && rel <= 2 ); checktype( joint, AMotor ); dUASSERT( !( !joint->node[1].body && ( joint->flags & dJOINT_REVERSE ) && rel == 1 ), "no first body, can't set axis rel=1" ); dUASSERT( !( !joint->node[1].body && !( joint->flags & dJOINT_REVERSE ) && rel == 2 ), "no second body, can't set axis rel=2" ); if ( anum < 0 ) anum = 0; if ( anum > 2 ) anum = 2; // adjust rel to match the internal body order if ( !joint->node[1].body && rel == 2 ) rel = 1; joint->rel[anum] = rel; // 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; 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 { // don't assert; handle the case of attachment to a bodiless geom if ( joint->node[1].body ) // jds { 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]; joint->axis[anum][3] = r[3]; } } } else { joint->axis[anum][0] = r[0]; joint->axis[anum][1] = r[1]; joint->axis[anum][2] = r[2]; } dNormalize3( joint->axis[anum] ); if ( joint->mode == dAMotorEuler ) joint->setEulerReferenceVectors(); } void dJointSetAMotorAngle( dJointID j, int anum, dReal angle ) { dxJointAMotor* joint = ( dxJointAMotor* )j; dAASSERT( joint && anum >= 0 && anum < 3 ); checktype( joint, AMotor ); if ( joint->mode == dAMotorUser ) { if ( anum < 0 ) anum = 0; if ( anum > 3 ) anum = 3; joint->angle[anum] = angle; } } void dJointSetAMotorParam( dJointID j, int parameter, dReal value ) { dxJointAMotor* joint = ( dxJointAMotor* )j; dAASSERT( joint ); checktype( joint, AMotor ); int anum = parameter >> 8; if ( anum < 0 ) anum = 0; if ( anum > 2 ) anum = 2; parameter &= 0xff; joint->limot[anum].set( parameter, value ); } void dJointSetAMotorMode( dJointID j, int mode ) { dxJointAMotor* joint = ( dxJointAMotor* )j; dAASSERT( joint ); checktype( joint, AMotor ); joint->mode = mode; if ( joint->mode == dAMotorEuler ) { joint->num = 3; joint->setEulerReferenceVectors(); } } int dJointGetAMotorNumAxes( dJointID j ) { dxJointAMotor* joint = ( dxJointAMotor* )j; dAASSERT( joint ); checktype( joint, AMotor ); return joint->num; } void dJointGetAMotorAxis( dJointID j, int anum, dVector3 result ) { dxJointAMotor* joint = ( dxJointAMotor* )j; dAASSERT( joint && anum >= 0 && anum < 3 ); checktype( joint, AMotor ); if ( anum < 0 ) anum = 0; if ( anum > 2 ) anum = 2; if ( joint->rel[anum] > 0 ) { if ( joint->rel[anum] == 1 ) { dMULTIPLY0_331( result, joint->node[0].body->posr.R, joint->axis[anum] ); } else { if ( joint->node[1].body ) // jds { dMULTIPLY0_331( result, joint->node[1].body->posr.R, joint->axis[anum] ); } else { result[0] = joint->axis[anum][0]; result[1] = joint->axis[anum][1]; result[2] = joint->axis[anum][2]; result[3] = joint->axis[anum][3]; } } } else { result[0] = joint->axis[anum][0]; result[1] = joint->axis[anum][1]; result[2] = joint->axis[anum][2]; } } int dJointGetAMotorAxisRel( dJointID j, int anum ) { dxJointAMotor* joint = ( dxJointAMotor* )j; dAASSERT( joint && anum >= 0 && anum < 3 ); checktype( joint, AMotor ); if ( anum < 0 ) anum = 0; if ( anum > 2 ) anum = 2; return joint->rel[anum]; } dReal dJointGetAMotorAngle( dJointID j, int anum ) { dxJointAMotor* joint = ( dxJointAMotor* )j; dAASSERT( joint && anum >= 0 && anum < 3 ); checktype( joint, AMotor ); if ( anum < 0 ) anum = 0; if ( anum > 3 ) anum = 3; return joint->angle[anum]; } dReal dJointGetAMotorAngleRate( dJointID j, int anum ) { //dxJointAMotor* joint = (dxJointAMotor*)j; // @@@ dDebug( 0, "not yet implemented" ); return 0; } dReal dJointGetAMotorParam( dJointID j, int parameter ) { dxJointAMotor* joint = ( dxJointAMotor* )j; dAASSERT( joint ); checktype( joint, AMotor ); int anum = parameter >> 8; if ( anum < 0 ) anum = 0; if ( anum > 2 ) anum = 2; parameter &= 0xff; return joint->limot[anum].get( parameter ); } int dJointGetAMotorMode( dJointID j ) { dxJointAMotor* joint = ( dxJointAMotor* )j; dAASSERT( joint ); checktype( joint, AMotor ); return joint->mode; } void dJointAddAMotorTorques( dJointID j, dReal torque1, dReal torque2, dReal torque3 ) { dxJointAMotor* joint = ( dxJointAMotor* )j; dVector3 axes[3]; dAASSERT( joint ); checktype( joint, AMotor ); if ( joint->num == 0 ) return; dUASSERT(( joint->flags & dJOINT_REVERSE ) == 0, "dJointAddAMotorTorques not yet implemented for reverse AMotor joints" ); joint->computeGlobalAxes( axes ); axes[0][0] *= torque1; axes[0][1] *= torque1; axes[0][2] *= torque1; if ( joint->num >= 2 ) { axes[0][0] += axes[1][0] * torque2; axes[0][1] += axes[1][1] * torque2; axes[0][2] += axes[1][2] * torque2; if ( joint->num >= 3 ) { axes[0][0] += axes[2][0] * torque3; axes[0][1] += axes[2][1] * torque3; axes[0][2] += axes[2][2] * torque3; } } if ( joint->node[0].body != 0 ) dBodyAddTorque( joint->node[0].body, axes[0][0], axes[0][1], axes[0][2] ); if ( joint->node[1].body != 0 ) dBodyAddTorque( joint->node[1].body, -axes[0][0], -axes[0][1], -axes[0][2] ); } dJointType dxJointAMotor::type() const { return dJointTypeAMotor; } size_t dxJointAMotor::size() const { return sizeof( *this ); } ode-0.11.1/ode/src/joints/null.h0000644000076400007640000000360211021624601013253 00000000000000/************************************************************************* * * * 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 getInfo1( Info1* info ); virtual void getInfo2( Info2* info ); virtual dJointType type() const; virtual size_t size() const; }; #endif ode-0.11.1/ode/src/joints/plane2d.cpp0000644000076400007640000001224011021624601014157 00000000000000/************************************************************************* * * * 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 "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 */ # define VoXYZ(v1, o1, x, y, z) \ ( \ (v1)[0] o1 (x), \ (v1)[1] o1 (y), \ (v1)[2] o1 (z) \ ) 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::getInfo1( dxJoint::Info1 *info ) { info->nub = 3; info->m = 3; if ( motor_x.fmax > 0 ) row_motor_x = info->m ++; if ( motor_y.fmax > 0 ) row_motor_y = info->m ++; if ( motor_angle.fmax > 0 ) row_motor_angle = info->m ++; } void dxJointPlane2D::getInfo2( dxJoint::Info2 *info ) { int r0 = 0, r1 = info->rowskip, r2 = 2 * r1; dReal eps = info->fps * info->erp; /* v = v1, w = omega1 (v2, omega2 not important (== static environment)) constraint equations: xz = 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: VoXYZ( &info->J1l[r0], = , 0, 0, 1 ); VoXYZ( &info->J1l[r1], = , 0, 0, 0 ); VoXYZ( &info->J1l[r2], = , 0, 0, 0 ); VoXYZ( &info->J1a[r0], = , 0, 0, 0 ); VoXYZ( &info->J1a[r1], = , 1, 0, 0 ); VoXYZ( &info->J1a[r2], = , 0, 1, 0 ); // error correction (against drift): // a) linear vz, so that z (== pos[2]) == 0 info->c[0] = eps * -node[0].body->posr.pos[2]; # if 0 // b) angular correction? -> left to application !!! dReal *body_z_axis = &node[0].body->R[8]; info->c[1] = eps * + atan2( body_z_axis[1], body_z_axis[2] ); // wx error info->c[2] = 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 ) motor_x.addLimot( this, info, row_motor_x, Midentity[0], 0 ); if ( row_motor_y > 0 ) motor_y.addLimot( this, info, row_motor_y, Midentity[1], 0 ); if ( row_motor_angle > 0 ) motor_angle.addLimot( this, info, row_motor_angle, Midentity[2], 1 ); } dJointType dxJointPlane2D::type() const { return dJointTypePlane2D; }; size_t 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 ); } ode-0.11.1/ode/src/joints/hinge2.h0000644000076400007640000000515411075411332013465 00000000000000/************************************************************************* * * * 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 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 measureAngle() const; void makeV1andV2(); void getAxisInfo(dVector3 ax1, dVector3 ax2, dVector3 axis, dReal &sin_angle, dReal &cos_Angle) const; dxJointHinge2( dxWorld *w ); virtual void getInfo1( Info1* info ); virtual void getInfo2( Info2* info ); virtual dJointType type() const; virtual size_t size() const; virtual void setRelativeValues(); }; #endif ode-0.11.1/ode/src/joints/hinge.cpp0000644000076400007640000002730011075411332013733 00000000000000/************************************************************************* * * * 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 "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::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( dxJoint::Info2 *info ) { // set the three ball-and-socket rows setBall( this, info, 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 ); int s3 = 3 * info->rowskip; int s4 = 4 * info->rowskip; info->J1a[s3+0] = p[0]; info->J1a[s3+1] = p[1]; info->J1a[s3+2] = p[2]; info->J1a[s4+0] = q[0]; info->J1a[s4+1] = q[1]; info->J1a[s4+2] = q[2]; if ( node[1].body ) { info->J2a[s3+0] = -p[0]; info->J2a[s3+1] = -p[1]; info->J2a[s3+2] = -p[2]; info->J2a[s4+0] = -q[0]; info->J2a[s4+1] = -q[1]; info->J2a[s4+2] = -q[2]; } // compute the right hand side of the constraint equation. set relative // body velocities along p and q to bring the hinge back into alignment. // if ax1,ax2 are the unit length hinge axes as computed from body1 and // body2, we need to rotate both bodies along the axis u = (ax1 x ax2). // if `theta' is the angle between ax1 and ax2, we need an angular velocity // along u to cover angle erp*theta in one step : // |angular_velocity| = angle/time = erp*theta / stepsize // = (erp*fps) * theta // angular_velocity = |angular_velocity| * (ax1 x ax2) / |ax1 x ax2| // = (erp*fps) * theta * (ax1 x ax2) / sin(theta) // ...as ax1 and ax2 are unit length. if theta is smallish, // theta ~= sin(theta), so // angular_velocity = (erp*fps) * (ax1 x ax2) // ax1 x ax2 is in the plane space of ax1, so we project the angular // velocity to p and q to find the right hand side. dVector3 ax2, b; 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]; } dCROSS( b, = , ax1, ax2 ); dReal k = info->fps * info->erp; info->c[3] = k * dDOT( b, p ); info->c[4] = k * dDOT( b, q ); // if the hinge is powered, or has joint limits, add in the stuff limot.addLimot( this, info, 5, 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 = dDOT( axis, joint->node[0].body->avel ); if ( joint->node[1].body ) rate -= dDOT( 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; } size_t 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]; } } } ode-0.11.1/ode/src/collision_trimesh_ccylinder.cpp0000644000076400007640000010342611156775756017150 00000000000000/************************************************************************* * * * 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 #include #include #include #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) \ (r)[0]=(a)[0] - (b)[0]; \ (r)[1]=(a)[1] - (b)[1]; \ (r)[2]=(a)[2] - (b)[2]; // dVector3 // a=b #define SET(a,b) \ (a)[0]=(b)[0]; \ (a)[1]=(b)[1]; \ (a)[2]=(b)[2]; // dMatrix3 // a=b #define SETM(a,b) \ (a)[0]=(b)[0]; \ (a)[1]=(b)[1]; \ (a)[2]=(b)[2]; \ (a)[3]=(b)[3]; \ (a)[4]=(b)[4]; \ (a)[5]=(b)[5]; \ (a)[6]=(b)[6]; \ (a)[7]=(b)[7]; \ (a)[8]=(b)[8]; \ (a)[9]=(b)[9]; \ (a)[10]=(b)[10]; \ (a)[11]=(b)[11]; // dVector3 // r=a+b #define ADD(a,b,r) \ (r)[0]=(a)[0] + (b)[0]; \ (r)[1]=(a)[1] + (b)[1]; \ (r)[2]=(a)[2] + (b)[2]; // dMatrix3, int, dVector3 // v=column a from m #define GETCOL(m,a,v) \ (v)[0]=(m)[(a)+0]; \ (v)[1]=(m)[(a)+4]; \ (v)[2]=(m)[(a)+8]; // dVector4, dVector3 // distance between plane p and point v #define POINTDISTANCE(p,v) \ ( p[0]*v[0] + p[1]*v[1] + p[2]*v[2] + p[3] ); \ // dVector4, dVector3, dReal // construct plane from normal and d #define CONSTRUCTPLANE(plane,normal,d) \ plane[0]=normal[0];\ plane[1]=normal[1];\ plane[2]=normal[2];\ plane[3]=d; // dVector3 // length of vector a #define LENGTHOF(a) \ dSqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);\ inline dReal _length2OfVector3(dVector3 v) { return (v[0] * v[0] + v[1] * v[1] + v[2] * v[2] ); } // 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_mTriMeshPos; 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(dDOT(m_vCapsuleAxis,vAxis))*(m_fCapsuleSize*REAL(0.5)-m_vCapsuleRadius) + m_vCapsuleRadius; // project triangle on vAxis dReal afv[3]; afv[0] = dDOT(m_vV0, vAxis); afv[1] = dDOT(m_vV1, vAxis); afv[2] = dDOT(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]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); dCROSS(t2,=,t1,v3); dCROSS(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::kEdge0) { // axis CxE0 - Edge 0 dCROSS(vAxis,=,m_vCapsuleAxis,m_vE0); //vAxis = dCROSS( m_vCapsuleAxis cross vE0 ); if (_length2OfVector3( vAxis ) > fEpsilon) { if (!_cldTestAxis(v0, v1, v2, vAxis, 2)) { return FALSE; } } } if (flags & dxTriMeshData::kEdge1) { // axis CxE1 - Edge 1 dCROSS(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::kEdge2) { // axis CxE2 - Edge 2 //vAxis = ( m_vCapsuleAxis cross m_vE2 ); dCROSS(vAxis,=,m_vCapsuleAxis,m_vE2); if (_length2OfVector3( vAxis ) > fEpsilon) { if (!_cldTestAxis(v0, v1, v2, vAxis, 4)) { return FALSE; } } } if (flags & dxTriMeshData::kEdge0) { // 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::kEdge1) { // 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::kEdge2) { // 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::kEdge0) { // 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::kEdge1) { // 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::kEdge2) { // 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::kVert0) { // 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::kVert1) { // 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::kVert2) { // 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::kVert0) { // 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::kVert1) { // 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::kVert2) { // 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::kVert0) { // 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::kVert1) { // 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::kVert2) { // 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 dCROSS(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 = -dDOT(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; SET (vPnt0,v0); dVector3 vPnt1; SET (vPnt1,v1); dVector3 vPnt2; SET (vPnt2,v2); if (fDistanceCapsuleCenterToPlane < 0 ) { SET (vPnt0,v0); SET (vPnt1,v2); SET (vPnt2,v1); } // 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; dCROSS(vTemp,=,m_vN,m_vE0); CONSTRUCTPLANE(plPlane, vTemp, REAL(1e-5)); if (!_cldClipEdgeToPlane( vCEdgePoint0, vCEdgePoint1, plPlane )) { return; } dCROSS(vTemp,=,m_vN,m_vE1); CONSTRUCTPLANE(plPlane, vTemp, -(dDOT(m_vE0,vTemp)-REAL(1e-5))); if (!_cldClipEdgeToPlane( vCEdgePoint0, vCEdgePoint1, plPlane )) { return; } dCROSS(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 = dDOT(vTemp,m_vNormal) - (m_fBestCenter-m_fBestrt); SUBTRACT(vCEdgePoint1,m_vCapsulePosition,vTemp); dReal fDepth1 = dDOT(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_mTriMeshPos, 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) { // It is a potential issue to explicitly cast to float // if custom width floating point type is introduced in OPCODE. // It is necessary to make a typedef and cast to it // (e.g. typedef float opc_float;) // However I'm not sure in what header it should be added. const dVector3 &vCapsulePosition = cData.m_vCapsulePosition; Point cCenter(/*(float)*/ vCapsulePosition[0], /*(float)*/ vCapsulePosition[1], /*(float)*/ vCapsulePosition[2]); Point cExtents(/*(float)*/ cData.m_vCapsuleRadius, /*(float)*/ cData.m_vCapsuleRadius,/*(float)*/ cData.m_fCapsuleSize/2); Matrix3x3 obbRot; const dMatrix3 &mCapsuleRotation = cData.m_mCapsuleRotation; obbRot[0][0] = /*(float)*/ mCapsuleRotation[0]; obbRot[1][0] = /*(float)*/ mCapsuleRotation[1]; obbRot[2][0] = /*(float)*/ mCapsuleRotation[2]; obbRot[0][1] = /*(float)*/ mCapsuleRotation[4]; obbRot[1][1] = /*(float)*/ mCapsuleRotation[5]; obbRot[2][1] = /*(float)*/ mCapsuleRotation[6]; obbRot[0][2] = /*(float)*/ mCapsuleRotation[8]; obbRot[1][2] = /*(float)*/ mCapsuleRotation[9]; obbRot[2][2] = /*(float)*/ mCapsuleRotation[10]; OBB obbCapsule(cCenter,cExtents,obbRot); Matrix4x4 CapsuleMatrix; MakeMatrix(vCapsulePosition, mCapsuleRotation, CapsuleMatrix); Matrix4x4 MeshMatrix; MakeMatrix(cData.m_mTriMeshPos, cData.m_mTriMeshRot, MeshMatrix); // TC results if (TriMesh->doBoxTC) { dxTriMesh::BoxTC* BoxTC = 0; for (int i = 0; i < TriMesh->BoxTCCache.size(); i++){ if (TriMesh->BoxTCCache[i].Geom == Capsule){ BoxTC = &TriMesh->BoxTCCache[i]; break; } } if (!BoxTC){ TriMesh->BoxTCCache.push(dxTriMesh::BoxTC()); BoxTC = &TriMesh->BoxTCCache[TriMesh->BoxTCCache.size() - 1]; BoxTC->Geom = Capsule; BoxTC->FatCoeff = 1.0f; } // Intersect Collider.SetTemporalCoherence(true); Collider.Collide(*BoxTC, obbCapsule, TriMesh->Data->BVTree, null, &MeshMatrix); } else { Collider.SetTemporalCoherence(false); Collider.Collide(BoxCache, obbCapsule, TriMesh->Data->BVTree, 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->_OBBCollider; // Will it better to use LSS here? -> confirm Pierre. dQueryCCTLPotentialCollisionTriangles(Collider, cData, TriMesh, Capsule, pccColliderCache->defaultBoxCache); if (Collider.GetContactStatus()) { // Retrieve data int TriCount = Collider.GetNbTouchedPrimitives(); if (TriCount != 0) { const int* Triangles = (const int*)Collider.GetTouchedPrimitives(); if (TriMesh->ArrayCallback != null) { TriMesh->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; uint8* UseFlags = TriMesh->Data->UseFlags; // loop through all intersecting triangles for (int i = 0; i < TriCount; i++) { const int Triint = Triangles[i]; if (!Callback(TriMesh, Capsule, Triint)) continue; dVector3 dv[3]; FetchTriangle(TriMesh, Triint, cData.m_mTriMeshPos, cData.m_mTriMeshRot, dv); uint8 flags = UseFlags ? UseFlags[Triint] : dxTriMeshData::kUseAll; 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 #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; unsigned contactmax = (unsigned)(flags & NUMC_MASK); if (contactcount > contactmax) { contactcount = contactmax; } dContactGeom* pcontact; unsigned i; for (i=0;ipos[0] = ptrimeshcontacts->m_point[0]; pcontact->pos[1] = ptrimeshcontacts->m_point[1]; pcontact->pos[2] = ptrimeshcontacts->m_point[2]; pcontact->pos[3] = 1.0f; pcontact->normal[0] = ptrimeshcontacts->m_normal[0]; pcontact->normal[1] = ptrimeshcontacts->m_normal[1]; pcontact->normal[2] = ptrimeshcontacts->m_normal[2]; pcontact->normal[3] = 0; pcontact->depth = ptrimeshcontacts->m_depth; pcontact->g1 = TriMesh; pcontact->g2 = gCylinder; pcontact->side1 = ptrimeshcontacts->m_feature1; pcontact->side2 = -1; ptrimeshcontacts++; } GIM_DYNARRAY_DESTROY(trimeshcontacts); return (int)contactcount; } #endif #endif // dTRIMESH_ENABLED ode-0.11.1/ode/src/collision_trimesh_trimesh.cpp0000644000076400007640000021441511206274560016627 00000000000000/************************************************************************* * * * 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 #include #include #include #include "config.h" // Classic Implementation #if dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER #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 #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) { dest[0]=v1[1]*v2[2]-v1[2]*v2[1]; \ dest[1]=v1[2]*v2[0]-v1[0]*v2[2]; \ dest[2]=v1[0]*v2[1]-v1[1]*v2[0]; } #define DOT(v1,v2) (v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2]) #define SUB(dest,v1,v2) { dest[0]=v1[0]-v2[0]; dest[1]=v1[1]-v2[1]; dest[2]=v1[2]-v2[2]; } #define ADD(dest,v1,v2) { dest[0]=v1[0]+v2[0]; dest[1]=v1[1]+v2[1]; dest[2]=v1[2]+v2[2]; } #define MULT(dest,v,factor) { dest[0]=factor*v[0]; dest[1]=factor*v[1]; dest[2]=factor*v[2]; } #define SET(dest,src) { dest[0]=src[0]; dest[1]=src[1]; dest[2]=src[2]; } #define SMULT(p,q,s) { p[0]=q[0]*s; p[1]=q[1]*s; p[2]=q[2]*s; } #define COMBO(combo,p,t,q) { combo[0]=p[0]+t*q[0]; combo[1]=p[1]+t*q[1]; combo[2]=p[2]+t*q[2]; } #define LENGTH(x) ((dReal) dSqrt(dDOT(x, x))) #define DEPTH(d, p, q, n) d = (p[0] - q[0])*n[0] + (p[1] - q[1])*n[1] + (p[2] - q[2])*n[2]; inline const dReal dMin(const dReal x, const dReal y) { return x < y ? x : y; } 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; 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->_AABBTreeCollider; BVTCache &ColCache = pccColliderCache->ColCache; ColCache.Model0 = &TriMesh1->Data->BVTree; ColCache.Model1 = &TriMesh2->Data->BVTree; // Collision query Matrix4x4 amatrix, bmatrix; BOOL IsOk = Collider.Collide(ColCache, &MakeMatrix(TLPosition1, TLRotation1, amatrix), &MakeMatrix(TLPosition2, TLRotation2, 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 FetchTriangle((dxTriMesh*) g1, id1, TLPosition1, TLRotation1, v1); FetchTriangle((dxTriMesh*) g2, id2, TLPosition2, TLRotation2, v2); // Since we'll be doing matrix transfomrations, 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(dDOT(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)->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)->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)->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( dDOT(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)->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( dDOT(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] = dDOT(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] = dDOT(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] = dDOT(tmp1, SolidPlanes[2]); FindTriSolidIntrsection(pen_v, SolidPlanes, 3, firstClippedTri); for (int j=0; jlast_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)->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(dDOT(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] = dDOT(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] = dDOT(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] = dDOT(tmp1, SolidPlanes[2]); FindTriSolidIntrsection(pen_v, SolidPlanes, 3, secondClippedTri); for (int j=0; jlast_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)->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(dDOT(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(dDOT(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(dDOT(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 = dDOT(dvTmp, n); if ( dFabs(rTmp) < dFabs(depth) ) { depth = rTmp; SET( ContactPt, pen_v[j] ); contact_elt_length = dFabs(dDOT(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(dDOT(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(dDOT(n1, elt_sum)) < REAL(0.01)) && (dFabs(dDOT(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= 0.0) { contact_elt_length = dFabs(dDOT(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= 0.0) { contact_elt_length = dFabs(dDOT(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; jpos, CoplanarPt); dist = dDOT(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 (-dDOT(elt_sum, n1) > -dDOT(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|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)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)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]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 = dDOT(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 (dDOT(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 (dDOT(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] = dDOT(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(dDOT(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; ipos); if (dDOT(diff, diff) < dEpsilon) { // same normal? if (dFabs(dDOT(in_Normal, Contact->normal)) > (REAL(1.0)-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 #endif // dTRIMESH_USE_OLD_TRIMESH_TRIMESH_COLLIDER #endif // dTRIMESH_ENABLED ode-0.11.1/ode/src/collision_cylinder_trimesh.cpp0000644000076400007640000010276011156775756017005 00000000000000/************************************************************************* * * * 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 #include #include #include #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]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) 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)); 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)); // 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= (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 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 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 (we should already exit in that 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= (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) { const dVector3 &vCylinderPos = cData.m_vCylinderPos; Point cCenter(vCylinderPos[0],vCylinderPos[1],vCylinderPos[2]); Point cExtents(cData.m_fCylinderRadius,cData.m_fCylinderRadius,cData.m_fCylinderRadius); cExtents[nCYLINDER_AXIS] = cData.m_fCylinderSize * REAL(0.5); Matrix3x3 obbRot; const dMatrix3 &mCylinderRot = cData.m_mCylinderRot; // It is a potential issue to explicitly cast to float // if custom width floating point type is introduced in OPCODE. // It is necessary to make a typedef and cast to it // (e.g. typedef float opc_float;) // However I'm not sure in what header it should be added. obbRot[0][0] = /*(float)*/mCylinderRot[0]; obbRot[1][0] = /*(float)*/mCylinderRot[1]; obbRot[2][0] = /*(float)*/mCylinderRot[2]; obbRot[0][1] = /*(float)*/mCylinderRot[4]; obbRot[1][1] = /*(float)*/mCylinderRot[5]; obbRot[2][1] = /*(float)*/mCylinderRot[6]; obbRot[0][2] = /*(float)*/mCylinderRot[8]; obbRot[1][2] = /*(float)*/mCylinderRot[9]; obbRot[2][2] = /*(float)*/mCylinderRot[10]; OBB obbCapsule(cCenter,cExtents,obbRot); Matrix4x4 CapsuleMatrix; MakeMatrix(vCylinderPos, mCylinderRot, CapsuleMatrix); Matrix4x4 MeshMatrix; MakeMatrix(cData.m_vTrimeshPos, cData.m_mTrimeshRot, MeshMatrix); // TC results if (Trimesh->doBoxTC) { dxTriMesh::BoxTC* BoxTC = 0; for (int i = 0; i < Trimesh->BoxTCCache.size(); i++) { if (Trimesh->BoxTCCache[i].Geom == Cylinder) { BoxTC = &Trimesh->BoxTCCache[i]; break; } } if (!BoxTC) { Trimesh->BoxTCCache.push(dxTriMesh::BoxTC()); BoxTC = &Trimesh->BoxTCCache[Trimesh->BoxTCCache.size() - 1]; BoxTC->Geom = Cylinder; BoxTC->FatCoeff = REAL(1.0); } // Intersect Collider.SetTemporalCoherence(true); Collider.Collide(*BoxTC, obbCapsule, Trimesh->Data->BVTree, null, &MeshMatrix); } else { Collider.SetTemporalCoherence(false); Collider.Collide(BoxCache, obbCapsule, Trimesh->Data->BVTree, 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->_OBBCollider; dQueryCTLPotentialCollisionTriangles(Collider, cData, Cylinder, Trimesh, pccColliderCache->defaultBoxCache); // Retrieve data int TriCount = Collider.GetNbTouchedPrimitives(); if (TriCount != 0) { const int* Triangles = (const int*)Collider.GetTouchedPrimitives(); if (Trimesh->ArrayCallback != null) { Trimesh->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 (!Callback(Trimesh, Cylinder, Triint)) continue; dVector3 dv[3]; FetchTriangle(Trimesh, Triint, cData.m_vTrimeshPos, cData.m_mTrimeshRot, dv); 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; test_aabb.minX = o1->aabb[0]; test_aabb.maxX = o1->aabb[1]; test_aabb.minY = o1->aabb[2]; test_aabb.maxY = o1->aabb[3]; test_aabb.minZ = o1->aabb[4]; test_aabb.maxZ = 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 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. ode-0.11.1/config.sub0000755000076400007640000010175611206343422011264 00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 # Free Software Foundation, Inc. timestamp='2008-09-08' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # 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 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., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, 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. # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # 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. # 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 ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 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-dietlibc | linux-newlib* | linux-uclibc* | \ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) 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) os= basic_machine=$1 ;; -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*) 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 \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | 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 \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | mt \ | msp430 \ | nios | nios2 \ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | score \ | sh | sh[1234] | sh[24]a | 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 \ | spu | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-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-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | 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-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ | sh-* | sh[1234]-* | sh[24]a-* | 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-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ | 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 ;; 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 ;; 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) 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'm not sure what "Sysv32" means. Should this be sysv3.2? 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 ;; 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 ;; mingw32) basic_machine=i386-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 ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; mvs) basic_machine=i370-ibm os=-mvs ;; 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 ;; 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) basic_machine=powerpc-unknown ;; ppc-*) 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) 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 ;; 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 ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; tile*) basic_machine=tile-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 ;; 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[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. -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* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -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* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -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*) # 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 ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -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 ;; # 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 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; 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 ;; -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: ode-0.11.1/config.guess0000755000076400007640000013061111206343422011611 00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 # Free Software Foundation, Inc. timestamp='2008-11-15' # 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 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., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, 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. # Originally written by Per Bothner . # Please send patches to . Submit a context # diff and a properly formatted ChangeLog entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # The plan is that this can be called by configure scripts if you # don't specify an explicit build system type. 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 ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 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 # 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 tupples: *-*-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=`(/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 ;; *) 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*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep __ELF__ >/dev/null 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 # 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/[-_].*/\./'` ;; 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}" 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 ;; 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'` exit ;; 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 ;; 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: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 '\n#ifdef __amd64\nIS_64BIT_ARCH\n#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 /* 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 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:*:[456]) 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/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` 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 #include 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 __LP64__ >/dev/null 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 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:*:*) case ${UNAME_MACHINE} in pc98) echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:[3456]*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; EM64T | authenticamd | genuineintel) 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 ;; 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-gnu`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/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix 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-gnu else echo ${UNAME_MACHINE}-unknown-linux-gnueabi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo crisv32-axis-linux-gnu exit ;; frv:Linux:*:*) echo frv-unknown-linux-gnu exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips #undef mipsel #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mipsel #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^CPU/{ s: ::g p }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef mips64 #undef mips64el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=mips64el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=mips64 #else CPU= #endif #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^CPU/{ s: ::g p }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo or32-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu 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 ld.so.1 >/dev/null if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-gnu 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-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent # problems with other programs or directories called `ld' in the path. # Set LC_ALL=C to ensure ld outputs messages in English. ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ | sed -ne '/supported targets:/!d s/[ ][ ]*/ /g s/.*supported targets: *// s/ .*// p'` case "$ld_supported_targets" in elf32-i386) TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" ;; a.out-i386-linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" exit ;; "") # Either a pre-BFD a.out linker (linux-gnuoldld) or # one that does not give us useful --help. echo "${UNAME_MACHINE}-pc-linux-gnuoldld" exit ;; esac # Determine whether the default compiler is a.out or elf eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 LIBC=gnu # else LIBC=gnulibc1 # endif # else LIBC=gnulibc1 # endif #else #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) LIBC=gnu #else LIBC=gnuaout #endif #endif #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' /^LIBC/{ s: ::g p }'`" test x"${LIBC}" != x && { echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit } test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; 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.0*:*) 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' /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 i386. echo i386-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; } ;; 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.0*:*) 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 echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # 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 ;; 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 case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac 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 ;; 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 ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < 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: ode-0.11.1/OPCODE/0000777000076400007640000000000011206343456010333 500000000000000ode-0.11.1/OPCODE/OPC_TreeCollider.cpp0000644000076400007640000011336111005162546014032 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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 = (const AABBQuantizedNoLeafTree*)cache.Model0->GetTree(); const AABBQuantizedNoLeafTree* T1 = (const AABBQuantizedNoLeafTree*)cache.Model1->GetTree(); Status = Collide(T0, T1, world0, world1, &cache); } else { const AABBNoLeafTree* T0 = (const AABBNoLeafTree*)cache.Model0->GetTree(); const AABBNoLeafTree* T1 = (const AABBNoLeafTree*)cache.Model1->GetTree(); Status = Collide(T0, T1, world0, world1, &cache); } } else { if(cache.Model0->IsQuantized()) { const AABBQuantizedTree* T0 = (const AABBQuantizedTree*)cache.Model0->GetTree(); const AABBQuantizedTree* T1 = (const AABBQuantizedTree*)cache.Model1->GetTree(); Status = Collide(T0, T1, world0, world1, &cache); } else { const AABBCollisionTree* T0 = (const AABBCollisionTree*)cache.Model0->GetTree(); const AABBCollisionTree* T1 = (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()); } } ode-0.11.1/OPCODE/Stdafx.h0000644000076400007640000000207210414557751011657 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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_) ode-0.11.1/OPCODE/OPC_TriBoxOverlap.h0000644000076400007640000002633310414557751013675 00000000000000 //! This macro quickly finds the min & max values among 3 variables #define FINDMINMAX(x0, x1, x2, min, max) \ min = max = x0; \ if(x1max) max=x1; \ if(x2max) 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 Mller, 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; } ode-0.11.1/OPCODE/OPC_TreeBuilders.cpp0000644000076400007640000002732611005162546014053 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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;iGetTriangle(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 * \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;iGetTriangle(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;iGetMeshInterface(); return mIMesh!=null; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Initializes a query */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// virtual inline_ void InitQuery() { mFlags &= ~OPC_TEMPORAL_CONTACT; } }; #endif // __OPC_COLLIDER_H__ ode-0.11.1/OPCODE/Opcode.h0000644000076400007640000000753511154520353011636 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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__ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 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 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 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" FUNCTION OPCODE_API bool InitOpcode(); FUNCTION OPCODE_API bool CloseOpcode(); } #endif // __OPCODE_H__ ode-0.11.1/OPCODE/OPC_Collider.cpp0000644000076400007640000000541510414557751013223 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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() { } ode-0.11.1/OPCODE/OPC_LSSCollider.h0000644000076400007640000001106710414557751013252 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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__ ode-0.11.1/OPCODE/OPC_OptimizedTree.cpp0000644000076400007640000007757311005162546014257 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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[mNbNodes]; CHECKALLOC(mNodes); } // Build the tree udword CurID = 1; _BuildCollisionTree(mNodes, 0, CurID, tree); ASSERT(CurID==mNbNodes); 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 NbNodes = tree->GetNbNodes(); if(NbNodes!=NbTriangles*2-1) return false; // Get nodes if(mNbNodes!=NbTriangles-1) // Same number of nodes => keep moving { mNbNodes = NbTriangles-1; DELETEARRAY(mNodes); mNodes = new AABBNoLeafNode[mNbNodes]; CHECKALLOC(mNodes); } // Build the tree udword CurID = 1; _BuildNoLeafTree(mNodes, 0, CurID, tree); ASSERT(CurID==mNbNodes); 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); \ for(udword i=0;iCMax.x) CMax.x = fabsf(Nodes[i].mAABB.mCenter.x); \ if(fabsf(Nodes[i].mAABB.mCenter.y)>CMax.y) CMax.y = fabsf(Nodes[i].mAABB.mCenter.y); \ if(fabsf(Nodes[i].mAABB.mCenter.z)>CMax.z) CMax.z = fabsf(Nodes[i].mAABB.mCenter.z); \ if(fabsf(Nodes[i].mAABB.mExtents.x)>EMax.x) EMax.x = fabsf(Nodes[i].mAABB.mExtents.x); \ if(fabsf(Nodes[i].mAABB.mExtents.y)>EMax.y) EMax.y = fabsf(Nodes[i].mAABB.mExtents.y); \ if(fabsf(Nodes[i].mAABB.mExtents.z)>EMax.z) EMax.z = fabsf(Nodes[i].mAABB.mExtents.z); \ } #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<Min[j]) mNodes[i].mAABB.mExtents[j]++; \ else FixMe=false; \ /* Prevent wrapping */ \ if(!mNodes[i].mAABB.mExtents[j]) \ { \ mNodes[i].mAABB.mExtents[j]=0xffff; \ FixMe=false; \ } \ }while(FixMe); \ } \ } #define REMAP_DATA(member) \ /* Fix data */ \ Data = Nodes[i].member; \ if(!(Data&1)) \ { \ /* Compute box number */ \ size_t Nb = (Data - size_t(Nodes))/Nodes[i].GetNodeSize(); \ 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[mNbNodes]; CHECKALLOC(Nodes); // Build the tree udword CurID = 1; _BuildCollisionTree(Nodes, 0, CurID, tree); // Quantize { mNodes = new AABBQuantizedNode[mNbNodes]; CHECKALLOC(mNodes); // Get max values FIND_MAX_VALUES // Quantization INIT_QUANTIZATION // Quantize size_t Data; for(udword i=0;iIsLeaf()) { _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 NbNodes = tree->GetNbNodes(); if(NbNodes!=NbTriangles*2-1) return false; // Get nodes mNbNodes = NbTriangles-1; DELETEARRAY(mNodes); AABBNoLeafNode* Nodes = new AABBNoLeafNode[mNbNodes]; CHECKALLOC(Nodes); // Build the tree udword CurID = 1; _BuildNoLeafTree(Nodes, 0, CurID, tree); ASSERT(CurID==mNbNodes); // Quantize { mNodes = new AABBQuantizedNoLeafNode[mNbNodes]; CHECKALLOC(mNodes); // Get max values FIND_MAX_VALUES // Quantization INIT_QUANTIZATION // Quantize size_t Data; for(udword i=0;iHasPosLeaf()) _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; } ode-0.11.1/OPCODE/OPC_IceHook.h0000644000076400007640000000274510414557751012457 00000000000000 // Should be included by Opcode.h if needed #define ICE_DONT_CHECK_COMPILER_OPTIONS // From Windows... typedef int BOOL; #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif #include #include #include #include #include #include #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" #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; ode-0.11.1/OPCODE/OPC_AABBCollider.cpp0000644000076400007640000006266511005162546013632 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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 = (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 = (const AABBNoLeafTree*)model.GetTree(); // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); else _Collide(Tree->GetNodes()); } } else { if(model.IsQuantized()) { const AABBQuantizedTree* Tree = (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 = (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;imCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes()); } else { const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes()); } } else { if(model.IsQuantized()) { const AABBQuantizedTree* Tree = (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 = (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; } ode-0.11.1/OPCODE/OPC_TreeBuilders.h0000644000076400007640000002136410715446136013523 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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) {} 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; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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) 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; 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; const MeshInterface* mIMesh; //!< Shortcut to an app-controlled mesh interface }; #endif // __OPC_TREEBUILDERS_H__ ode-0.11.1/OPCODE/OPC_Model.cpp0000644000076400007640000002066210726322630012517 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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(); } ode-0.11.1/OPCODE/OPC_VolumeCollider.cpp0000644000076400007640000001114310414557751014406 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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) ode-0.11.1/OPCODE/OPC_RayCollider.h0000644000076400007640000003001110726322630013322 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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__ ode-0.11.1/OPCODE/OPC_RayTriOverlap.h0000644000076400007640000000657010414557751013701 00000000000000#define LOCAL_EPSILON 0.000001f /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * Computes a ray-triangle intersection test. * Original code from Tomas Mller'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 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(det>-LOCAL_EPSILON && det1.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; } ode-0.11.1/OPCODE/OPC_OBBCollider.h0000644000076400007640000001502610414557751013212 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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__ ode-0.11.1/OPCODE/OPC_OBBCollider.cpp0000644000076400007640000007056711005162546013547 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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 = (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 = (const AABBNoLeafTree*)model.GetTree(); // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); else _Collide(Tree->GetNodes()); } } else { if(model.IsQuantized()) { const AABBQuantizedTree* Tree = (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 = (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 || fmB0.y || fmB0.z || f 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;imCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes()); } else { const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes()); } } else { if(model.IsQuantized()) { const AABBQuantizedTree* Tree = (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 = (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; } ode-0.11.1/OPCODE/OPC_MeshInterface.cpp0000644000076400007640000003463411005162546014177 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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) #else #ifdef OPC_USE_STRIDE mTriStride (sizeof(IndexedTriangle)), mVertexStride (sizeof(Point)), mFetchTriangle (&MeshInterface::FetchTriangleFromSingles), #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;imVRef[0] * mVertexStride); vp.Vertex[1] = (const Point*)(((ubyte*)mVerts) + T->mVRef[1] * mVertexStride); vp.Vertex[2] = (const Point*)(((ubyte*)mVerts) + T->mVRef[2] * mVertexStride); } void MeshInterface::FetchTriangleFromDoubles(VertexPointers& vp, udword index, ConversionArea vc) const { const IndexedTriangle* T = (const IndexedTriangle*)(((ubyte*)mTris) + index * mTriStride); for (int i = 0; i < 3; i++){ const double* v = (const double*)(((ubyte*)mVerts) + T->mVRef[i] * mVertexStride); vc[i].x = (float)v[0]; vc[i].y = (float)v[1]; vc[i].z = (float)v[2]; 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;iDistance(*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; } ode-0.11.1/OPCODE/OPC_Common.h0000644000076400007640000001113610414557751012360 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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)= 0.0f; } }; 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); #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; } #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); } #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 IndexedTriangle* T = &mTris[index]; vp.Vertex[0] = &mVerts[T->mVRef[0]]; vp.Vertex[1] = &mVerts[T->mVRef[1]]; vp.Vertex[2] = &mVerts[T->mVRef[2]]; #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; #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 #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; #endif const IndexedTriangle* mTris; //!< Array of indexed triangles const Point* mVerts; //!< Array of vertices #endif }; #endif //__OPC_MESHINTERFACE_H__ ode-0.11.1/OPCODE/OPC_BaseModel.h0000644000076400007640000002445410414557751012772 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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 OPCODECREATE(); 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__ ode-0.11.1/OPCODE/OPC_AABBTree.h0000644000076400007640000001545710715446136012445 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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__ ode-0.11.1/OPCODE/OPC_Picking.cpp0000644000076400007640000001231011005162546013031 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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.mDistancemDistance) *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 ode-0.11.1/OPCODE/OPC_OptimizedTree.h0000644000076400007640000002227210414557751013717 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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__ ode-0.11.1/OPCODE/OPC_SphereCollider.cpp0000644000076400007640000006767511005162546014401 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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;imCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); else _Collide(Tree->GetNodes()); } else { const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); else _Collide(Tree->GetNodes()); } } else { if(model.IsQuantized()) { const AABBQuantizedTree* Tree = (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 = (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;imCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes()); } else { const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes()); } } else { if(model.IsQuantized()) { const AABBQuantizedTree* Tree = (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 = (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; } ode-0.11.1/OPCODE/OPC_RayAABBOverlap.h0000644000076400007640000000677610414557751013640 00000000000000// 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; } ode-0.11.1/OPCODE/OPC_LSSAABBOverlap.h0000644000076400007640000003757010414557751013542 00000000000000 // 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; // 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; } } 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(s2Refit(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); } ode-0.11.1/OPCODE/Opcode.cpp0000644000076400007640000000405111154520353012157 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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; bool Opcode::InitOpcode() { //Log("// Initializing OPCODE\n\n"); // LogAPIInfo(); return true; } bool Opcode::CloseOpcode() { //Log("// Closing OPCODE\n\n"); return true; } #ifdef ICE_MAIN void ModuleAttach(HINSTANCE hinstance) { } void ModuleDetach() { } #endif ode-0.11.1/OPCODE/Makefile.in0000644000076400007640000005270711206343412012317 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ode/src/config.h CONFIG_CLEAN_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) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libOPCODE_la_SOURCES) DIST_SOURCES = $(libOPCODE_la_SOURCES) RECURSIVE_TARGETS = all-recursive check-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 uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ 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@ 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@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODE_PRECISION = @ODE_PRECISION@ ODE_RELEASE = @ODE_RELEASE@ 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_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ 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@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ 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 = Ice noinst_LTLIBRARIES = libOPCODE.la AM_CPPFLAGS = -fno-strict-aliasing -I$(top_srcdir)/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'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign OPCODE/Makefile .PRECIOUS: 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 clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libOPCODE.la: $(libOPCODE_la_OBJECTS) $(libOPCODE_la_DEPENDENCIES) $(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@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(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. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; 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; \ (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" $(RECURSIVE_CLEAN_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ 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 || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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 \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-exec-am: install-html: install-html-recursive install-info: install-info-recursive install-man: install-pdf: install-pdf-recursive install-ps: install-ps-recursive 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: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ clean-noinstLTLIBRARIES ctags ctags-recursive 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-recursive \ uninstall uninstall-am # 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: ode-0.11.1/OPCODE/OPC_PlanesCollider.h0000644000076400007640000001322211005162546014015 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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__ ode-0.11.1/OPCODE/OPC_Common.cpp0000644000076400007640000000525210414557751012715 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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; ode-0.11.1/OPCODE/OPC_AABBTree.cpp0000644000076400007640000005373410726322630012772 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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;iGetSplittingValue(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;iGetSplittingValue(Index, 0); Means.y+=builder->GetSplittingValue(Index, 1); Means.z+=builder->GetSplittingValue(Index, 2); } Means/=float(mNbPrimitives); // Compute variances Point Vars(0.0f, 0.0f, 0.0f); for(udword i=0;iGetSplittingValue(Index, 0); float Cy = builder->GetSplittingValue(Index, 1); float Cz = builder->GetSplittingValue(Index, 2); Vars.x += (Cx - Means.x)*(Cx - Means.x); Vars.y += (Cy - Means.y)*(Cy - Means.y); Vars.z += (Cz - Means.z)*(Cz - Means.z); } 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]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]]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 = (AABBTreeNode*)GetPos(); AABBTreeNode* Neg = (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 = (AABBTreeNode*)GetPos(); AABBTreeNode* Neg = (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 = (AABBTreeNode*)GetPos(); AABBTreeNode* Neg = (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;imNbPrimitives;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(), *(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_); ((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); } ode-0.11.1/OPCODE/OPC_SphereTriOverlap.h0000644000076400007640000001053510414557751014370 00000000000000 // 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; } ode-0.11.1/OPCODE/OPC_LSSCollider.cpp0000644000076400007640000006427211005162546013602 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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 = (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 = (const AABBNoLeafTree*)model.GetTree(); // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes()); else _Collide(Tree->GetNodes()); } } else { if(model.IsQuantized()) { const AABBQuantizedTree* Tree = (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 = (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;imCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes()); } else { const AABBNoLeafTree* Tree = (const AABBNoLeafTree*)model.GetTree(); // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes()); } } else { if(model.IsQuantized()) { const AABBQuantizedTree* Tree = (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 = (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; } ode-0.11.1/OPCODE/OPC_LSSTriOverlap.h0000644000076400007640000005130210414557751013600 00000000000000// 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 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>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__ ode-0.11.1/OPCODE/OPC_RayCollider.cpp0000644000076400007640000007114711005162546013673 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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(mStabbedFaces->GetFaces()); \ if(Current && mStabbedFace.mDistancemDistance) \ { \ *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)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 = (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 = (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 = (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 = (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.mDistanceAddFace(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); } } ode-0.11.1/OPCODE/OPC_TriTriOverlap.h0000644000076400007640000002027310414557751013700 00000000000000 //! if OPC_TRITRI_EPSILON_TEST is true then we do a check (if |dv|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 if(fabsf(du0)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 if(fabsf(dv0)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]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]Max[i]) if(mCenter[i]>Max) { float s = mCenter[i] - Max; d += s*s; } } } #endif return d <= mRadius2; } ode-0.11.1/OPCODE/Makefile.am0000644000076400007640000000374611154520353012310 00000000000000SUBDIRS = Ice noinst_LTLIBRARIES = libOPCODE.la AM_CPPFLAGS= -fno-strict-aliasing -I$(top_srcdir)/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 ode-0.11.1/OPCODE/OPC_Settings.h0000644000076400007640000000433610414557751012734 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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__ ode-0.11.1/OPCODE/OPC_VolumeCollider.h0000644000076400007640000001572310414557751014063 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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__ ode-0.11.1/OPCODE/OPC_AABBCollider.h0000644000076400007640000001052710414557751013276 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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__ ode-0.11.1/OPCODE/OPC_PlanesCollider.cpp0000644000076400007640000006261211005162546014357 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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<mCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); else _Collide(Tree->GetNodes(), PlaneMask); } else { const AABBNoLeafTree* Tree = (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 = (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 = (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;iHasSingleNode()) { 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< 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< 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<mCenterCoeff; mExtentsCoeff = Tree->mExtentsCoeff; // Perform collision query - we don't want primitive tests here! _CollideNoPrimitiveTest(Tree->GetNodes(), PlaneMask); } else { const AABBNoLeafTree* Tree = (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 = (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 = (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<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 = (AABBNoLeafNode*)((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; } ode-0.11.1/OPCODE/OPC_Model.h0000644000076400007640000000653710414557751012201 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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__ ode-0.11.1/OPCODE/OPC_HybridModel.h0000644000076400007640000001413710414557751013336 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* * 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__ ode-0.11.1/OPCODE/Ice/0000777000076400007640000000000011206343456011033 500000000000000ode-0.11.1/OPCODE/Ice/IceOBB.cpp0000644000076400007640000003035710732253301012476 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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; } ode-0.11.1/OPCODE/Ice/IcePlane.cpp0000644000076400007640000000376410414557751013152 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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; } ode-0.11.1/OPCODE/Ice/IcePlane.h0000644000076400007640000001156610414557751012616 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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__ ode-0.11.1/OPCODE/Ice/IceAABB.cpp0000644000076400007640000003760410732253301012563 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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) 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 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; 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; 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; 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__ ode-0.11.1/OPCODE/Ice/IceRevisitedRadix.cpp0000644000076400007640000005300210726322630015017 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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(ValCurSize) 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>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>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>2) & 3; mAxis2 = (order>>4) & 3; } inline_ ~Axes() {} udword mAxis0; udword mAxis1; udword mAxis2; }; #endif // __ICEAXES_H__ ode-0.11.1/OPCODE/Ice/IceUtils.h0000644000076400007640000002542611005162546012646 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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<> 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 inline_ void TSwap(Type& a, Type& b) { const Type c = a; a = b; b = c; } template inline_ Type TClamp(const Type& x, const Type& lo, const Type& hi) { return ((xhi) ? hi : x); } template inline_ void TSort(Type& a, Type& b) { if(a>b) TSwap(a, b); } template 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 #define ARRAYSIZE(p) (sizeof(p)/sizeof((p)[0])) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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__ ode-0.11.1/OPCODE/Ice/IceRay.cpp0000644000076400007640000000470010414557751012635 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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(); } ode-0.11.1/OPCODE/Ice/IceRevisitedRadix.h0000644000076400007640000000503210414557751014474 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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__ ode-0.11.1/OPCODE/Ice/IceTypes.h0000644000076400007640000001645211040351501012637 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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)(); //!< 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 inline_ const T& TMin (const T& a, const T& b) { return b < a ? b : a; } template inline_ const T& TMax (const T& a, const T& b) { return a < b ? b : a; } template inline_ void TSetMin (T& a, const T& b) { if(a>b) a = b; } template inline_ void TSetMax (T& a, const T& b) { if(a 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; } } ode-0.11.1/OPCODE/Ice/IceMatrix3x3.cpp0000644000076400007640000000346310414557751013711 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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); } ode-0.11.1/OPCODE/Ice/IceTriangle.h0000644000076400007640000000466410414557751013325 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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__ ode-0.11.1/OPCODE/Ice/IceContainer.h0000644000076400007640000002317610715446136013477 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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(); // 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); // 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); // 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(); // 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); // 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) { 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_ float GetGrowthFactor() const { return mGrowthFactor; } //!< Returns the growth factor inline_ void SetGrowthFactor(float 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=0 && i=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__ ode-0.11.1/OPCODE/Ice/IceSegment.h0000644000076400007640000000510210414557751013146 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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__ ode-0.11.1/OPCODE/Ice/IcePoint.cpp0000644000076400007640000001640410414557751013177 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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. IR(x) = 0xffffffff; IR(y) = 0xffffffff; IR(z) = 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; } ode-0.11.1/OPCODE/Ice/IceMatrix4x4.h0000644000076400007640000005114510414557751013360 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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) inline_ Matrix4x4& Set( 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; return *this; } //! Assign values inline_ Matrix4x4& Set( 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; 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() { IR(m[1][0]) ^= IR(m[0][1]); IR(m[0][1]) ^= IR(m[1][0]); IR(m[1][0]) ^= IR(m[0][1]); IR(m[2][0]) ^= IR(m[0][2]); IR(m[0][2]) ^= IR(m[2][0]); IR(m[2][0]) ^= IR(m[0][2]); IR(m[3][0]) ^= IR(m[0][3]); IR(m[0][3]) ^= IR(m[3][0]); IR(m[3][0]) ^= IR(m[0][3]); IR(m[1][2]) ^= IR(m[2][1]); IR(m[2][1]) ^= IR(m[1][2]); IR(m[1][2]) ^= IR(m[2][1]); IR(m[1][3]) ^= IR(m[3][1]); IR(m[3][1]) ^= IR(m[1][3]); IR(m[1][3]) ^= IR(m[3][1]); IR(m[2][3]) ^= IR(m[3][2]); IR(m[3][2]) ^= IR(m[2][3]); IR(m[2][3]) ^= IR(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__ ode-0.11.1/OPCODE/Ice/IceContainer.cpp0000644000076400007640000003323210414557751014026 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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; // 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.0f) { #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.0f) { #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 // Get more entries mMaxNbEntries = mMaxNbEntries ? udword(float(mMaxNbEntries)*mGrowthFactor) : 2; // Default nb Entries = 2 if(mMaxNbEntries= 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])); } ode-0.11.1/OPCODE/Ice/IceMemoryMacros.h0000644000076400007640000000674711122617066014172 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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 //! Standard allocation cycle #define SAFE_ALLOC(ptr, type, count) DELETEARRAY(ptr); ptr = new type[count]; CHECKALLOC(ptr); #endif // __ICEMEMORYMACROS_H__ ode-0.11.1/OPCODE/Ice/IcePoint.h0000644000076400007640000004622610470615264012645 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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 inline_ Point(float xx, float yy, float zz) : x(xx), y(yy), z(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 inline_ Point& Set(float xx, float yy, float zz) { x = xx; y = yy; z = 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(xmax) x=max; if(ymax) y=max; if(zmax) 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__ ode-0.11.1/OPCODE/Ice/IceLSS.h0000644000076400007640000000756110414557751012220 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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__ ode-0.11.1/OPCODE/Ice/IcePairs.h0000644000076400007640000000337310414557751012632 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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__ ode-0.11.1/OPCODE/Ice/IceIndexedTriangle.h0000644000076400007640000000666610715446136014630 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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__ ode-0.11.1/OPCODE/Ice/IceRay.h0000644000076400007640000001112010414557751012274 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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__ ode-0.11.1/OPCODE/Ice/Makefile.am0000644000076400007640000000176510765152110013006 00000000000000AM_CPPFLAGS = -I $(top_srcdir)/OPCODE -I $(top_srcdir)/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 ode-0.11.1/OPCODE/Ice/IceHPoint.cpp0000644000076400007640000000755410414557751013315 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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; } ode-0.11.1/OPCODE/Ice/IceHPoint.h0000644000076400007640000001634610470615264012755 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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__ ode-0.11.1/OPCODE/Ice/IceFPU.h0000644000076400007640000002047011122617066012174 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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 //! Integer representation of a floating-point value. #define IR(x) ((udword&)(x)) //! Signed integer representation of a floating-point value. #define SIR(x) ((sdword&)(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) ((float&)(x)) //! 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 sqrt(square); } //! Saturates positive to zero. inline_ float fsat(float f) { udword y = (udword&)f & ~((sdword&)f >>31); return (float&)y; } //! Computes 1.0f / sqrtf(x). inline_ float frsqrt(float f) { float x = f * 0.5f; udword y = 0x5f3759df - ((udword&)f >> 1); // Iteration... (float&)y = (float&)y * ( 1.5f - ( x * (float&)y * (float&)y ) ); // Result return (float&)y; } //! Computes 1.0f / sqrtf(x). Comes from NVIDIA. inline_ float InvSqrt(const float& x) { udword tmp = (udword(IEEE_1_0 << 1) + IEEE_1_0 - *(udword*)&x) >> 1; float y = *(float*)&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) { long i; float x2, y; const float threehalfs = 1.5f; x2 = number * 0.5f; y = number; i = * (long *) &y; i = 0x5f3759df - (i >> 1); y = * (float *) &i; y = y * (threehalfs - (x2 * y * y)); return y; } //! TO BE DOCUMENTED inline_ float fsqrt(float f) { udword y = ( ( (sdword&)f - 0x3f800000 ) >> 1 ) + 0x3f800000; // Iteration...? // (float&)y = (3.0f - ((float&)y * (float&)y) / f) * (float&)y * 0.5f; // Result return (float&)y; } //! Returns the float ranged espilon value. inline_ float fepsilon(float f) { udword b = (udword&)f & 0xff800000; udword a = b | 0x00000001; (float&)a -= (float&)b; // Result return (float&)a; } //! 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() { float f = 1.0f; ((udword&)f)^=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 = (int&)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__ ode-0.11.1/OPCODE/Ice/IceOBB.h0000644000076400007640000002300010414557751012143 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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__ ode-0.11.1/OPCODE/Ice/IceMatrix3x3.h0000644000076400007640000005003310732253301013334 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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 inline_ void Set(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; } //! 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() { IR(m[1][0]) ^= IR(m[0][1]); IR(m[0][1]) ^= IR(m[1][0]); IR(m[1][0]) ^= IR(m[0][1]); IR(m[2][0]) ^= IR(m[0][2]); IR(m[0][2]) ^= IR(m[2][0]); IR(m[2][0]) ^= IR(m[0][2]); IR(m[2][1]) ^= IR(m[1][2]); IR(m[1][2]) ^= IR(m[2][1]); IR(m[2][1]) ^= IR(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__ ode-0.11.1/OPCODE/Ice/IceTriList.h0000644000076400007640000000427310715446136013144 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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__ ode-0.11.1/OPCODE/Ice/IcePreprocessor.h0000644000076400007640000000712410414557751014240 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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__ ode-0.11.1/OPCODE/Ice/IceUtils.cpp0000644000076400007640000000336110414557751013204 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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; } ode-0.11.1/OPCODE/Ice/IceSegment.cpp0000644000076400007640000000361010414557751013503 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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(); } ode-0.11.1/OPCODE/OPC_PlanesAABBOverlap.h0000644000076400007640000000500010414557751014302 00000000000000/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * 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 Mller). 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</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 || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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 \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ distdir) \ || exit 1; \ fi; \ done -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -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__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-lzma: distdir tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma $(am__remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__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) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ unlzma -c $(distdir).tar.lzma | $(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) gunzip -c $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && cd $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(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 $(am__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: @cd $(distuninstallcheck_dir) \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-recursive info-am: install-data-am: install-pkgconfigDATA install-dvi: install-dvi-recursive install-exec-am: install-binSCRIPTS install-html: install-html-recursive install-info: install-info-recursive install-man: install-pdf: install-pdf-recursive install-ps: install-ps-recursive 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: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am am--refresh check check-am clean clean-generic \ clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \ dist-gzip dist-lzma 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-recursive \ uninstall uninstall-am uninstall-binSCRIPTS \ uninstall-pkgconfigDATA # 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: ode-0.11.1/aclocal.m40000644000076400007640000115064711206343407011150 00000000000000# generated automatically by aclocal 1.10.2 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008 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_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.63],, [m4_warning([this file was generated for autoconf 2.63. 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, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008 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) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) # serial 56 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.58])dnl We use AC_INCLUDES_DEFAULT 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 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_CC_BASENAME(CC) # ------------------- # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. m4_defun([_LT_CC_BASENAME], [for cc_temp in $1""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ]) # _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 _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_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options which 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 _LT_PROG_ECHO_BACKSLASH 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 "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # 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. 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' # 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_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 "X$][$1" | $Xsed -e "$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: # # ='`$ECHO "X$" | $Xsed -e "$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' # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) 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 "X\\\\\$\$var"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Fix-up fallback echo if it was mangled by the above quoting rules. case \$lt_ECHO in *'\\\[$]0 --fallback-echo"')dnl " lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\` ;; esac _LT_OUTPUT_LIBTOOL_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]) cat >"$CONFIG_LT" <<_LTEOF #! $SHELL # Generated by $as_me. # Run this file to recreate a libtool stub with the current configuration. lt_cl_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 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 ." 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) 2008 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. if test "$no_create" != yes; then lt_cl_success=: test "$silent" = yes && 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) fi ])# 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 which 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 # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $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. # _LT_COPYING _LT_LIBTOOL_TAGS # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _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 "X${COLLECT_NAMES+set}" != Xset; 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 '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) _LT_PROG_XSI_SHELLFNS sed -n '/^# Generated shell functions inserted here/,$p' "$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' TIMESTAMP='$TIMESTAMP' 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)], [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 # _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([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)]) 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], []) # _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 test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; 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" ]) 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 "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; 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" != ":"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES # -------------------------- # 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 _LT_TAGVAR(whole_archive_flag_spec, $1)='' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=echo _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 "$lt_cv_apple_cc_single_mod" != "yes"; 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 # ----------------------- # 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. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl AC_LINK_IFELSE(AC_LANG_PROGRAM,[ lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/ p } }' 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 "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [ifdef([AC_DIVERSION_NOTICE], [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], [AC_DIVERT_PUSH(NOTICE)]) $1 AC_DIVERT_POP ])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Add some code to the start of the generated configure script which # will find an echo command which doesn't interpret backslashes. m4_defun([_LT_PROG_ECHO_BACKSLASH], [_LT_SHELL_INIT([ # Check that we are running under the correct shell. SHELL=${CONFIG_SHELL-/bin/sh} case X$lt_ECHO in X*--fallback-echo) # Remove one level of quotation (which was required for Make). ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` ;; esac ECHO=${lt_ECHO-echo} if test "X[$]1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X[$]1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then # Yippee, $ECHO works! : else # Restart under the correct shell. exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} fi if test "X[$]1" = X--fallback-echo; then # used as fallback echo shift cat <<_LT_EOF [$]* _LT_EOF exit 0 fi # 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 if test -z "$lt_ECHO"; then if test "X${echo_test_string+set}" != Xset; then # find a string as large as possible, as long as the shell can cope with it for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... if { echo_test_string=`eval $cmd`; } 2>/dev/null && { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null then break fi done fi if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then : else # The Solaris, AIX, and Digital Unix default echo programs unquote # backslashes. This makes it impossible to quote backslashes using # echo "$something" | sed 's/\\/\\\\/g' # # So, first we look for a working echo in the user's PATH. lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for dir in $PATH /usr/ucb; do IFS="$lt_save_ifs" if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then ECHO="$dir/echo" break fi done IFS="$lt_save_ifs" if test "X$ECHO" = Xecho; then # We didn't find a better echo, so look for alternatives. if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # This shell has a builtin print -r that does the trick. ECHO='print -r' elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && test "X$CONFIG_SHELL" != X/bin/ksh; then # If we have ksh, try running configure again with it. ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} export ORIGINAL_CONFIG_SHELL CONFIG_SHELL=/bin/ksh export CONFIG_SHELL exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} else # Try using printf. ECHO='printf %s\n' if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # Cool, printf works : elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL export CONFIG_SHELL SHELL="$CONFIG_SHELL" export SHELL ECHO="$CONFIG_SHELL [$]0 --fallback-echo" elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then ECHO="$CONFIG_SHELL [$]0 --fallback-echo" else # maybe with a smaller string... prev=: for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null then break fi prev="$cmd" done if test "$prev" != 'sed 50q "[$]0"'; then echo_test_string=`eval $prev` export echo_test_string exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} else # Oops. We lost completely, so just stick with echo. ECHO=echo fi fi fi fi fi fi # Copy echo and quote the copy suitably for passing to libtool from # the Makefile, instead of quoting the original, which is used later. lt_ECHO=$ECHO if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" fi AC_SUBST(lt_ECHO) ]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that does not interpret backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _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 "x$enable_libtool_lock" != xno && 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 which ABI we are using. 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 which ABI we are using. echo '[#]line __oline__ "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test "$lt_cv_prog_gnu_ld" = yes; 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* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. 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*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|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" ;; ppc*-*linux*|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 x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; sparc*-*solaris*) # Find out which ABI we are using. 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*) LD="${LD-ld} -m elf64_sparc" ;; *) 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_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [AC_CHECK_TOOL(AR, ar, false) test -z "$AR" && AR=ar test -z "$AR_FLAGS" && AR_FLAGS=cru _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1]) 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 openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" fi _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_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" # 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:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:__oline__: \$? = $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 "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/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 x"[$]$2" = xyes; 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 "X$_lt_linker_boilerplate" | $Xsed -e '/^$/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 x"[$]$2" = xyes; 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; ;; 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; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # 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 ;; 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"; 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"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ = "XX$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 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 "$cross_compiling" = yes; 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 __oline__ "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #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 void fnord() { int i=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; /* 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 "x$enable_dlopen" != xyes; 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 ]) ;; *) 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 "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && 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 "x$lt_cv_dlopen_self" = xyes; 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:__oline__: $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:__oline__: \$? = $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 "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/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 "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; 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 "$hard_links" = no; 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 in which 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 "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then # We can hardcode non-existent directories. if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && # 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 "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; 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 "$_LT_TAGVAR(hardcode_action, $1)" = relink || test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; 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_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 AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then # 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 -e 's/;/ /g'` else lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # 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` 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" else 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; } }'` sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` 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 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 need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; 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 # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.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}' else # 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' fi 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=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $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 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,$host_os in yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) 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="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. 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 ;; 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 ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # 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 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 ;; freebsd1*) dynamic_linker=no ;; 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[[123]]*) 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} $libname${shared_ext}' 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 ;; 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 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 "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; 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' ;; interix[[3-9]]*) 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' 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 "$lt_cv_prog_gnu_ld" = yes; then version_type=linux 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 ;; # This must be Linux ELF. linux* | k*bsd*-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' 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 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], [shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir # 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 # find out which ABI we are using libsuff= case "$host_cpu" in x86_64*|s390x*|powerpc64*) echo '[#]line __oline__ "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *64-bit*) libsuff=64 ;; esac fi rm -rf conftest* ;; esac sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff}" # Append ld.so.conf contents 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;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $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' ;; 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 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*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac 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 if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[[89]] | openbsd2.[[89]].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; 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 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 "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux 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 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=freebsd-elf 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 "$with_gnu_ld" = yes; 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 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 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 "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi _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([], [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], [2], [Run-time system search path for libraries]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program which 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 which 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 AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test "$GCC" = yes; 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 "$with_gnu_ld" = yes; 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 &1 /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 lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' 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 ;; gnu*) 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]) 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 Linux ELF. linux* | k*bsd*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd*) 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*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; 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 ;; esac ]) 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_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 case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) 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 "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :) 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:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:__oline__: $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:__oline__: 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_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cygwin* | *-*-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 "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' _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([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 "$host_cpu" = ia64; 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 # 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 -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$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 -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/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 # and D for any global 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};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print 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 # 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 #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. */ const struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$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_save_LIBS="$LIBS" lt_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_save_LIBS" CFLAGS="$lt_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 "$pipe_works" = yes; 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 _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_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_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)= AC_MSG_CHECKING([for $compiler option to produce PIC]) m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; 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 "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; 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']) ;; 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)= ;; 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 "$host_cpu" = ia64; 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 ;; 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 "$host_cpu" != ia64; 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) 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*) # IBM XL 8.0 on PPC _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*) ;; *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*) # 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 "$GCC" = yes; 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 "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; 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']) ;; 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' ;; 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 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 "$host_cpu" = ia64; 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 ;; 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']) ;; 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) 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' ;; pgcc* | pgf77* | pgf90* | pgf95*) # 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*) # IBM XL C 8.0/Fortran 10.1 on PPC _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)='-Wl,' ;; *Sun\ F*) # 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)='' ;; 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*) _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 which 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_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # 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]) # # 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_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' 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 AIX nm, but means don't demangle with GNU 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")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' ;; linux* | k*bsd*-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 _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] ], [ 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_flag_spec_ld, $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 "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes if test "$with_gnu_ld" = yes; 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 2>&1` in *\ [[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 "$host_cpu" != ia64; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.9.1, 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 modify your PATH *** so that a non-GNU linker is found, and then restart. _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 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(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/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' 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 (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; 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 ;; 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) tmp_diet=no if test "$host_os" = linux-dietlibc; 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 "$tmp_diet" = no then tmp_addflag= 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; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95*) # 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; $ECHO \"$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' ;; xl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; 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; $ECHO \"$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 "x$supports_anon_versioning" = xyes; 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 xlf*) # 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)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; 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 $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd*) 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 $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' 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 $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 ;; 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 can not *** 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 $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 if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; 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 "$GCC" = yes && 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 "$host_cpu" = ia64; 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 AIX nm, but means don't demangle with GNU 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")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | 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 # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; 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,' if test "$GCC" = yes; 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 "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi _LT_TAGVAR(link_all_deplibs, $1)=no else # not using gcc if test "$host_cpu" = ia64; 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 "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi 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_use_runtimelinking" = yes; 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 _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 "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; 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 _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' # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' 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. _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 `$ECHO "X$deplibs" | $Xsed -e '\''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(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; 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 ;; freebsd1*) _LT_TAGVAR(ld_shlibs, $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 -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 "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $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 $output_objdir/$soname = $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 "$GCC" = yes -a "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${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 "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $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 "$GCC" = yes -a "$with_gnu_ld" = no; 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 -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${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' ;; *) _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 "$with_gnu_ld" = no; 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 "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${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. save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" AC_LINK_IFELSE(int foo(void) {}, _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' ) LDFLAGS="$save_LDFLAGS" else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -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" && $ECHO "X-set_version $verstring" | $Xsed` -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 ;; netbsd*) 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*) 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__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; 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 case $host_os in openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ;; *) _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' ;; esac 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 _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; 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" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${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" && $ECHO "X-set_version $verstring" | $Xsed` -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 "$GCC" = yes; 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}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${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" && $ECHO "X-set_version $verstring" | $Xsed` -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 "X-set_version $verstring" | $Xsed` -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 "$GCC" = yes; then wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${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 ${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 "$GCC" = yes; 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 "x$host_vendor" = xsequent; 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 "$GCC" = yes; 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 can NOT 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 "$GCC" = yes; 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 x$host_vendor = xsni; 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 "$_LT_TAGVAR(ld_shlibs, $1)" = no && 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 "$enable_shared" = yes && test "$GCC" = yes; 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_MSG_CHECKING([whether -lc should be explicitly linked in]) $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_TAGVAR(archive_cmds_need_lc, $1)=no else _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* AC_MSG_RESULT([$_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_flag_spec_ld], [1], [[If ld is used when linking, 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([], [fix_srcfile_path], [1], [Fix the shell variable $srcfile for the compiler]) _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([], [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 which 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 "$can_build_shared" = "no" && 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 "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no 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 "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC="$lt_save_CC" ])# _LT_LANG_C_CONFIG # _LT_PROG_CXX # ------------ # Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++ # compiler, we have our own version here. m4_defun([_LT_PROG_CXX], [ pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes]) AC_PROG_CXX if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi popdef([AC_MSG_ERROR]) ])# _LT_PROG_CXX dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([_LT_PROG_CXX], []) # _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], [AC_REQUIRE([_LT_PROG_CXX])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl 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_flag_spec_ld, $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(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 "$_lt_caught_CXX_error" != yes; 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_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++"} 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 "$GXX" = yes; 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 "$GXX" = yes; 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 "$with_gnu_ld" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -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 "\-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 "$host_cpu" = ia64; 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 # need to do runtime linking. 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 ;; 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,' if test "$GXX" = yes; 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 "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; 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 "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi 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_use_runtimelinking" = yes; 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 _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 "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; 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 _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' # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared # libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach 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*) # _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(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 (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; 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 ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; 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 ;; freebsd[[12]]*) # 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 ;; gnu*) ;; 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 $output_objdir/$soname = $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; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $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 $with_gnu_ld = no; 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; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; 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 -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${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" && $ECHO "X-set_version $verstring" | $Xsed` -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 "$GXX" = yes; then if test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -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) 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; $ECHO "X$list" | $Xsed' _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 | $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 | $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 | $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 | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 will 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; $ECHO \"$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=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; xl*) # 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 "x$supports_anon_versioning" = xyes; 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; $ECHO \"$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='echo' # 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 ;; openbsd2*) # C++ shared libraries are fairly broken _LT_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) 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__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; 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=echo 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" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -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" && $ECHO "X-set_version $verstring" | $Xsed` -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 "X-set_version $verstring" | $Xsed` -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=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; 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" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${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 "\-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*) # 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='echo' # 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 "$GXX" = yes && test "$with_gnu_ld" = no; 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 -nostdlib $LDFLAGS $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 -nostdlib ${wl}-M $wl$lib.exp -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 "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $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 -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 "\-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 can NOT 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(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 "$_LT_TAGVAR(ld_shlibs, $1)" = no && 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 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 "$_lt_caught_CXX_error" != yes AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _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 # 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 ]) 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 $p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue else prev= fi if test "$pre_test_object_deps_done" = no; then case $p 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 ;; *.$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 "$pre_test_object_deps_done" = no; 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 # 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)= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; 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_PROG_F77 # ------------ # Since AC_PROG_F77 is broken, in that it returns the empty string # if there is no fortran compiler, we have our own version here. m4_defun([_LT_PROG_F77], [ pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes]) AC_PROG_F77 if test -z "$F77" || test "X$F77" = "Xno"; then _lt_disable_F77=yes fi popdef([AC_MSG_ERROR]) ])# _LT_PROG_F77 dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([_LT_PROG_F77], []) # _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_REQUIRE([_LT_PROG_F77])dnl AC_LANG_PUSH(Fortran 77) _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_flag_spec_ld, $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(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 "$_lt_disable_F77" != yes; 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 CC=${F77-"f77"} 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 "$can_build_shared" = "no" && 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 "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no 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 "$enable_shared" = yes || 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" fi # test "$_lt_disable_F77" != yes AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_PROG_FC # ----------- # Since AC_PROG_FC is broken, in that it returns the empty string # if there is no fortran compiler, we have our own version here. m4_defun([_LT_PROG_FC], [ pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes]) AC_PROG_FC if test -z "$FC" || test "X$FC" = "Xno"; then _lt_disable_FC=yes fi popdef([AC_MSG_ERROR]) ])# _LT_PROG_FC dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([_LT_PROG_FC], []) # _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_REQUIRE([_LT_PROG_FC])dnl AC_LANG_PUSH(Fortran) _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_flag_spec_ld, $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(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 "$_lt_disable_FC" != yes; 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 CC=${FC-"f95"} 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 "$can_build_shared" = "no" && 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 "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no 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 "$enable_shared" = yes || 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" fi # test "$_lt_disable_FC" != yes 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_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} 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 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" ])# _LT_LANG_GCJ_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_GCC=$GCC GCC= CC=${RC-"windres"} 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" ])# _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 "x${GCJFLAGS+set}" = xset || 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_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_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 $lt_ac_count -gt 10 && 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], [AC_MSG_CHECKING([whether the shell understands some XSI constructs]) # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes AC_MSG_RESULT([$xsi_shell]) _LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) AC_MSG_CHECKING([whether the shell understands "+="]) lt_shell_append=no ( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes AC_MSG_RESULT([$lt_shell_append]) _LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) 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_PROG_XSI_SHELLFNS # --------------------- # Bourne and XSI compatible variants of some useful shell functions. m4_defun([_LT_PROG_XSI_SHELLFNS], [case $xsi_shell in yes) cat << \_LT_EOF >> "$cfgfile" # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac } # func_basename file func_basename () { func_basename_result="${1##*/}" } # 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" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}" } # func_stripname 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). func_stripname () { # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"} } # func_opt_split func_opt_split () { func_opt_split_opt=${1%%=*} func_opt_split_arg=${1#*=} } # func_lo2o object func_lo2o () { case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac } # func_xform libobj-or-source func_xform () { func_xform_result=${1%.*}.lo } # func_arith arithmetic-term... func_arith () { func_arith_result=$(( $[*] )) } # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=${#1} } _LT_EOF ;; *) # Bourne compatible functions. cat << \_LT_EOF >> "$cfgfile" # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_basename file func_basename () { func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` } dnl func_dirname_and_basename dnl A portable version of this function is already defined in general.m4sh dnl so there is no need for it here. # func_stripname 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). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "X${3}" \ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "X${3}" \ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; esac } # sed scripts: my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q' my_sed_long_arg='1s/^-[[^=]]*=//' # func_opt_split func_opt_split () { func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` } # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` } # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'` } # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "$[@]"` } # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len` } _LT_EOF esac case $lt_shell_append in yes) cat << \_LT_EOF >> "$cfgfile" # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "$[1]+=\$[2]" } _LT_EOF ;; *) cat << \_LT_EOF >> "$cfgfile" # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "$[1]=\$$[1]\$[2]" } _LT_EOF ;; esac ]) # Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004, 2005, 2007, 2008 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 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_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], [0], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [0], [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_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], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [pic_mode="$withval"], [pic_mode=default]) test -z "$pic_mode" && 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 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 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. # Generated from ltversion.in. # serial 3012 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.2.6]) m4_define([LT_PACKAGE_REVISION], [1.3012]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.2.6' macro_revision='1.3012' _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 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 4 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_RC], [AC_DEFUN([AC_LIBTOOL_RC])]) 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])]) # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 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.10' 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.10.2], [], [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.10.2])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, 2003, 2005 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], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006 # 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. # serial 8 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$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 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, 2000, 2001, 2002, 2003, 2004, 2005, 2006 # 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. # serial 9 # 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", "GCJ", or "OBJC". # 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 ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" 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'. 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 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 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in 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 ;; none) break ;; esac # 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. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} 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 sub/conftest.${OBJEXT-o} 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, [ --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 # 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. #serial 4 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [# Autoconf 2.62 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"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //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' -e 's/\$U/'"$U"'/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, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2008 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. # serial 13 # 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. # 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.60])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], [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], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, [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) AM_PROG_INSTALL_SH AM_PROG_INSTALL_STRIP AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. 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)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES(OBJC)], [define([AC_PROG_OBJC], defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ]) ]) # 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, 2003, 2005 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 install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 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. # serial 2 # 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, 2002, 2003, 2005 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. # serial 3 # 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 done .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 # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008 # 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. # serial 6 # AM_PROG_CC_C_O # -------------- # Like AC_PROG_CC_C_O, but changed for automake. AC_DEFUN([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC_C_O])dnl AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl # FIXME: we rely on the cache variable name because # there is no other way. set dummy $CC am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o if test "$am_t" != 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 dnl Make sure AC_PROG_CC is never called again, or it will override our dnl setting of CC. m4_define([AC_PROG_CC], [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005 # 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. # serial 5 # 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 supports --run. # If it does, 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 test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # Copyright (C) 2003, 2004, 2005, 2006 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_MKDIR_P # --------------- # Check for `mkdir -p'. AC_DEFUN([AM_PROG_MKDIR_P], [AC_PREREQ([2.60])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, dnl while keeping a definition of mkdir_p for backward compatibility. dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of dnl Makefile.ins that do not define MKDIR_P, so we do our own dnl adjustment using top_builddir (which is defined more often than dnl MKDIR_P). AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl case $mkdir_p in [[\\/$]]* | ?:[[\\/]]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2008 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. # serial 4 # _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])]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # 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. # serial 4 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # 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 ( 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 rm -f conftest.file 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 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)]) # Copyright (C) 2001, 2003, 2005 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 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]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005 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. # serial 2 # _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. AM_MISSING_PROG([AMTAR], [tar]) m4_if([$1], [v7], [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. 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 /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 ode-0.11.1/tests/0000777000076400007640000000000011206343457010525 500000000000000ode-0.11.1/tests/joint.cpp0000644000076400007640000030171011140354003012254 00000000000000/************************************************************************* * * * 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 #include #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) // ///
///^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
//
/// 
///^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)
ode-0.11.1/tests/Makefile.in0000644000076400007640000010735111206343412012504 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@

# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008  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@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@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
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
	$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/ode/src/config.h
CONFIG_CLEAN_FILES =
am_tests_OBJECTS = main.$(OBJEXT) joint.$(OBJEXT) odemath.$(OBJEXT) \
	collision.$(OBJEXT) ball.$(OBJEXT) fixed.$(OBJEXT) \
	hinge.$(OBJEXT) hinge2.$(OBJEXT) piston.$(OBJEXT) pr.$(OBJEXT) \
	pu.$(OBJEXT) slider.$(OBJEXT) universal.$(OBJEXT)
tests_OBJECTS = $(am_tests_OBJECTS)
tests_LDADD = $(LDADD)
tests_DEPENDENCIES = $(builddir)/UnitTest++/src/libunittestpp.la \
	$(top_builddir)/ode/src/libode.la
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
	--mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
	--mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
	$(LDFLAGS) -o $@
SOURCES = $(tests_SOURCES)
DIST_SOURCES = $(tests_SOURCES)
RECURSIVE_TARGETS = all-recursive check-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 uninstall-recursive
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
  distclean-recursive maintainer-clean-recursive
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
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@
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@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
ODE_PRECISION = @ODE_PRECISION@
ODE_RELEASE = @ODE_RELEASE@
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_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
WINDRES = @WINDRES@
XMKMF = @XMKMF@
X_CFLAGS = @X_CFLAGS@
X_EXTRA_LIBS = @X_EXTRA_LIBS@
X_LIBS = @X_LIBS@
X_PRE_LIBS = @X_PRE_LIBS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
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@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
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 = UnitTest++
AM_CPPFLAGS = -I $(srcdir)/UnitTest++/src -I $(top_srcdir)/include -I \
	$(top_srcdir)/ode/src $(am__append_1) $(am__append_2)
LDADD = $(builddir)/UnitTest++/src/libunittestpp.la \
        $(top_builddir)/ode/src/libode.la

tests_SOURCES = main.cpp joint.cpp odemath.cpp collision.cpp \
                joints/ball.cpp \
                joints/fixed.cpp \
                joints/hinge.cpp \
                joints/hinge2.cpp \
                joints/piston.cpp \
                joints/pr.cpp \
                joints/pu.cpp \
                joints/slider.cpp \
                joints/universal.cpp

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/Makefile'; \
	cd $(top_srcdir) && \
	  $(AUTOMAKE) --foreign  tests/Makefile
.PRECIOUS: 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

clean-checkPROGRAMS:
	@list='$(check_PROGRAMS)'; for p in $$list; do \
	  f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
	  echo " rm -f $$p $$f"; \
	  rm -f $$p $$f ; \
	done
tests$(EXEEXT): $(tests_OBJECTS) $(tests_DEPENDENCIES) 
	@rm -f tests$(EXEEXT)
	$(CXXLINK) $(tests_OBJECTS) $(tests_LDADD) $(LIBS)

mostlyclean-compile:
	-rm -f *.$(OBJEXT)

distclean-compile:
	-rm -f *.tab.c

@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ball.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collision.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fixed.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hinge.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hinge2.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@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/piston.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pu.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slider.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/universal.Po@am__quote@

.cpp.o:
@am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ $<

.cpp.obj:
@am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`

.cpp.lo:
@am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(LTCXXCOMPILE) -c -o $@ $<

ball.o: joints/ball.cpp
@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ball.o -MD -MP -MF $(DEPDIR)/ball.Tpo -c -o ball.o `test -f 'joints/ball.cpp' || echo '$(srcdir)/'`joints/ball.cpp
@am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/ball.Tpo $(DEPDIR)/ball.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='joints/ball.cpp' object='ball.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ball.o `test -f 'joints/ball.cpp' || echo '$(srcdir)/'`joints/ball.cpp

ball.obj: joints/ball.cpp
@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ball.obj -MD -MP -MF $(DEPDIR)/ball.Tpo -c -o ball.obj `if test -f 'joints/ball.cpp'; then $(CYGPATH_W) 'joints/ball.cpp'; else $(CYGPATH_W) '$(srcdir)/joints/ball.cpp'; fi`
@am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/ball.Tpo $(DEPDIR)/ball.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='joints/ball.cpp' object='ball.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ball.obj `if test -f 'joints/ball.cpp'; then $(CYGPATH_W) 'joints/ball.cpp'; else $(CYGPATH_W) '$(srcdir)/joints/ball.cpp'; fi`

fixed.o: joints/fixed.cpp
@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT fixed.o -MD -MP -MF $(DEPDIR)/fixed.Tpo -c -o fixed.o `test -f 'joints/fixed.cpp' || echo '$(srcdir)/'`joints/fixed.cpp
@am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/fixed.Tpo $(DEPDIR)/fixed.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='joints/fixed.cpp' object='fixed.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o fixed.o `test -f 'joints/fixed.cpp' || echo '$(srcdir)/'`joints/fixed.cpp

fixed.obj: joints/fixed.cpp
@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT fixed.obj -MD -MP -MF $(DEPDIR)/fixed.Tpo -c -o fixed.obj `if test -f 'joints/fixed.cpp'; then $(CYGPATH_W) 'joints/fixed.cpp'; else $(CYGPATH_W) '$(srcdir)/joints/fixed.cpp'; fi`
@am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/fixed.Tpo $(DEPDIR)/fixed.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='joints/fixed.cpp' object='fixed.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o fixed.obj `if test -f 'joints/fixed.cpp'; then $(CYGPATH_W) 'joints/fixed.cpp'; else $(CYGPATH_W) '$(srcdir)/joints/fixed.cpp'; fi`

hinge.o: joints/hinge.cpp
@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT hinge.o -MD -MP -MF $(DEPDIR)/hinge.Tpo -c -o hinge.o `test -f 'joints/hinge.cpp' || echo '$(srcdir)/'`joints/hinge.cpp
@am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/hinge.Tpo $(DEPDIR)/hinge.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='joints/hinge.cpp' object='hinge.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o hinge.o `test -f 'joints/hinge.cpp' || echo '$(srcdir)/'`joints/hinge.cpp

hinge.obj: joints/hinge.cpp
@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT hinge.obj -MD -MP -MF $(DEPDIR)/hinge.Tpo -c -o hinge.obj `if test -f 'joints/hinge.cpp'; then $(CYGPATH_W) 'joints/hinge.cpp'; else $(CYGPATH_W) '$(srcdir)/joints/hinge.cpp'; fi`
@am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/hinge.Tpo $(DEPDIR)/hinge.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='joints/hinge.cpp' object='hinge.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o hinge.obj `if test -f 'joints/hinge.cpp'; then $(CYGPATH_W) 'joints/hinge.cpp'; else $(CYGPATH_W) '$(srcdir)/joints/hinge.cpp'; fi`

hinge2.o: joints/hinge2.cpp
@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT hinge2.o -MD -MP -MF $(DEPDIR)/hinge2.Tpo -c -o hinge2.o `test -f 'joints/hinge2.cpp' || echo '$(srcdir)/'`joints/hinge2.cpp
@am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/hinge2.Tpo $(DEPDIR)/hinge2.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='joints/hinge2.cpp' object='hinge2.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o hinge2.o `test -f 'joints/hinge2.cpp' || echo '$(srcdir)/'`joints/hinge2.cpp

hinge2.obj: joints/hinge2.cpp
@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT hinge2.obj -MD -MP -MF $(DEPDIR)/hinge2.Tpo -c -o hinge2.obj `if test -f 'joints/hinge2.cpp'; then $(CYGPATH_W) 'joints/hinge2.cpp'; else $(CYGPATH_W) '$(srcdir)/joints/hinge2.cpp'; fi`
@am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/hinge2.Tpo $(DEPDIR)/hinge2.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='joints/hinge2.cpp' object='hinge2.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o hinge2.obj `if test -f 'joints/hinge2.cpp'; then $(CYGPATH_W) 'joints/hinge2.cpp'; else $(CYGPATH_W) '$(srcdir)/joints/hinge2.cpp'; fi`

piston.o: joints/piston.cpp
@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT piston.o -MD -MP -MF $(DEPDIR)/piston.Tpo -c -o piston.o `test -f 'joints/piston.cpp' || echo '$(srcdir)/'`joints/piston.cpp
@am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/piston.Tpo $(DEPDIR)/piston.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='joints/piston.cpp' object='piston.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o piston.o `test -f 'joints/piston.cpp' || echo '$(srcdir)/'`joints/piston.cpp

piston.obj: joints/piston.cpp
@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT piston.obj -MD -MP -MF $(DEPDIR)/piston.Tpo -c -o piston.obj `if test -f 'joints/piston.cpp'; then $(CYGPATH_W) 'joints/piston.cpp'; else $(CYGPATH_W) '$(srcdir)/joints/piston.cpp'; fi`
@am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/piston.Tpo $(DEPDIR)/piston.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='joints/piston.cpp' object='piston.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o piston.obj `if test -f 'joints/piston.cpp'; then $(CYGPATH_W) 'joints/piston.cpp'; else $(CYGPATH_W) '$(srcdir)/joints/piston.cpp'; fi`

pr.o: joints/pr.cpp
@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT pr.o -MD -MP -MF $(DEPDIR)/pr.Tpo -c -o pr.o `test -f 'joints/pr.cpp' || echo '$(srcdir)/'`joints/pr.cpp
@am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/pr.Tpo $(DEPDIR)/pr.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='joints/pr.cpp' object='pr.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o pr.o `test -f 'joints/pr.cpp' || echo '$(srcdir)/'`joints/pr.cpp

pr.obj: joints/pr.cpp
@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT pr.obj -MD -MP -MF $(DEPDIR)/pr.Tpo -c -o pr.obj `if test -f 'joints/pr.cpp'; then $(CYGPATH_W) 'joints/pr.cpp'; else $(CYGPATH_W) '$(srcdir)/joints/pr.cpp'; fi`
@am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/pr.Tpo $(DEPDIR)/pr.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='joints/pr.cpp' object='pr.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o pr.obj `if test -f 'joints/pr.cpp'; then $(CYGPATH_W) 'joints/pr.cpp'; else $(CYGPATH_W) '$(srcdir)/joints/pr.cpp'; fi`

pu.o: joints/pu.cpp
@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT pu.o -MD -MP -MF $(DEPDIR)/pu.Tpo -c -o pu.o `test -f 'joints/pu.cpp' || echo '$(srcdir)/'`joints/pu.cpp
@am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/pu.Tpo $(DEPDIR)/pu.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='joints/pu.cpp' object='pu.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o pu.o `test -f 'joints/pu.cpp' || echo '$(srcdir)/'`joints/pu.cpp

pu.obj: joints/pu.cpp
@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT pu.obj -MD -MP -MF $(DEPDIR)/pu.Tpo -c -o pu.obj `if test -f 'joints/pu.cpp'; then $(CYGPATH_W) 'joints/pu.cpp'; else $(CYGPATH_W) '$(srcdir)/joints/pu.cpp'; fi`
@am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/pu.Tpo $(DEPDIR)/pu.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='joints/pu.cpp' object='pu.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o pu.obj `if test -f 'joints/pu.cpp'; then $(CYGPATH_W) 'joints/pu.cpp'; else $(CYGPATH_W) '$(srcdir)/joints/pu.cpp'; fi`

slider.o: joints/slider.cpp
@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT slider.o -MD -MP -MF $(DEPDIR)/slider.Tpo -c -o slider.o `test -f 'joints/slider.cpp' || echo '$(srcdir)/'`joints/slider.cpp
@am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/slider.Tpo $(DEPDIR)/slider.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='joints/slider.cpp' object='slider.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o slider.o `test -f 'joints/slider.cpp' || echo '$(srcdir)/'`joints/slider.cpp

slider.obj: joints/slider.cpp
@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT slider.obj -MD -MP -MF $(DEPDIR)/slider.Tpo -c -o slider.obj `if test -f 'joints/slider.cpp'; then $(CYGPATH_W) 'joints/slider.cpp'; else $(CYGPATH_W) '$(srcdir)/joints/slider.cpp'; fi`
@am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/slider.Tpo $(DEPDIR)/slider.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='joints/slider.cpp' object='slider.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o slider.obj `if test -f 'joints/slider.cpp'; then $(CYGPATH_W) 'joints/slider.cpp'; else $(CYGPATH_W) '$(srcdir)/joints/slider.cpp'; fi`

universal.o: joints/universal.cpp
@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT universal.o -MD -MP -MF $(DEPDIR)/universal.Tpo -c -o universal.o `test -f 'joints/universal.cpp' || echo '$(srcdir)/'`joints/universal.cpp
@am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/universal.Tpo $(DEPDIR)/universal.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='joints/universal.cpp' object='universal.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o universal.o `test -f 'joints/universal.cpp' || echo '$(srcdir)/'`joints/universal.cpp

universal.obj: joints/universal.cpp
@am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT universal.obj -MD -MP -MF $(DEPDIR)/universal.Tpo -c -o universal.obj `if test -f 'joints/universal.cpp'; then $(CYGPATH_W) 'joints/universal.cpp'; else $(CYGPATH_W) '$(srcdir)/joints/universal.cpp'; fi`
@am__fastdepCXX_TRUE@	mv -f $(DEPDIR)/universal.Tpo $(DEPDIR)/universal.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='joints/universal.cpp' object='universal.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o universal.obj `if test -f 'joints/universal.cpp'; then $(CYGPATH_W) 'joints/universal.cpp'; else $(CYGPATH_W) '$(srcdir)/joints/universal.cpp'; fi`

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.
$(RECURSIVE_TARGETS):
	@failcom='exit 1'; \
	for f in x $$MAKEFLAGS; do \
	  case $$f in \
	    *=* | --[!k]*);; \
	    *k*) failcom='fail=yes';; \
	  esac; \
	done; \
	dot_seen=no; \
	target=`echo $@ | sed s/-recursive//`; \
	list='$(SUBDIRS)'; 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; \
	  (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"

$(RECURSIVE_CLEAN_TARGETS):
	@failcom='exit 1'; \
	for f in x $$MAKEFLAGS; do \
	  case $$f in \
	    *=* | --[!k]*);; \
	    *k*) failcom='fail=yes';; \
	  esac; \
	done; \
	dot_seen=no; \
	case "$@" in \
	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
	  *) list='$(SUBDIRS)' ;; \
	esac; \
	rev=''; for subdir in $$list; do \
	  if test "$$subdir" = "."; then :; else \
	    rev="$$subdir $$rev"; \
	  fi; \
	done; \
	rev="$$rev ."; \
	target=`echo $@ | sed s/-recursive//`; \
	for subdir in $$rev; do \
	  echo "Making $$target in $$subdir"; \
	  if test "$$subdir" = "."; then \
	    local_target="$$target-am"; \
	  else \
	    local_target="$$target"; \
	  fi; \
	  (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
	  || eval $$failcom; \
	done && test -z "$$fail"
tags-recursive:
	list='$(SUBDIRS)'; for subdir in $$list; do \
	  test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
	done
ctags-recursive:
	list='$(SUBDIRS)'; for subdir in $$list; do \
	  test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
	done

ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
	unique=`for i in $$list; do \
	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
	  done | \
	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
	      END { if (nonempty) { for (i in files) print i; }; }'`; \
	mkid -fID $$unique
tags: TAGS

TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
		$(TAGS_FILES) $(LISP)
	tags=; \
	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 || \
	      tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
	  fi; \
	done; \
	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
	unique=`for i in $$list; do \
	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
	  done | \
	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
	      END { if (nonempty) { for (i in files) print i; }; }'`; \
	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
	  test -n "$$unique" || unique=$$empty_fix; \
	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
	    $$tags $$unique; \
	fi
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
		$(TAGS_FILES) $(LISP)
	tags=; \
	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
	unique=`for i in $$list; do \
	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
	  done | \
	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
	      END { if (nonempty) { for (i in files) print i; }; }'`; \
	test -z "$(CTAGS_ARGS)$$tags$$unique" \
	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
	     $$tags $$unique

GTAGS:
	here=`$(am__cd) $(top_builddir) && pwd` \
	  && cd $(top_srcdir) \
	  && gtags -i $(GTAGS_ARGS) $$here

distclean-tags:
	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags

check-TESTS: $(TESTS)
	@failed=0; all=0; xfail=0; xpass=0; skip=0; \
	srcdir=$(srcdir); export srcdir; \
	list=' $(TESTS) '; \
	if test -n "$$list"; then \
	  for tst in $$list; do \
	    if test -f ./$$tst; then dir=./; \
	    elif test -f $$tst; then dir=; \
	    else dir="$(srcdir)/"; fi; \
	    if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
	      all=`expr $$all + 1`; \
	      case " $(XFAIL_TESTS) " in \
	      *[\ \	]$$tst[\ \	]*) \
		xpass=`expr $$xpass + 1`; \
		failed=`expr $$failed + 1`; \
		echo "XPASS: $$tst"; \
	      ;; \
	      *) \
		echo "PASS: $$tst"; \
	      ;; \
	      esac; \
	    elif test $$? -ne 77; then \
	      all=`expr $$all + 1`; \
	      case " $(XFAIL_TESTS) " in \
	      *[\ \	]$$tst[\ \	]*) \
		xfail=`expr $$xfail + 1`; \
		echo "XFAIL: $$tst"; \
	      ;; \
	      *) \
		failed=`expr $$failed + 1`; \
		echo "FAIL: $$tst"; \
	      ;; \
	      esac; \
	    else \
	      skip=`expr $$skip + 1`; \
	      echo "SKIP: $$tst"; \
	    fi; \
	  done; \
	  if test "$$all" -eq 1; then \
	    tests="test"; \
	    All=""; \
	  else \
	    tests="tests"; \
	    All="All "; \
	  fi; \
	  if test "$$failed" -eq 0; then \
	    if test "$$xfail" -eq 0; then \
	      banner="$$All$$all $$tests passed"; \
	    else \
	      if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
	      banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
	    fi; \
	  else \
	    if test "$$xpass" -eq 0; then \
	      banner="$$failed of $$all $$tests failed"; \
	    else \
	      if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
	      banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
	    fi; \
	  fi; \
	  dashes="$$banner"; \
	  skipped=""; \
	  if test "$$skip" -ne 0; then \
	    if test "$$skip" -eq 1; then \
	      skipped="($$skip test was not run)"; \
	    else \
	      skipped="($$skip tests were not run)"; \
	    fi; \
	    test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
	      dashes="$$skipped"; \
	  fi; \
	  report=""; \
	  if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
	    report="Please report to $(PACKAGE_BUGREPORT)"; \
	    test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
	      dashes="$$report"; \
	  fi; \
	  dashes=`echo "$$dashes" | sed s/./=/g`; \
	  echo "$$dashes"; \
	  echo "$$banner"; \
	  test -z "$$skipped" || echo "$$skipped"; \
	  test -z "$$report" || echo "$$report"; \
	  echo "$$dashes"; \
	  test "$$failed" -eq 0; \
	else :; fi

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 $(srcdir)/$$file && test $$d != $(srcdir); then \
	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
	    fi; \
	    cp -pR $$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 \
	    test -d "$(distdir)/$$subdir" \
	    || $(MKDIR_P) "$(distdir)/$$subdir" \
	    || exit 1; \
	    distdir=`$(am__cd) $(distdir) && pwd`; \
	    top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
	    (cd $$subdir && \
	      $(MAKE) $(AM_MAKEFLAGS) \
	        top_distdir="$$top_distdir" \
	        distdir="$$distdir/$$subdir" \
		am__remove_distdir=: \
		am__skip_length_check=: \
	        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:
	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
	  `test -z '$(STRIP)' || \
	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:

clean-generic:

distclean-generic:
	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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

info: info-recursive

info-am:

install-data-am:

install-dvi: install-dvi-recursive

install-exec-am:

install-html: install-html-recursive

install-info: install-info-recursive

install-man:

install-pdf: install-pdf-recursive

install-ps: install-ps-recursive

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: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \
	install-strip

.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
	all all-am check check-TESTS check-am clean \
	clean-checkPROGRAMS clean-generic clean-libtool ctags \
	ctags-recursive 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-recursive uninstall uninstall-am

# 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:
ode-0.11.1/tests/collision.cpp0000644000076400007640000000653011147374032013141 00000000000000#include 
#include 

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

    dInitODE();

    {
        const int VertexCount = 4;
        const int IndexCount = 2*3;
        // this is a square on the XY plane
        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);
        dGeomSetPosition(sphere, 0,0,radius);
        dContactGeom cg[4];
        int nc;

        // check extreme case
        nc = dCollide(trimesh, sphere, 4, &cg[0], sizeof cg[0]);
        CHECK_EQUAL(1, nc);
        CHECK_EQUAL(0, cg[0].depth);
        
        // 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(1, nc);
        CHECK_EQUAL(0, cg[0].depth);
        
        // 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(1, nc);
        CHECK_EQUAL(0, cg[0].depth);
    }
    dCloseODE();
}



TEST(test_collision_heightfield_ray_fail)
{
    /*
     * This test demonstrated a bug in the AABB handling of the
     * heightfield.
     */
    dInitODE();
    {
        // 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];

        // Crash!
        dCollide(ray, height, 10, &(contactBuf[0].geom), sizeof(dContact));

        dGeomDestroy(height);
        dGeomDestroy(ray);
        dGeomHeightfieldDataDestroy(heightfieldData);
    }
    dCloseODE();
}

ode-0.11.1/tests/main.cpp0000644000076400007640000000025211075411332012060 00000000000000// openode_UnitTest++.cpp : Defines the entry point for the console application.
//

#include 

int main()
{
    return UnitTest::RunAllTests();
}
ode-0.11.1/tests/odemath.cpp0000644000076400007640000001553711102044052012561 00000000000000/*************************************************************************
 *                                                                       *
 * 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 
#include 
#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(dLENGTH(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(dLENGTH(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(dLENGTH(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(dLENGTH(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(dLENGTH(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(dLENGTH(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(dLENGTH(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(dLENGTH(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(dLENGTH(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(dLENGTH(v), REAL(1.0));

    v[0] = REAL(-0.1);
    v[1] = REAL(0.0);
    v[2] = REAL(0.0);
    dSafeNormalize3(v);
    CHECK_EQUAL(dLENGTH(v), REAL(1.0));

    v[0] = REAL(-1e-20);
    v[1] = REAL(0.0);
    v[2] = REAL(0.0);
    dSafeNormalize3(v);
    CHECK_EQUAL(dLENGTH(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(dLENGTH(v), REAL(1.0));

    v[0] = REAL(0.0);
    v[1] = REAL(-0.1);
    v[2] = REAL(0.0);
    dSafeNormalize3(v);
    CHECK_EQUAL(dLENGTH(v), REAL(1.0));

    v[0] = REAL(0.0);
    v[1] = REAL(-1e-20);
    v[2] = REAL(0.0);
    dSafeNormalize3(v);
    CHECK_EQUAL(dLENGTH(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(dLENGTH(v), REAL(1.0));

    v[0] = REAL(0.0);
    v[1] = REAL(0.0);
    v[2] = REAL(-0.1);
    dSafeNormalize3(v);
    CHECK_EQUAL(dLENGTH(v), REAL(1.0));

    v[0] = REAL(0.0);
    v[1] = REAL(0.0);
    v[2] = REAL(-1e-20);
    dSafeNormalize3(v);
    CHECK_EQUAL(dLENGTH(v), REAL(1.0));


    v[0] = REAL(9999999999.0);
    v[1] = REAL(0.0);
    v[2] = REAL(1e-20);
    dSafeNormalize3(v);
    CHECK_EQUAL(dLENGTH(v), REAL(1.0));


    v[0] = REAL(9999999999.0);
    v[1] = REAL(9999.0);
    v[2] = REAL(9.0);
    dSafeNormalize3(v);
    CHECK_EQUAL(dLENGTH(v), REAL(1.0));

}


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);
    }

}
ode-0.11.1/tests/Makefile.am0000644000076400007640000000144711147374032012500 00000000000000SUBDIRS = UnitTest++

AM_CPPFLAGS = -I $(srcdir)/UnitTest++/src \
              -I $(top_srcdir)/include \
              -I $(top_srcdir)/ode/src

if GIMPACT
    AM_CPPFLAGS += -DdTRIMESH_ENABLED -DdTRIMESH_GIMPACT
endif
if OPCODE
    AM_CPPFLAGS += -DdTRIMESH_ENABLED -DdTRIMESH_OPCODE
endif

LDADD = $(builddir)/UnitTest++/src/libunittestpp.la \
        $(top_builddir)/ode/src/libode.la

check_PROGRAMS = tests

TESTS = tests

tests_SOURCES = main.cpp joint.cpp odemath.cpp collision.cpp \
                joints/ball.cpp \
                joints/fixed.cpp \
                joints/hinge.cpp \
                joints/hinge2.cpp \
                joints/piston.cpp \
                joints/pr.cpp \
                joints/pu.cpp \
                joints/slider.cpp \
                joints/universal.cpp

ode-0.11.1/tests/UnitTest++/0000777000076400007640000000000011206343457012432 500000000000000ode-0.11.1/tests/UnitTest++/docs/0000777000076400007640000000000011206343336013356 500000000000000ode-0.11.1/tests/UnitTest++/docs/UnitTest++.html0000644000076400007640000003011110716133106016056 00000000000000

	UnitTest++ in brief


UnitTest++ in brief

Introduction

This little document serves as bare-bones documentation for UnitTest++.

For background, goals and license details, see:

The documentation, while sparse, aims to be practical, so it should give you enough info to get started using UnitTest++ as fast as possible.

Building UnitTest++

Building UnitTest++ will be specific to each platform and build environment, but it should be straightforward.

Building with Visual Studio

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.

Building with Make

The bundled makefile is written to build with g++. It also needs sed installed in the path, and to be able to use the mv and rm shell commands. The makefile should be usable on most Posix-like platforms.

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.

Packaging

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 UnitTest++/src/ and its per-platform subfolders. The tests directory only contains the unit tests for the library, and need not be included.

Using UnitTest++

The source code for UnitTest++ comes with a full test suite written using UnitTest++. This is a great place to learn techniques for testing. There is one sample .cpp file: UnitTest++/src/tests/TestUnitTest++.cpp. 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.

Getting started

Listed below is a minimal C++ program to run a failing test through UnitTest++.

  // test.cpp
  #include <UnitTest++.h>

  TEST(FailSpectacularly)
  {
    CHECK(false);
  }

  int main()
  {
    return UnitTest::RunAllTests();
  }

UnitTest++.h 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 UnitTest, so you need to either qualify their full names (as with RunAllTests() in the example) or add a using namespace UnitTest; statement in your .cpp files. Note that any mention of UnitTest++ functions and classes in this document assume that the UnitTest namespace has been opened.

Compiling and linking this program with UnitTest++'s static library into an executable, and running it, will produce the following output (details may vary):

  .\test.cpp(5): error: Failure in FailSpectacularly: false
  FAILED: 1 out of 1 tests failed (1 failures).
  Test time: 0.00 seconds.

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.

Test macros

To add a test, simply put the following code in a .cpp file of your choice:

  TEST(YourTestName)
  {
  }

The TEST 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 RunAllTests().

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 TEST_FIXTURE 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.

  struct SomeFixture
  {
    SomeFixture() { /* some setup */ }
    ~SomeFixture() { /* some teardown */ }

    int testData;
  };
 
  TEST_FIXTURE(SomeFixture, YourTestName)
  {
    int temp = testData;
  }

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.

Suite macros

Tests can be grouped into suites, using the SUITE macro. A suite serves as a namespace for test names, so that the same test name can be used in two difference contexts.

  SUITE(YourSuiteName)
  {
    TEST(YourTestName)
    {
    }

    TEST(YourOtherTestName)
    {
    }
  }

This will place the tests into a C++ namespace called YourSuiteName, and make the suite name available to UnitTest++. RunAllTests() can be called for a specific suite name, so you can use this to build named groups of tests to be run together.

Simple check macros

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.

The most basic variety is the boolean CHECK macro:

  CHECK(false); // fails

It will fail if the boolean expression evaluates to false.

For equality checks, it's generally better to use CHECK_EQUAL:

  CHECK_EQUAL(10, 20); // fails
  CHECK_EQUAL("foo", "bar"); // fails

Note how CHECK_EQUAL is overloaded for C strings, so you don't have to resort to strcmp or similar. There is no facility for case-insensitive comparison or string searches, so you may have to drop down to a plain boolean CHECK with help from the CRT:

  CHECK(std::strstr("zaza", "az") != 0); // succeeds

For floating-point comparison, equality isn't necessarily well-defined, so you should prefer the CHECK_CLOSE macro:

  CHECK_CLOSE(3.14, 3.1415, 0.01); // succeeds

All of the macros are tailored to avoid unintended side-effects, for example:

  TEST(CheckMacrosHaveNoSideEffects)
  {
    int i = 4;
    CHECK_EQUAL(5, ++i); // succeeds
    CHECK_EQUAL(5, i); // succeeds
  }

The check macros guarantee that the ++i expression isn't repeated internally, as demonstrated above.

Array check macros

There is a set of check macros for array comparison as well:

  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

The array equal macro compares elements using operator==, so CHECK_ARRAY_EQUAL won't work for an array of C strings, for example.

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.

Note that the one-dimensional array macros work for std::vector as well, as it can be indexed just as a C array.

Exception check macros

Finally, there's a CHECK_THROW macro, which asserts that its enclosed expression throws the specified type:

  struct TestException {};
  CHECK_THROW(throw TestException(), TestException); // succeeds

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 what() method for std::exception derivatives or just a plain message for unknown exception types.

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.

Time constraints

UnitTest++ can fail a test if it takes too long to complete, using so-called time constraints.

They come in two flavors; local and global time constraints.

Local time constraints are limited to the current scope, like so:

  TEST(YourTimedTest)
  {
     // Lengthy setup...

     {
        UNITTEST_TIME_CONSTRAINT(50);

        // Do time-critical stuff
     }

     // Lengthy teardown...
  }

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.

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 RunAllTests().

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 UNITTEST_TIME_CONSTRAINT_EXEMPT macro anywhere inside the test body.

  TEST(NotoriouslySlowTest)
  {
     UNITTEST_TIME_CONSTRAINT_EXEMPT();

     // Oh boy, this is going to take a while
     ...
  }

Test runners

The RunAllTests() 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.

  int RunAllTests(TestReporter& reporter, TestList const& list, char const* suiteName, int const maxTestTimeInMs);

If you attempt to pass custom parameters to RunAllTests(), note that the list parameter should have the value Test::GetTestList().

The parameterless RunAllTests() is a simple wrapper for this one, with sensible defaults.

Example setup

How to create a new test project varies depending on your environment, but here are some directions on common file structure and usage.

The general idea is that you keep one Main.cpp file with the entry-point which calls RunAllTests().

Then you can simply compile and link new .cpp files at will, typically one per test suite.

   + ShaverTests/
   |
   +- Main.cpp
   |
   +- TestBrush.cpp   
   +- TestEngine.cpp
   +- TestRazor.cpp   

Each of the Test*.cpp files will contain one or more TEST macro incantations with the associated test code. There are no source-level dependencies between Main.cpp and Test*.cpp, as the TEST macro handles the registration and setup necessary for RunAllTests() to find all tests compiled into the same final executable.

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 TESTs and calls RunAllTests() at one point or another, it will be handled by UnitTest++.

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.

ode-0.11.1/tests/UnitTest++/COPYING0000644000076400007640000000206510716133106013375 00000000000000Copyright (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. ode-0.11.1/tests/UnitTest++/Makefile.in0000644000076400007640000003523011206343412014405 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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++ DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ COPYING ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ode/src/config.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-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 uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ 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@ 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@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODE_PRECISION = @ODE_PRECISION@ ODE_RELEASE = @ODE_RELEASE@ 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_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ 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@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ 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'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign tests/UnitTest++/Makefile .PRECIOUS: 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 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. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; 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; \ (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" $(RECURSIVE_CLEAN_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ 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 || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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 \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-exec-am: install-html: install-html-recursive install-info: install-info-recursive install-man: install-pdf: install-pdf-recursive install-ps: install-ps-recursive 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: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ ctags ctags-recursive 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-recursive \ uninstall uninstall-am # 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: ode-0.11.1/tests/UnitTest++/Makefile.am0000644000076400007640000000010011022071001014344 00000000000000# Makefile.am for UnitTest++ SUBDIRS = src EXTRA_DIST = docs ode-0.11.1/tests/UnitTest++/src/0000777000076400007640000000000011206343457013221 500000000000000ode-0.11.1/tests/UnitTest++/src/XmlTestReporter.h0000644000076400007640000000171410716133106016425 00000000000000#ifndef UNITTEST_XMLTESTREPORTER_H #define UNITTEST_XMLTESTREPORTER_H #include "DeferredTestReporter.h" #include 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 ode-0.11.1/tests/UnitTest++/src/ReportAssert.cpp0000644000076400007640000000032010716133106016262 00000000000000#include "AssertException.h" namespace UnitTest { void ReportAssert(char const* description, char const* filename, int const lineNumber) { throw AssertException(description, filename, lineNumber); } } ode-0.11.1/tests/UnitTest++/src/TestDetails.cpp0000644000076400007640000000074410716133106016064 00000000000000#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_) { } } ode-0.11.1/tests/UnitTest++/src/TestReporterStdout.h0000644000076400007640000000102310716133106017140 00000000000000#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 ode-0.11.1/tests/UnitTest++/src/TestSuite.h0000644000076400007640000000026410716133106015232 00000000000000#ifndef UNITTEST_TESTSUITE_H #define UNITTEST_TESTSUITE_H namespace UnitTestSuite { inline char const* GetSuiteName () { return "DefaultSuite"; } } #endif ode-0.11.1/tests/UnitTest++/src/DeferredTestReporter.h0000644000076400007640000000120310716133106017376 00000000000000#ifndef UNITTEST_DEFERREDTESTREPORTER_H #define UNITTEST_DEFERREDTESTREPORTER_H #include "TestReporter.h" #include "DeferredTestResult.h" #include 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 ode-0.11.1/tests/UnitTest++/src/AssertException.h0000644000076400007640000000077310716133106016426 00000000000000#ifndef UNITTEST_ASSERTEXCEPTION_H #define UNITTEST_ASSERTEXCEPTION_H #include 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 ode-0.11.1/tests/UnitTest++/src/UnitTest++.h0000644000076400007640000000042710716133106015207 00000000000000#ifndef UNITTESTCPP_H #define UNITTESTCPP_H #include "Config.h" #include "Test.h" #include "TestList.h" #include "TestSuite.h" #include "TestResults.h" #include #include "TestMacros.h" #include "CheckMacros.h" #include "TestRunner.h" #include "TimeConstraint.h" #endif ode-0.11.1/tests/UnitTest++/src/TimeConstraint.h0000644000076400007640000000134310716133106016243 00000000000000#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 ode-0.11.1/tests/UnitTest++/src/DeferredTestResult.h0000644000076400007640000000104310716133106017054 00000000000000#ifndef UNITTEST_DEFERREDTESTRESULT_H #define UNITTEST_DEFERREDTESTRESULT_H #include #include 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 ode-0.11.1/tests/UnitTest++/src/Win32/0000777000076400007640000000000011206343457014123 500000000000000ode-0.11.1/tests/UnitTest++/src/Win32/TimeHelpers.cpp0000644000076400007640000000175310716133106016763 00000000000000#include "TimeHelpers.h" #include 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); } } ode-0.11.1/tests/UnitTest++/src/Win32/Makefile.in0000644000076400007640000003375511206343412016110 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ode/src/config.h CONFIG_CLEAN_FILES = libhelper_la_LIBADD = am_libhelper_la_OBJECTS = TimeHelpers.lo libhelper_la_OBJECTS = $(am_libhelper_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libhelper_la_SOURCES) DIST_SOURCES = $(libhelper_la_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ 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@ 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@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODE_PRECISION = @ODE_PRECISION@ ODE_RELEASE = @ODE_RELEASE@ 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_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ 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@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ 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'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign tests/UnitTest++/src/Win32/Makefile .PRECIOUS: 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 clean-checkLTLIBRARIES: -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES) @list='$(check_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libhelper.la: $(libhelper_la_OBJECTS) $(libhelper_la_DEPENDENCIES) $(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@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-am info-am: install-data-am: install-dvi: install-dvi-am 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 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 all all-am check check-am clean \ clean-checkLTLIBRARIES clean-generic clean-libtool ctags \ 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 uninstall uninstall-am # 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: ode-0.11.1/tests/UnitTest++/src/Win32/Makefile.am0000644000076400007640000000013011022071001016040 00000000000000check_LTLIBRARIES = libhelper.la libhelper_la_SOURCES = TimeHelpers.cpp TimeHelpers.h ode-0.11.1/tests/UnitTest++/src/Win32/TimeHelpers.h0000644000076400007640000000110310716133106016415 00000000000000#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 ode-0.11.1/tests/UnitTest++/src/CheckMacros.h0000644000076400007640000000660510716133106015470 00000000000000#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 ode-0.11.1/tests/UnitTest++/src/TestResults.cpp0000644000076400007640000000224110716133106016132 00000000000000#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; } } ode-0.11.1/tests/UnitTest++/src/AssertException.cpp0000644000076400007640000000107110716133106016751 00000000000000#include "AssertException.h" #include 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; } } ode-0.11.1/tests/UnitTest++/src/MemoryOutStream.h0000644000076400007640000000230210716133106016410 00000000000000#ifndef UNITTEST_MEMORYOUTSTREAM_H #define UNITTEST_MEMORYOUTSTREAM_H #include "Config.h" #ifndef UNITTEST_USE_CUSTOM_STREAMS #include 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 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 ode-0.11.1/tests/UnitTest++/src/TestReporterStdout.cpp0000644000076400007640000000210710716133106017477 00000000000000#include "TestReporterStdout.h" #include #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); } } ode-0.11.1/tests/UnitTest++/src/MemoryOutStream.cpp0000644000076400007640000000503210716133106016746 00000000000000#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 #include namespace UnitTest { namespace { template 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 ode-0.11.1/tests/UnitTest++/src/TestList.h0000644000076400007640000000051210716133106015050 00000000000000#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 ode-0.11.1/tests/UnitTest++/src/TestResults.h0000644000076400007640000000136110716133106015601 00000000000000#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 ode-0.11.1/tests/UnitTest++/src/Makefile.in0000644000076400007640000005140411206343412015175 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ode/src/config.h CONFIG_CLEAN_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) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libunittestpp_la_SOURCES) DIST_SOURCES = $(libunittestpp_la_SOURCES) RECURSIVE_TARGETS = all-recursive check-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 uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = Posix Win32 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ 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@ 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@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODE_PRECISION = @ODE_PRECISION@ ODE_RELEASE = @ODE_RELEASE@ 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_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ 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@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ 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'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign tests/UnitTest++/src/Makefile .PRECIOUS: 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 clean-checkLTLIBRARIES: -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES) @list='$(check_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libunittestpp.la: $(libunittestpp_la_OBJECTS) $(libunittestpp_la_DEPENDENCIES) $(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@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(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. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; 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; \ (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" $(RECURSIVE_CLEAN_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ 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 || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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 \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-exec-am: install-html: install-html-recursive install-info: install-info-recursive install-man: install-pdf: install-pdf-recursive install-ps: install-ps-recursive 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: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-checkLTLIBRARIES \ clean-generic clean-libtool ctags ctags-recursive 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-recursive \ uninstall uninstall-am # 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: ode-0.11.1/tests/UnitTest++/src/Checks.h0000644000076400007640000001101410716133106014474 00000000000000#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 ode-0.11.1/tests/UnitTest++/src/DeferredTestReporter.cpp0000644000076400007640000000145710716133106017744 00000000000000#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; } ode-0.11.1/tests/UnitTest++/src/Config.h0000644000076400007640000000152310716133106014505 00000000000000#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 ode-0.11.1/tests/UnitTest++/src/DeferredTestResult.cpp0000644000076400007640000000060510716133106017412 00000000000000#include "DeferredTestResult.h" #include 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) { } } ode-0.11.1/tests/UnitTest++/src/TestMacros.h0000644000076400007640000001176010716133106015370 00000000000000#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 ode-0.11.1/tests/UnitTest++/src/Test.cpp0000644000076400007640000000233410716133106014553 00000000000000#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 { } } ode-0.11.1/tests/UnitTest++/src/TestRunner.h0000644000076400007640000000041010716133106015403 00000000000000#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 ode-0.11.1/tests/UnitTest++/src/Posix/0000777000076400007640000000000011206343457014323 500000000000000ode-0.11.1/tests/UnitTest++/src/Posix/SignalTranslator.h0000644000076400007640000000162310716133106017672 00000000000000#ifndef UNITTEST_SIGNALTRANSLATOR_H #define UNITTEST_SIGNALTRANSLATOR_H #include #include 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 ode-0.11.1/tests/UnitTest++/src/Posix/TimeHelpers.cpp0000644000076400007640000000102710716133106017155 00000000000000#include "TimeHelpers.h" #include 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); } } ode-0.11.1/tests/UnitTest++/src/Posix/Makefile.in0000644000076400007640000003422511206343412016301 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ode/src/config.h CONFIG_CLEAN_FILES = libhelper_la_LIBADD = am_libhelper_la_OBJECTS = SignalTranslator.lo TimeHelpers.lo libhelper_la_OBJECTS = $(am_libhelper_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libhelper_la_SOURCES) DIST_SOURCES = $(libhelper_la_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ 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@ 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@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODE_PRECISION = @ODE_PRECISION@ ODE_RELEASE = @ODE_RELEASE@ 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_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ 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@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ 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'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign tests/UnitTest++/src/Posix/Makefile .PRECIOUS: 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 clean-checkLTLIBRARIES: -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES) @list='$(check_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libhelper.la: $(libhelper_la_OBJECTS) $(libhelper_la_DEPENDENCIES) $(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@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-am info-am: install-data-am: install-dvi: install-dvi-am 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 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 all all-am check check-am clean \ clean-checkLTLIBRARIES clean-generic clean-libtool ctags \ 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 uninstall uninstall-am # 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: ode-0.11.1/tests/UnitTest++/src/Posix/SignalTranslator.cpp0000644000076400007640000000210410716133106020220 00000000000000#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; } } ode-0.11.1/tests/UnitTest++/src/Posix/Makefile.am0000644000076400007640000000023211022071001016243 00000000000000check_LTLIBRARIES = libhelper.la libhelper_la_SOURCES = SignalTranslator.cpp SignalTranslator.h \ TimeHelpers.cpp TimeHelpers.h ode-0.11.1/tests/UnitTest++/src/Posix/TimeHelpers.h0000644000076400007640000000046210716133106016624 00000000000000#ifndef UNITTEST_TIMEHELPERS_H #define UNITTEST_TIMEHELPERS_H #include namespace UnitTest { class Timer { public: Timer(); void Start(); int GetTimeInMs() const; private: struct timeval m_startTime; }; namespace TimeHelpers { void SleepMs (int ms); } } #endif ode-0.11.1/tests/UnitTest++/src/TimeConstraint.cpp0000644000076400007640000000122510716133106016575 00000000000000#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()); } } } ode-0.11.1/tests/UnitTest++/src/Checks.cpp0000644000076400007640000000222610716133106015034 00000000000000#include "Checks.h" #include 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); } } ode-0.11.1/tests/UnitTest++/src/TestReporter.h0000644000076400007640000000101710716133106015740 00000000000000#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 ode-0.11.1/tests/UnitTest++/src/Makefile.am0000644000076400007640000000275011022071001015150 00000000000000if 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 ode-0.11.1/tests/UnitTest++/src/TimeHelpers.h0000644000076400007640000000020310716133106015513 00000000000000#include "Config.h" #if defined UNITTEST_POSIX #include "Posix/TimeHelpers.h" #else #include "Win32/TimeHelpers.h" #endif ode-0.11.1/tests/UnitTest++/src/ReportAssert.h0000644000076400007640000000025410716133106015735 00000000000000#ifndef UNITTEST_ASSERT_H #define UNITTEST_ASSERT_H namespace UnitTest { void ReportAssert(char const* description, char const* filename, int lineNumber); } #endif ode-0.11.1/tests/UnitTest++/src/TestReporter.cpp0000644000076400007640000000012710716133106016274 00000000000000#include "TestReporter.h" namespace UnitTest { TestReporter::~TestReporter() { } } ode-0.11.1/tests/UnitTest++/src/Test.h0000644000076400007640000000114310716133106014215 00000000000000#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 ode-0.11.1/tests/UnitTest++/src/XmlTestReporter.cpp0000644000076400007640000000635310716133106016764 00000000000000#include "XmlTestReporter.h" #include #include #include 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 << ""; } void XmlTestReporter::BeginResults(std::ostream& os, int const totalTestCount, int const failedTestCount, int const failureCount, float const secondsElapsed) { os << ""; } void XmlTestReporter::EndResults(std::ostream& os) { os << ""; } void XmlTestReporter::BeginTest(std::ostream& os, DeferredTestResult const& result) { os << ""; else os << "/>"; } void XmlTestReporter::AddFailure(std::ostream& os, DeferredTestResult const& result) { os << ">"; // close 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 << ""; } } } ode-0.11.1/tests/UnitTest++/src/TestDetails.h0000644000076400007640000000107610716133106015530 00000000000000#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 ode-0.11.1/tests/UnitTest++/src/TestList.cpp0000644000076400007640000000076110716133106015411 00000000000000#include "TestList.h" #include "Test.h" #include 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); } } ode-0.11.1/tests/UnitTest++/src/TestRunner.cpp0000644000076400007640000000327010716133106015745 00000000000000#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 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); } } ode-0.11.1/tests/UnitTest++/README0000644000076400007640000000375310716133106013227 00000000000000UnitTest++ 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 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 ode-0.11.1/tests/joints/0000777000076400007640000000000011206343457012033 500000000000000ode-0.11.1/tests/joints/universal.cpp0000644000076400007640000020246611140354507014470 00000000000000/************************************************************************* * * * 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 #include #include #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; dCROSS(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[0], anchorOrig1[0] , 1e-4); CHECK_CLOSE (anchor1[0], anchorOrig1[0] , 1e-4); CHECK_CLOSE (anchor2[0], anchorOrig2[0] , 1e-4); CHECK_CLOSE (anchor2[0], anchorOrig2[0] , 1e-4); CHECK_CLOSE (anchor2[0], anchorOrig2[0] , 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; dCROSS(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 ode-0.11.1/tests/joints/piston.cpp0000644000076400007640000013254711111057332013770 00000000000000/************************************************************************* * * * 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 #include #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 dJointSetPistonAxisDelta (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_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); dJointSetPistonAxisDelta (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_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 ode-0.11.1/tests/joints/ball.cpp0000644000076400007640000001243411143213260013355 00000000000000/************************************************************************* * * * 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 #include #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 ode-0.11.1/tests/joints/pu.cpp0000644000076400007640000007034211111307357013077 00000000000000/************************************************************************* * * * 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 #include #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 ode-0.11.1/tests/joints/slider.cpp0000644000076400007640000012124611111057332013730 00000000000000 /************************************************************************* * * * 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 #include #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 ode-0.11.1/tests/joints/pr.cpp0000644000076400007640000010524511111066476013101 00000000000000/************************************************************************* * * * 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 #include #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 ode-0.11.1/tests/joints/fixed.cpp0000644000076400007640000001267011075411332013550 00000000000000/************************************************************************* * * * 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 #include #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 ode-0.11.1/tests/joints/hinge2.cpp0000644000076400007640000001302611140354507013624 00000000000000/************************************************************************* * * * 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 #include #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 axis; dJointGetHinge2Axis1(jId[1], axis); dJointSetHinge2Axis1(jId[1], axis[0], axis[1], axis[2]); dJointGetHinge2Axis2(jId[1], axis); dJointSetHinge2Axis2(jId[1], axis[0], axis[1], axis[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 TestdxJointHinge2 ode-0.11.1/tests/joints/hinge.cpp0000644000076400007640000005635211140354507013553 00000000000000/************************************************************************* * * * 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 #include #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); } } } // End of SUITE TestdxJointHinge ode-0.11.1/install-sh0000755000076400007640000003246411206343422011304 00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2006-12-25.00 # 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. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # 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_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' 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 no_target_directory= 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 *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done 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 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 trap '(exit $?); exit' 1 2 13 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 starting with `-'. 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 # Protect names starting with `-'. case $dst in -*) dst=./$dst;; esac # 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 -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` 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-writeable 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 eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test -z "$d" && 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` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob 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-end: "$" # End: ode-0.11.1/drawstuff/0000777000076400007640000000000011206343456011367 500000000000000ode-0.11.1/drawstuff/dstest/0000777000076400007640000000000011206343456012675 500000000000000ode-0.11.1/drawstuff/dstest/dstest.cpp0000644000076400007640000000715507506200314014624 00000000000000/************************************************************************* * * * 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 #include #include #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; } ode-0.11.1/drawstuff/dstest/Makefile.in0000644000076400007640000003375111206343412014657 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 @X11_TRUE@am__append_2 = $(X_PRE_LIBS) $(X_LIBS) $(X_EXTRA_LIBS) subdir = drawstuff/dstest DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ode/src/config.h CONFIG_CLEAN_FILES = PROGRAMS = $(noinst_PROGRAMS) am_dstest_OBJECTS = dstest.$(OBJEXT) dstest_OBJECTS = $(am_dstest_OBJECTS) am__DEPENDENCIES_1 = @X11_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) \ @X11_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) dstest_DEPENDENCIES = $(top_builddir)/drawstuff/src/libdrawstuff.la \ $(am__append_1) $(am__DEPENDENCIES_2) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(dstest_SOURCES) DIST_SOURCES = $(dstest_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ 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@ 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@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODE_PRECISION = @ODE_PRECISION@ ODE_RELEASE = @ODE_RELEASE@ 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_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ 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@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ 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) $(am__append_2) 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'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign drawstuff/dstest/Makefile .PRECIOUS: 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 clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; for p in $$list; do \ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ echo " rm -f $$p $$f"; \ rm -f $$p $$f ; \ done dstest$(EXEEXT): $(dstest_OBJECTS) $(dstest_DEPENDENCIES) @rm -f dstest$(EXEEXT) $(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@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-am info-am: install-data-am: install-dvi: install-dvi-am 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 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 all all-am check check-am clean clean-generic \ clean-libtool clean-noinstPROGRAMS ctags 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 uninstall uninstall-am @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: ode-0.11.1/drawstuff/dstest/Makefile.am0000644000076400007640000000073411021347356014647 00000000000000noinst_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 if X11 dstest_LDADD+=$(X_PRE_LIBS) $(X_LIBS) $(X_EXTRA_LIBS) endif ode-0.11.1/drawstuff/Makefile.in0000644000076400007640000003521411206343412013345 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ode/src/config.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-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 uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = src dstest DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ 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@ 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@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODE_PRECISION = @ODE_PRECISION@ ODE_RELEASE = @ODE_RELEASE@ 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_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ 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@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ 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'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign drawstuff/Makefile .PRECIOUS: 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 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. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; 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; \ (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" $(RECURSIVE_CLEAN_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ 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 || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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 \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-exec-am: install-html: install-html-recursive install-info: install-info-recursive install-man: install-pdf: install-pdf-recursive install-ps: install-ps-recursive 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: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ ctags ctags-recursive 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-recursive \ uninstall uninstall-am # 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: ode-0.11.1/drawstuff/Makefile.am0000644000076400007640000000010511031007470013320 00000000000000if ENABLE_DRAWSTUFF SUBDIRS = src dstest EXTRA_DIST = textures endif ode-0.11.1/drawstuff/src/0000777000076400007640000000000011206343456012156 500000000000000ode-0.11.1/drawstuff/src/x11.cpp0000644000076400007640000002727611061304326013215 00000000000000/************************************************************************* * * * 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 #include "config.h" #include #include #include #include #include #include #include #ifdef HAVE_SYS_TIME_H #include #endif #include #include #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); exit (1); } extern "C" void dsDebug (const char *msg, ...) { va_list ap; va_start (ap,msg); printMessage ("INTERNAL ERROR",msg,ap); // *((char *)0) = 0; ... commit SEGVicide ? abort(); } extern "C" void dsPrint (const char *msg, ...) { va_list ap; va_start (ap,msg); vprintf (msg,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 pause=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': pause ^= 1; singlestep = 0; break; case 'o': case 'O': if (pause) 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; yred_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 dsPlatformSimLoop (int window_width, int window_height, dsFunctions *fn, int initial_pause) { pause = 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(); 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); } dsDrawFrame (width,height,fn,pause && !singlestep); singlestep = 0; glFlush(); glXSwapBuffers (display,win); XSync (display,0); // capture frames if necessary if (pause==0 && writeframes) { captureFrame (frame); frame++; } }; 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 Inform an alternative textures path TODO ---- manage openGL state changes better */ #ifdef WIN32 #include #endif #include #include "config.h" #ifdef HAVE_APPLE_OPENGL_FRAMEWORK #include #include #else #include #include #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; } } //*************************************************************************** // 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 (float *_planes,unsigned int _planecount, float *_points, unsigned int _pointcount, 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 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]; dCROSS (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] ); dCROSS (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; ipath_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], float *_planes,unsigned int _planecount, float *_points, unsigned int _pointcount, 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 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); } } void dsDrawLine (const float pos1[3], const float pos2[3]) { setupDrawingMode(); glColor3f (color[0],color[1],color[2]); 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(); } 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], double *_planes,unsigned int _planecount, double *_points, unsigned int _pointcount, 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(); } 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; } } ode-0.11.1/drawstuff/src/Makefile.in0000644000076400007640000003636711206343412014146 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ode/src/config.h CONFIG_CLEAN_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) libdrawstuff_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(libdrawstuff_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libdrawstuff_la_SOURCES) DIST_SOURCES = $(am__libdrawstuff_la_SOURCES_DIST) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ 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@ 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@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODE_PRECISION = @ODE_PRECISION@ ODE_RELEASE = @ODE_RELEASE@ 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_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ 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@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ 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 \ -DDEFAULT_PATH_TO_TEXTURES='"$(top_srcdir)/drawstuff/textures/"' \ $(X_CFLAGS) @WIN32_TRUE@libdrawstuff_la_LIBADD = -lwinmm -lgdi32 @X11_TRUE@libdrawstuff_la_LIBADD = $(X_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'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign drawstuff/src/Makefile .PRECIOUS: 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 clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libdrawstuff.la: $(libdrawstuff_la_OBJECTS) $(libdrawstuff_la_DEPENDENCIES) $(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@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-am info-am: install-data-am: install-dvi: install-dvi-am 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 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 all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES ctags 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 uninstall uninstall-am # 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: ode-0.11.1/drawstuff/src/windows.cpp0000644000076400007640000003646511206274560014305 00000000000000/************************************************************************* * * * 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 #endif #include #include "config.h" #include #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); } extern "C" void dsError (const char *msg, ...) { va_list ap; va_start (ap,msg); errorBox ("Error",msg,ap); exit (1); } extern "C" void dsDebug (const char *msg, ...) { va_list ap; va_start (ap,msg); errorBox ("INTERNAL ERROR",msg,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); } //*************************************************************************** // 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 DWORD WINAPI 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; DWORD threadId, thirdParam = 0; HANDLE hThread; hThread = CreateThread( NULL, // no security attributes 0, // use default stack size renderingThread, // thread function &thirdParam, // 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 #include "config.h" #include #include #include #ifdef HAVE_SYS_TIME_H #include #endif #include #include #include "internal.h" #include #include // Global variables static bool running = true; // 1 if simulation running 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 UInt32 modifierMask = 0; 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 WindowRef windowReference; static AGLContext aglContext; static EventHandlerUPP mouseUPP = NULL; static EventHandlerUPP keyboardUPP = NULL; static EventHandlerUPP windowUPP = NULL; // Describes the window-events we are interested in EventTypeSpec OSX_WINDOW_EVENT_TYPES[] = { { kEventClassWindow, kEventWindowBoundsChanged }, { kEventClassWindow, kEventWindowClose }, { kEventClassWindow, kEventWindowDrawContent } }; // Describes the mouse-events we are interested in EventTypeSpec OSX_MOUSE_EVENT_TYPES[] = { { kEventClassMouse, kEventMouseDown }, { kEventClassMouse, kEventMouseUp }, { kEventClassMouse, kEventMouseMoved }, { kEventClassMouse, kEventMouseDragged } }; // Describes the key-events we are interested in EventTypeSpec OSX_KEY_EVENT_TYPES[] = { { kEventClassKeyboard, kEventRawKeyDown }, // { kEventClassKeyboard, kEventRawKeyUp }, { kEventClassKeyboard, kEventRawKeyModifiersChanged } }; //*************************************************************************** // 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); exit (1); } extern "C" void dsDebug (const char *msg, ...) { va_list ap; va_start (ap,msg); printMessage ("INTERNAL ERROR",msg,ap); // *((char *)0) = 0; ... commit SEGVicide ? abort(); } extern "C" void dsPrint (const char *msg, ...) { va_list ap; va_start (ap,msg); vprintf (msg,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(){ running = false; } 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= ' ' && charCode <= 126 && functions -> command ){ functions -> command( charCode ); } } else if( ( modifierMask & controlKey ) ){ // ctrl+key was pressed switch(uppercase ){ case 'T': dsSetTextures( !dsGetTextures() ); break; case 'S': dsSetShadows( !dsGetShadows() ); break; case 'X': running = false; 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; } } return noErr; case kEventRawKeyModifiersChanged: if( GetEventParameter( event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof( UInt32 ), NULL, &modifierMask ) == noErr ){ if( ( mouseWithOption && !( modifierMask & optionKey ) ) || ( mouseWithControl && !( modifierMask & controlKey ) ) ){ // The mouse was being dragged using either the command-key or the option-key modifier to emulate // the right button or both left + right. // Now the modifier-key has been released so the mouseButtonMode must be changed accordingly // The following releases the right-button. mouseButtonMode &= (~4); mouseWithOption = false; mouseWithControl = false; } return noErr; } break; } return eventNotHandledErr; } OSStatus osxMouseEventHandler( EventHandlerCallRef handlerCallRef, EventRef event, void *userData ){ bool buttonDown = false; HIPoint mouseLocation; switch( GetEventKind( event ) ){ case kEventMouseDown: buttonDown = true; case kEventMouseUp: if( GetEventParameter( event, kEventParamWindowMouseLocation, typeHIPoint, NULL, sizeof( HIPoint ), NULL, &mouseLocation ) != noErr ){ break; } EventMouseButton button; if( GetEventParameter( event, kEventParamMouseButton, typeMouseButton, NULL, sizeof( EventMouseButton ), NULL, &button ) == noErr ){ if( button == kEventMouseButtonPrimary ){ if( modifierMask & controlKey ){ // Ctrl+button == right button = kEventMouseButtonSecondary; mouseWithControl = true; } else if( modifierMask & optionKey ){ // Alt+button == left+right mouseButtonMode = 5; mouseWithOption = true; return noErr; } } if( buttonDown ){ if( button == kEventMouseButtonPrimary ) mouseButtonMode |= 1; // Left if( button == kEventMouseButtonTertiary ) mouseButtonMode |= 2; // Middle if( button == kEventMouseButtonSecondary ) mouseButtonMode |= 4; // Right } else{ if( button == kEventMouseButtonPrimary ) mouseButtonMode &= (~1); // Left if( button == kEventMouseButtonTertiary ) mouseButtonMode &= (~2); // Middle if( button == kEventMouseButtonSecondary ) mouseButtonMode &= (~4);// Right } return noErr; } break; case kEventMouseMoved: // NO-OP return noErr; case kEventMouseDragged: // Carbon provides mouse-position deltas, so we don't have to store the old state ourselves if( GetEventParameter( event, kEventParamMouseDelta, typeHIPoint, NULL, sizeof( HIPoint ), NULL, &mouseLocation ) == noErr ){ //printf( "Mode %d\n", mouseButtonMode ); dsMotion( mouseButtonMode, (int)mouseLocation.x, (int)mouseLocation.y ); return noErr; } break; case kEventMouseWheelMoved: // NO-OP break; } return eventNotHandledErr; } static void osxCloseMainWindow(){ if( windowUPP != NULL ){ DisposeEventHandlerUPP( windowUPP ); windowUPP = NULL; } if( aglContext != NULL ){ aglSetCurrentContext( NULL ); aglSetDrawable( aglContext, NULL ); aglDestroyContext( aglContext ); aglContext = NULL; } if( windowReference != NULL ){ ReleaseWindow( windowReference ); windowReference = NULL; } } OSStatus osxWindowEventHandler( EventHandlerCallRef handlerCallRef, EventRef event, void *userData ){ //printf( "WindowEvent\n" ); switch( GetEventKind(event) ){ case kEventWindowBoundsChanged: WindowRef window; GetEventParameter( event, kEventParamDirectObject, typeWindowRef, NULL, sizeof(WindowRef), NULL, &window ); Rect rect; GetWindowPortBounds( window, &rect ); windowWidth = rect.right; windowHeight = rect.bottom; aglUpdateContext( aglContext ); break; case kEventWindowClose: osxCloseMainWindow(); exit( 0 ); return noErr; case kEventWindowDrawContent: // NO-OP break; } return eventNotHandledErr; } static void osxCreateMainWindow( int width, int height ){ int redbits = 4; int greenbits = 4; int bluebits = 4; int alphabits = 4; int depthbits = 16; OSStatus error; // create pixel format attribute list GLint pixelFormatAttributes[256]; int numAttrs = 0; pixelFormatAttributes[numAttrs++] = AGL_RGBA; pixelFormatAttributes[numAttrs++] = AGL_DOUBLEBUFFER; pixelFormatAttributes[numAttrs++] = AGL_RED_SIZE; pixelFormatAttributes[numAttrs++] = redbits; pixelFormatAttributes[numAttrs++] = AGL_GREEN_SIZE; pixelFormatAttributes[numAttrs++] = greenbits; pixelFormatAttributes[numAttrs++] = AGL_BLUE_SIZE; pixelFormatAttributes[numAttrs++] = bluebits; pixelFormatAttributes[numAttrs++] = AGL_ALPHA_SIZE; pixelFormatAttributes[numAttrs++] = alphabits; pixelFormatAttributes[numAttrs++] = AGL_DEPTH_SIZE; pixelFormatAttributes[numAttrs++] = depthbits; pixelFormatAttributes[numAttrs++] = AGL_NONE; // create pixel format. AGLDevice mainMonitor = GetMainDevice(); AGLPixelFormat pixelFormat = aglChoosePixelFormat( &mainMonitor, 1, pixelFormatAttributes ); if( pixelFormat == NULL ){ return; } aglContext = aglCreateContext( pixelFormat, NULL ); aglDestroyPixelFormat( pixelFormat ); if( aglContext == NULL ){ osxCloseMainWindow(); return; } Rect windowContentBounds; windowContentBounds.left = 0; windowContentBounds.top = 0; windowContentBounds.right = width; windowContentBounds.bottom = height; int windowAttributes = kWindowCloseBoxAttribute | kWindowFullZoomAttribute | kWindowCollapseBoxAttribute | kWindowResizableAttribute | kWindowStandardHandlerAttribute | kWindowLiveResizeAttribute; error = CreateNewWindow( kDocumentWindowClass, windowAttributes, &windowContentBounds, &windowReference ); if( ( error != noErr ) || ( windowReference == NULL ) ){ osxCloseMainWindow(); return; } windowUPP = NewEventHandlerUPP( osxWindowEventHandler ); error = InstallWindowEventHandler( windowReference, windowUPP,GetEventTypeCount( OSX_WINDOW_EVENT_TYPES ), OSX_WINDOW_EVENT_TYPES, NULL, NULL ); if( error != noErr ){ osxCloseMainWindow(); return; } // The process-type must be changed for a ForegroundApplication // Unless it is a foreground-process, the application will not show in the dock or expose and the window // will not behave properly. ProcessSerialNumber currentProcess; GetCurrentProcess( ¤tProcess ); TransformProcessType( ¤tProcess, kProcessTransformToForegroundApplication ); SetFrontProcess( ¤tProcess ); SetWindowTitleWithCFString( windowReference, CFSTR( "ODE - Drawstuff" ) ); RepositionWindow( windowReference, NULL, kWindowCenterOnMainScreen ); ShowWindow( windowReference ); if( !aglSetDrawable( aglContext, GetWindowPort( windowReference ) ) ){ osxCloseMainWindow(); return; } if( !aglSetCurrentContext( aglContext ) ){ osxCloseMainWindow(); } windowWidth = width; windowHeight = height; } int osxInstallEventHandlers(){ OSStatus error; mouseUPP = NewEventHandlerUPP( osxMouseEventHandler ); error = InstallEventHandler( GetApplicationEventTarget(), mouseUPP, GetEventTypeCount( OSX_MOUSE_EVENT_TYPES ), OSX_MOUSE_EVENT_TYPES, NULL, NULL ); if( error != noErr ){ return GL_FALSE; } keyboardUPP = NewEventHandlerUPP( osxKeyEventHandler ); error = InstallEventHandler( GetApplicationEventTarget(), keyboardUPP, GetEventTypeCount( OSX_KEY_EVENT_TYPES ), OSX_KEY_EVENT_TYPES, NULL, NULL ); if( error != noErr ){ return GL_FALSE; } 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(); int frame = 1; running = true; while( running ){ // read in and process all pending events for the main window EventRef event; EventTargetRef eventDispatcher = GetEventDispatcherTarget(); while( ReceiveNextEvent( 0, NULL, 0.0, TRUE, &event ) == noErr ){ SendEventToEventTarget( event, eventDispatcher ); ReleaseEvent( event ); } dsDrawFrame( windowWidth, windowHeight, fn, paused && !singlestep ); singlestep = false; glFlush(); aglSwapBuffers( aglContext ); // capture frames if necessary if( !paused && writeframes ){ captureFrame( frame ); frame++; } } if( fn->stop ) fn->stop(); dsStopGraphics(); osxCloseMainWindow(); } ode-0.11.1/drawstuff/textures/0000777000076400007640000000000011206343337013250 500000000000000ode-0.11.1/drawstuff/textures/ground.ppm0000644000076400007640000060005307251560070015204 00000000000000P6 # Created by Paint Shop Pro 256 256 255 mttv{}{{tdc\}dc\}||UTSu{{bVU{{t|lritt{zllf]cSKJ|{ttlekzll|z[[Ttsl|uztlri||u||}}mttttslks}|leklld|z|zSKJ]bZ}ttsddc{tt[TTult{tttllv{tll}cbVdc\lrijcVsre[TTsleSKJj]\\[[:97*)(ztlJHFlddJHFVTLbVUVTLddcb[Ulrib[Uultmttlldllklld|dc\|zmtttsl||uttsddc{{tmtt\UZlj||}ttslldkd\lddult|z|zu{{ek]|lri|zztltsltslztl[[T{u{]bZldd]cddc\mttUMRldd}VZTSKJD;9mttlld\[[JHFUTSJHF[TT||tzlmtt|lksddc|{{}|}||}||{{{{{{}ÙÜttsllk{{t{||||{||}mttd\\tllultVTL|cbV{tt}{ttultr]gultf]cbVU}}tlltlllekztl{{t{ttmttult{u{tllult}{||{{ldd{{]cd}{{|u{{{{lksUUYldddc\}{{tult}sre{zmttsj]\VTLSKJrg]iWUv{ekd:97$kd\uztultultlddbVUVTLSKJkk]}}ztlVTLtzl{||lld|uttstsltsldc\tzlsle|u{{ekdtyglri{||]cd{u{tzlv{ztl{{t|zv{|u||VTLddcb[UbVZ|z[TT[[Tlri{tt{u{rfklldttsd\\ult{tti\Vredtzlllk{{iq]{ttdc\ekddc\ztltzl]cdJHFjcVLKR}uzt{{mttd\\\[[||zuztnvmttlks{{}^^qmttddc{{nv}||lks}ylnvnv}{{edk{{f]c|z|u|{{t||}{||JHF|{{ultred}|z{||}zll|z}jcVtll}w{||}ttsmttu{{tt{ttsu{{VTLlrimtt\[[|zlrilldmtttt{lks|tsl|\[bf]clkslri|||lks}dc\ult}{u{ttsu{{ddc|UUY}]bZtslddcslesrev{lddslecbVSKJ{{tdc\kd\tzltsl||v|j]\[[T:97:97cbVlrid\\tlltllldd[[T|zcbV}}{||lkscbV}tzl{u{{tt}ekd{{tek]f]c{u{ddctll{u{lek}tlldc\{tt{||{||ultv|ultult]bZ{||tzledk]cdfkktllsle[[T\[[ttslriekdmtt|tsllri\[[b[U{{tuzt[[Tddc[[T|z{{d\\UTSult{tt{{tyllkstt{ult||{{{{{{|{{t{{lks{{|nv{{|fkk{{}|^fslkslksnv}|nv}ǻǪekduztutlld}{{ddcedkddclritsl{{lek|ulddztlred|u]bZtslSKJf]c}[[Tv|||{{}}ultf]c[TTlddd\\||\[b[TTUMRult|||lld|lksd\\{tttt{{||||{u{rfktt{||uztf]clddrfk{{tsletll|urfkzllb[Ukk]ztlztldc\cbV|z{{tbVZ[TTSKJutllkLKR*)(rg]llklekult{u{VTLVTLllk|uztVTLVTLedk|z{{ttsl|z|zddcddcekdVTLlrif]culttsl}{{ztl{{ttsl||sle]cdtll{{t{{tult}|z{{tult{||mttVZ[JHF]bZ|lksv{f]cekdtt{tll[[T}||{{{u{{{t]bZ{tt|uttslld]bZ\[bSKJlksd\\tll{{ttsu{{tslu{{{{mttek]}|{{u{{mtt|ttsmttylnv^^q\[b\[bnvtt{~u{{}\[bnvnn{{t{||}utultlekddc{{tsl{{tleklks{tt|}|}bVZultlksedktsl{{tlks|llkdc\ttsfkk|z|zuztuztztllld{ttu{{|z|tt{uzt{u{dc\{u{|lldtt{v{||j]\ut{{trg]PF=]bZ[TTlri{{t{{tddcSKJbVUlldUTSJHF*)(d\\}{ttlddlldsref]cf]clritslslellku{{ekdlrilrimttlks{zm|zaWMlek|red\[[dc\ttsUTS~tslkk]ult{{t|ultd\\|uultf]cLKR:97MRKllk{||{{ttzllri\[[llktslu{{|[[Tztlu{{[[Tlrirfk\[[VTLmtt{||v}{{t|uzt]cd|tt{fkk{{|{{{{|~||ttsnv}}{{nvlks{{}|}nvmk}{{tttsllk{{}ult{{lks|\UZtts|f]cred|zuzttts{{tJHF||lddldd{ttultSKJVZT{u{uzt{{|u}|zuzt}|v{|tt{edk|lks{{mtt]cd|{{tt{tll{{tmtt}lldrfk}}ultrfkztl}ztf{zmd\\|zdc\dc\]bZ}aWMtt{\UZFD;?;C?;Credlldj]\f]ctlllld{{llkekd||j]\ultlektt{\[[lddtygek]ult\UZ]bZ||lridc\{ttult}{u{rfklri|ult{||||tsl|u|{{tdc\cbVMRK*)(UTSlldmttddcekdllkttsllk{u{]bZ\[[|u}|ddcleklld}kjVSKJUMR}tts||lks{{u{{mtt~}}|^^q}ntt{{{|zu{{|{||||zllktt{|lksvttsllk||redsre{{t{zmuztlddlldsle\UZttstts|{u{{{{{tuzt{tt|rg]kk]|{{t||u{{fkkmtt|JHFv{tzli\VtslbVUv{rfkr]gyleSKJtsl\[[leklld|JHFztfb[U]bZ[[TUUY:97lldsleuztrfkr]gekdVTLj]\d\\\[bdc\|u||{u{{||tsl|v[TTkk]lri|u|zu{{{tttsl{tt{||ultsle{u{\[[||{||ekdbVUlldtts{ttJHF:97owVTLuzttzl|lldrg]j]\usreJHFlrillkrg]dc\}ddc|z]bZ|mttSKJmwf]cf]clkslks|z|ult{{{{{||mtt{{}n{{ylmtt|{{}|nv^fs{{mtt}|lksedkċ}tts{{mtt{{tllkztl{{\[bbVZred{||ztlu{{ekdlekmtttsllriu{{tts{||{u{\[b{u{{{|f]ctll|z]cd|edk|{{ttsu{{{{{{lekttsmttlkstt{lriddc||uztsreUMR|tllbVU||}SKJut}kd\wlultdc\llkPF=]bZSKJVTLf]c:97lekztlutzllek[TTf]clks]bZu{{{{tsltll{||}|}\[[u{{mttVTL}{tt{{srettsLKRmtt{||sletzl~ultttslksf]cbVZUTSVTL[TT]cd}||lddf]c{tt[TT[TT{u{d\\UMRJHFJHFlekekd}tzl]cdkd\ultu{{r]gf]cJHFddclrilriultv{u{\[blks|mtt|]cdmttmtt}||\[bmttOS`lks{{}Å|{{}ttsslekk]|tt{tts{||uztultztlekdtll{tttsl||||f]ctt{vlddJHFMRKfkkiq]uztttslks\[b]bZlksult]cdlri]cdSKJbVUMSS{{|\UZult|tt{u{{{u{lddmttlld{||lrilri|zlldtsldc\dc\|mtt|zuztSKJtllkd\{ttultzlliWUztlsleSKJzllslekd\v{ekdtslUTS]bZllkVTLd\\VTLek]\[b*)(f]credtllsre{{tekd[TTddcultdc\dc\tsltsl|zu{{}sreuztl}b[Ub[U\UZlekulttt{}|z{u{|sletslsre|{u{f]cedkUUYUMR|{{lriztl{u{|ztllUMRVTL\[[||zkd\slellk[TTult{ttkd\D;9edkJHFllkd\\sretts|}llklkslks\[b}ekd{{ow|{{lks{||ult{{mttmtt^fsu{{}|}nvnv||mtt}}Ä|ęuztlri|tzlb[U||~u{{{||lkslekztl||lri|{{tdc\ult}||z}lek]cd\[bUTStt{}{{tSKJ[TTtt{lldfkk~{{ultttsult||\[bultf]cu{{{u{|tt{ttsldd}||zdc\j]\d\\VTLlri{ttf]ctsllddvztl{ttlddv{cbVuzt}tllVTLllktsl\[b)+2mtt|utlltsllekb[Urg]u{||dc\ek]|zzllsre||{|||z|z|uulldztlttstt{ultttsulttt{rg]||{u{|ultvredldd}d\\[TT||}lek|lri{u{lld{||\[[ek]SKJtsl[TTb[Ulld|dc\usresle\UZldd{u{ztltsl[TT>B9owulttslnv}{|||ultnv{{u{{u{{|lksmk{{}{{|z{||red{u{lri|z||{tttsl||{ttslezl|uzt{u{{u{ztl{{tllduslesle}tt{j]\f]cf]cultultlks{ttedk\[b{{llkddc]bZ{{tlld{tt}]cd{u{ttsUTS|zttsuztekdlld|ztl\[bmttlksSKJ{ttlrikk]dc\UUYsle[[TjcVmttkd\||rg]tts{||tllsleJHFddcdc\b[Uult{||\[[:97zll{{ttslztlsreUMRztltts\UZ{{t{{tttslek}|ult{{t}kk]d\\{u{vtzltslzlllrif]c|uutUTSulttzlf]c||ult{u{{u{|}ldd[TTSKJ{{t~ztl{tt{ttreddc\{tt{||uztSKJ{zmek]lrittslddvu{{UMRultD;9UTSLKRlri{u{{u{{{{{tt{lekttslri}tts]cd{{u{{{{lksmtt{{^fs|mtt{{~tt{tll{{{|||zedk||{ttSKJ{tt}|j]\tllJHF{{{{lri|zdc\tsl{||{{{{kd\ztl\UZ}|{||f]cv~f]c{{{tt||lek|u{ttuztulttts}||}}lld}{ttu{{ultlks{{tts|z\UZllk[TTddctsl]bZtzlSKJreduztu{{ldd}|{ttekdztfred[[T{{tek]redllk}[TT:97zllkk]d\\kd\lldred\[bf]clldlri{u{{||tzllddf]c|llkult{zmztl}v{kd\ttslks}mttu{{mttuzt]cdultut||[[T|{tt|{||||lri||ztlbVZ[[T||cbVlldMRKd\\ekd}SKJj]\SKJUMRult{zm|mw{{}}ult{{|]cd]cd}lkslkstt{{{\[b{{f]cmtt{zm}v{Ó{zmtts|]cdlektsltt{ztltts|ztsl{zmtslultu{{tll|v|tlltsl{{}b[Uv{}v{ldd{{fkk}UTS}{|||llk{tt{{t}tlllekv}ldd{u{||tt{|{u{cbV|lldiq]jV[}ztltslSKJutVTLlrivlriUTSlddJHFFD;llkttsSKJ:97lld{u{||rg]JHFlek[[T|zekdlddbVU|zVTLek]|zdc\|z}||tsltllut{||tt{llkekdtllu{{t[[T{{|z{{VTLtt{tlltts}tsl{tttts[TTyl{u{lddekdVTLUMRwlsre{u{kd\lksu{{\UZf]csleg\rredmttv{{||{u{}||lek{||{{{{{||}{{tt{|mttmtt^fs{{|{{{{{{|}ă}lddv{tlluzttsl{{tf]cJHFf]culttt{u||[[Tsle[[Tkd\f]c||tt{\UZ{{|\[blkslri]bZttssle{ttttszllkd\tllult}lekmttedk{{{{{{{{lld|zlldlrittscbVUTStt{|z\[[{{t\UZ{ttttssreslerfk|||u{ttfkkddc[[TllkzlmttlriztlUMR:97||ukd\ztlu{{ylekd\{tttllek]llk|{tt||{||wl}]bZlriuztldd}{{t|uuztult{{ult{||||||z{{f]czllult||SKJ{ttsleuzt||{{MRKUMRlekf]c{ttdc\tlld\\tsltllj]\VTLVTLutt{vtsl|[[T[TT\UZultzllultedkldd|z{u{lddddc{{tts{{{{yllks|\UZmtt|{{nv{{|{{nv{{{{}u{{}lriuztllklek{||f]c\[[llk|z{ttultmwlekb[Ulrimttf]csle{ttVZ[mtt]cdnv|lks]bZzlltslldd{ttultfkku{{{{lddtsl\[[lri{{ttt{d\\VTL||ttslrikd\|SKJaWM[[Tf]c[TTVTLlldlriJHFUUYsle||ldd||{ttultedkvlritsltts{{||{zmultntzlsretts|zztl{tt{{t{{|ztllut|]bZkd\{u{ztlldd{{d\\edktt{||UUY[[TLKR{{f]cultttslksultUMRlksddc\UZ\UZlek}rfk}|tsl|{{tulttts}{||tllf]cmtt{{tj]\f]c}mk{tt|zmttu{{lks{{|lksult\UZtlllek\[b|^^q\[[mtt|n{{MSSult{{~{{^fs}{||}|llk{tt|]bZ|}{{uttll|u||{{t||lri|ztt{{||SKJekd{{t|{{lri||{{tuzt{u{}mttfkkult|uuztuztlksultttsb[U|zultlek|||srerg]||d\\ddcztllldFD;f]clkskk]|z|zllk3+*ttsUMRf]cr]g{u{tsllek{zmsletzllek}}ttsldd|zztl{{t{u{{||}||}|}|kd\ult{{tsl|}{u{[[Tddclld{||VTLJHFVZTtsllks{u{{||{{t{{\[[\[[}f]c{ttlldttsf]c|uttskk]aWMVTLedklksmtt||f]clddtt{\[bult{||{{{u{|{{t}{{ttsttsmtt\[bedk\[bmtt{{mttnv~{{tttssre|tts{||||tts|z}|z}{{t|zwlu{u{ulttt{lek\[[||{||llk{{\[blks}}VZ[UMRedkuzt}{{tfkk{{{{{{f]c}ultult[[Tmttfkklek{tt{tt|ddckk]yfdtts||kk]|ttsSKJtt{tzl[[T]cdlek}UTS*)(ultbVZlek{{t{u{||{{wluztlriu{{{||f]cu{{|z||}|ultrg]wlsleut||{tt|tt{{{t|z|uztf]c[TTddctlld\\tllkd\ldd\[[ultttsekdlkslks||UTSd\\llkVTLtt{tts|{||{||[[Tg\rLKRlksf]cek]dc\VTLkd\]cd]cdek]||}ult|llklksmtt{{{{|{{edk|\[[edk{{{{vuzt{{{{tt{}{u{|ztsllksultult||tll||{||]bZttstt{\[[lri|ztzl]bZttsu{{tllwl}u|zedkuztu{{{{mttult{{t{{lri\[b]cdmtt|zz}lri|lksf]c|u{{\UZ}|ult}tll{tt|uUMRllk{{tlksultlks{u{mtttts}}[[TSKJbVZ}tt{}[TTllktslkd\||sle|ztll{{tllk74,SKJtllddcmttldd{{tslef]cslesle|lri|z|u{tt|usre|lldmtt|ddctt{{u{tslr]Zu{{|uultllkfkkSKJ]bZ]bZF=CF=Cmttlri|{{ttsllkstlltts]bZlekuzt|ddclkslrid\\sleu{{slesred\\cbVtll}uztlritll{tt{{llk{u{}lks|{{|tt{||nv|{{lks{||}{{tlltts[TT{tt}v{ztl||mtt{u{{||SKJ|u{{t~{{|edk|tsltzl{{t{{lektt{{{mttldd]cdvlksu{{\[bUUYmtt|{{{{VZ[|mtttt{lkslksult\[[dc\||UMRyflreddc\j]\j]\{ttllkedkb[Uultult]cddc\[TTVTLtll[[Ttllr]g}{{tekdultbVZj]\UTSC8.JHFlddJHF!ekd{{{{tultllksle|zb[U{{|||}{tt}v{|ttssleuf]c}mtt{{tlri|{||tt{dc\tllekdlldvmkmtt{|||rfkekd[TTekdlldmttek]}lek\UZVTLlks}redultd\\{{{||}\[[ddcult{||}lks|tts|v||~|lks{u{ldd{{mttMSSUTStts~ztlv|]bZcbV|z\UZddc\[[[TT{|||mtt\UZlksultJHF\[bUMR}|||ult{{tult||z~{{}f]c[TTleksleztl{u{red{ttrfkult|ddcztl|||j]\u|cbVddcztlllk}kd\u{{t||{zmMRK*)(|ztlltts[TTlriredtsl|}lld||n||u}{zmlriztlbVU{tt|ztt{uzttts|z||ttsmttUTS^^qlks{u{{{{||lddztldc\ult}||}{{}\UZ{{||}~|{u{uzt{{|ultmttedk{ttllkult|ult|z|{||tzlsle{|||]bZult{||{zm||{{|z{{t}{{t{{t|{{tdc\tsl[TTkk]f]cf]c{{tt{tt{lek|tt{fkkmtt]cd}|Ù{{ult|}{||tsl{||llkedk}||{u{ldd{tt||slesle{{tj]\}kd\ek]dc\ekdredVTLb[UVTL]bZSKJlksVTL*)(|{u{{u{ztlttsutsre|u{{b[U|zultut|iq]{{t{||b[U{zm{{t|z{||{u{tt{tt{tslmttuzt|z}ttsuztlritsl]cdMRKllkmtttll\[[|ztl{{{{t{tt|utsl{tt|zbVZ}}{ttmttlldSKJlddJHF|z}|}lrimttmtt{{|}wl~mtt|ztt{|{||ultu{{mttmttlks{||lks|ddcf]c{{{u{lks[TT\[[dc\|ztsl|z}}{{d\\llktsl{{t}ttsdc\ult[[TUUYlriuztMRKtllllkylddc{{ult{||}tt{ztl{||tsltt{u{{ddc\[blldlddedkdc\{{tlldj]\{ttSKJSKJ]bZlridc\d\\j]\j]\lddekdttsUTS*)({tti\Vldd{tt}zllsre{{t{{tllktsllrid\\yle||{u{lldyletts}|{||d\\|u|{|||lrikd\kd\uztu{{uzt]cdUMR]cdddcd\\]bZult\UZd\\nsleu{{||{ttf]c{{tdc\|}JHF{tt[TT|utsl|mwUMRttslksultlkstts{u{{{||{||{{t|lks{{{{{{{{{{{{nvlksnjultu{{ut{{tts{{{||\UZult]cdult{ttultllk|ultedktts\[bf]cult{u{{{ttsmtt|tt{mtt{{}lld|zdc\v{tts|zd\\lks|d\\red{{}\[[tslSKJ||tsl{ttultdkVSKJVTLVZTmtt\UZredtllztl\[[SKJ{{tJHF*)(dc\ultd\\i\V{tt|~sred\\v{lldek]f]c|z||zlltll{tttt{|z|llk|||}ek]|cbVlldmttd\\lldllkedk{{llkulttts~bVU[[T|sreddcttsf]cv|||sleb[U|utt{d\\\[bLKR{{llku{{{||}rfk}{{{u{zllu{{ultult{{{{{{tsl}|{||lldmttlrittsslemtt\[bult}|zuztlldttslriurfk}dc\JHFf]cultlldult{u{f]c}{||mttlld{{}{u{ztl|z{{ttslsleudc\ztl|tzlslelksekd{{t{||ultleksleUTS{||d\\slett{vldd{ttsle{{tUUYztlult|sremttSKJcbVF=C*)(d\\tts[TTv{{tt{{tu{zmultred{{t}lddllk|z\[blld{{|uu|ult|zf]c|z}ttsu{{]cdJHF}[[Tf]c\[[tt{ulttlllri{{}lekedkllk|z|u|udc\llkb[Ui\VUTSlddUMRkd\VTLrg]f]cf]c|u|v{{{||tll}|uztlks{{{{|}{{^fs}|~}tll|tt{tsllriullk}lektt{}lldf]ctts{tt|uztj]\|}tzl}ukjV||ztltll\[[ddcultult{u{{{tlluzt|utll{{|{{{u{u{{{||]bZlriUTSd\\u{{f]c}ult{||d\\{ttsle|uztl}u{{|{||{u{||{|||||u}JHF[TTkd\VTL74,ulttslttsbVU|wl[TTsle{tt{ttultvleklldlriekd||tll|ut|u}|{|||z{tt{{t|zulttslult}{||ekdf]cUMRVZ[\[b}||u{{ek][TTlri{{|ddclridc\j]\lriultlek}[TT}}{{~|tt{}uztlri}|zu{{lriuzt{||lkstt{{{||lld||z|||ztts{ttlekUTStts}}|{zm{{tv{ttsVTLlldlldSKJlekedkuzttts}}{u{{ttult~tts||mttf]c}lldv{}tt{ztlrfkultbVUu{{|ultslev{{}{||cbV{{tedk{||JHF*)({{lddttsztlultcbV||rfk{zm}tllj]\uztuztztflddd\\|tt{u|{||lri{{t|llklek{||||tts||}mtt}d\\{||srett{lekztltzlkd\|kk]kd\{zm}{ttu{{lrilldf]cztl~{{tddcvmttrfkUTStsl{{|lldtslylult{||mtt{||{{tleku{{}|{u{lriuzt{u{ē}bVZsleult}lekrg]sle}lri{zmtzl{{t[[Tllduztu{{mtt}]bZultu{u{ulttsllksVZT{{u{{}{u{}{{}lldsle|z{{ttslkd\ultlksult}ddcu{{bVZ[TTd\\{tt{tttygtts{{tlektllkd\|ulkslldtslFD;*)(|vtt{rg]||utsltsltll{u{kd\|vztllriedk{{|uultzllld{{}lldf]c}{{ttlltts|\[[rfk||uzt|zu{{lri{{{{|z||}{tt}rg]{{t|z}}|zlriuzt}leklldllk~u{{llk{u{||{||tts{||vtts{ttf]ctt{|{{t{{tddc}u{{tts{{|mtttt{u{{{{|||{u{edk{{u{{redtll}VTLztl}usleztlVTL{u{}f]c|u{{mtttt{lks||z||u{{~bVUtsl~JHFek]lks\[[lrilri\UZbVUultkd\zll[TTd\\uzt|usred\\uztmw[[TSKJ|JHFd\\ultJHF*)(|uztlredulekrg]ztlult}sreult|zttsfkk|z}srellk{u{{||{u{lldu{{|uztultLKRVTL\UZlekuzttts{u{[[T{{lldultllk||uztl}redvlddtsl{ttuztlldlks||~lri[TTtslf]cuttsltllv{}||||lks|||zult{{||{{{{}{u{llkĂvyfd||rfk}{||ztluztlri|lrillktt{|{{]cd]cdmttfkkfkk{{Ù|}|{{mtt{||lldlrikk]lldddc|zlld||ddcldd{{{{JHFUUYu{{lddJHFf]cldd||ttsllklriv{ddclldj]\dc\}}lri|JHFJHFuztlld{ttztlllkjV[|z|zkd\uzttsl}|zztl}tsltts{tt{||ult|zlekuzt]bZMRKlld]bZ|tt{{{tllk||u{{||zbVUtsllldfkk|tslsred\\fkkldd}|{{t}{||tts]bZ{u{~|||{u{tts{||f]c|u|tts~ldduztu{{|}||mtt|{{||ttstt{uzt{ttut~}~f]cmw}llklektts{{lrilriedkultJHFlks{{{{lksedk|z|zlks|zuzt}|}|uVTL|v}slerr]tzl|z|[TT|lri}|tslUTSd\\|ekduztyl[[T}~VZTlekvlldultztlf]c{ttF=Ckk]rg]UTS*)(slej]\}||uldd}}ttsrg]sle|utt{VTLsleztl}zll|}u{{{{tts|zlriUTSJHF[TT{{{{}|uzt{{t{||fkktslmttsre{ttu{{}b[U}{||tzlkd\74,{u{ztl}ztl||uztmtt{u{f]clrid\\lddttsultult}[TTlks{{|z|fkk||{{ttsu{{]cdtts{u{||\[[}|kd\{zmttsekdttsf]ctlldc\tzlJHF{||lkstll{{lkszlld\\dc\v{redv|{u{f]cedku{{~llkekduzt|zttsmtt}{||tllkk]{||tllllklri|zVTLek]dc\|z|dc\{{t{||lksmttultmtt{{}{{|[TTsresle{||lld]bZrr]JHFttsJHF{zm|uJHF:97tsllrilld|}|}}uukd\v{|tt{}{u{u{{lks||lri||{||llkmttf]c{{{||{{t|zuztlekdc\tt{kk]lek||d\\|z|z{||||||kd\VTL{||tllsre|||UMR~}{tt||kk]}{{{u{{{|{tt|z|{||{||{{{||}ttsuztUTSUTSSKJSKJ|}utultslelksddcd\\lek||uztddctsl}{u{\[b}{{f]c]cdJHFultllktsl||lddD;9lldbVUuztekd|z{ttek]|z|z|z|z|z||yleekd}||||[[TbVU{||||{{t|dc\\[[mttlld[[TSKJVTL}tts|\[b{{tj]\JHF*)({tt|z|u}}|u{zmdc\leklld|{{tslellk||uzt{||}zl||||llk{u{|z~{{v{mttlekullk{{ldd|{{ekd{tt|z|ttsldd{u{|z|u|ztllztldc\b[U[[TddcVZTtlldc\ekdldduztlri||{ttlek}u{{ekd{||}zll{{ultmtt{{{{{{mttek]lri||z|z{{tlldultttsUUYdc\v|Ē}|v{s_qred}VTL]cdtzltzlmtt{||f]c[[T|lksedk\[[}tt{|u{{}b[U{{d\\tt{|mtt{{{{}|||redslej]\ultbVUr]ZcbVkd\slelddkd\{tttll\UZVZ[dc\edkuzt[[T[TT\UZlld[[Tzllkd\VTLj]\>EC:97ult|z{{tzllztlVTL|}}|}|red{tt{tttllttsuult||ultdc\{u{}vedk{{{|||LKRtslmttu{{ttsd\\ttsuztldduztj]\|tt{llklddkk]tt{|uldd|{zm|zlrid\\||ekdlek|z|z{u{{zm[TT|zttsUTS|u{{t||{{{ttfkklks{{|]cdtt{fkktt{||mttultttsf]c|z|z{u{{u{ultkd\SKJkd\tll}{{t{{t}uttslSKJJHFb[U|tslvldd|]bZdc\mtt|ttsVZTult|{{}{u{}ċ||bVU~ult|z}dc\ldd|ztslUTSSKJlld[TTslej]\\[[MRK[[T{{tlksllk{||{||mttlrimttddc[TTj]\}kk]lddtslu{{{u{\[bVZ[}|JHF*)(tll|z|uyleutkd\sle||j]\{{tvddc}kk]ztl||}tts}|{tttt{|ztts{tttsl{{t{u{tsllriuVTL\[b[[Tedk|u|zlektt{{{lddtts||leklddlldtll}tll||tsl\[[{||ult{{tMSS|z|zu{{|lddu{{|{tt|sleSKJfkkVTL{ttztltzl|u}{{t{{{zmtllv{ult{{|znvultmttult|zttstt{|{{tkd\dc\{{kd\ult}{tt}kd\iq]|zUTS|{ttllk[TTedklksu{{]bZVZ[lri]cdlek|lekllkllkkk]{tt{{tllk||u|ulksllkb[Udc\VTLjcVcbV]bZlddVTL}dc\\[[uzt{{tlksttslddmtt|z]cdlld{u{[[TVTL{{tlrillk{{tuddc[[TedkmttUMR>EC74,|||ztsl|utllkd\{zmldd|z]bZ|u}}tt{{zm|ztl{u{lks|z}|}u{{||{ttf]c[[Tsre{|||ztslldd]cdtt{{{lks|lksfkk||tllSKJlddSKJ[[Tlek}ultekdlld\[[||uMSS\[b\[[lldd\\edkf]ckd\|zult|||zultult}|edkf]c{{lks|{{mttmtt|{u{|tsl{{{{Ǧ}sreutsre}{{t{u{{tt|zwv{{tukd\|ulldtsl{{ttt{leklksult}u{{ulttts{tt~ultllk|||llku{{tts|kd\||ult|zllkkd\usre}VZTekdlksJHFUMRlri|]cdbVZ|zlldUTS|ulld||dc\sleVTLJHFJHFJHFztlJHF3+*{u{u]bZtsl|u{ttut{{tjcVb[Ukd\ttssle||{u{{u{rfkutfkk}llkult{||}|zf]c{u{zll\[[tt{lekdc\\[bf]cult{{tllkllkldd}uf]cv{|uultVTLuztttsslef]c||ddc\[[|z}u{{ldd|||tllrfkttslek{||{||tzl{{t|{u{|}lriedkllk}{{|||z|{{||bVUredtllƨ|udc\}|uv~]bZuztkd\lek~\UZ|bVZultf]cf]c}}}fkk{{{{mttUTStzl}tllultult{{tultdc\u{{uztekd[[Tlridc\|zlrisleddctzldc\VZ[lriUTS\[[ddcVZT|fkk}bVUtt{|tsllld{zmlriulldf]c{ttUTS|zJHF*)(lksuztuztzlluu{tt{ttuzt}{u{|bVU|u}tll}{||uzt{u{lekvtts{||}v{{u{{||{{t{u{SKJlld{{t|{u{ult{u{lld{||{||{tt}j]\}s_qzll}tsl|ud\\zllcbVtslmtttsl\[[tll\UZ{zmuztu{{u{{|{{t}ttslek}uzt{{tult}{tt{{~ttstt{{{uzttt{ldd|zu{{|z|tsltt{tt{ddcddcSKJ{tttllv{}||ztlmw{||uztfkkMRKlrilrillkddc}{||edk{{f]cleku{{u{{mtt{{tsl|mtt|z{||tsl|dc\{u{edk|JHFVTLVTLiq]VTLu{{]bZlekllkuzt\UZttsJHF]bZvJHF]cd]bZSKJut}ub[UlldcbVzll|}|{{t|zmttmttJHF*)(ldd{zmvu{zm}|{{tut|vutv{{||tts|u{tttts{zm}{u{tlltt{ztl|{||}v{||llktlllldlddlri}{{f]cult||}mttf]c||ultrfkulttll~}{tt{||{ttddctzluztttsuzt||edktts{||{{{{tmtt||{tt}|tts}d\\lekttstt{|}}tts{ttekd}|b[Uzll{tt}lksult{u{~}tllv{v{tll{{|z|zlldf]c}{{]cduzt}{{}v{[[Tuzt{||{{tVTLcbVllk|tzl[[TuztUTSuzt\UZVZ[ekdtll\[[uztUMRlri[[Ttts}|zkk]ekd{zm||ztzl[[Tedkv{:973+*|zttslld{zm}||ztlldd|utsl||{ttą{{t{u{||lrif]c{{\UZ\[bf]c{{}||[TT}\UZ{u{sle~ut|z|lriuztSKJ{||ultlksMSS|{{}|zlks{||||}|uzt}{tttts||ult}vuztttslddlddtsllks}ultlksultlddldd~||}ulttll}|zlridc\|zekdlri|tslf]c||{{t{{uzt|z|lldllduztkk]]bZ{ttllk[[T|mttddcVTL{{}f]cUTSlkslkslri{||lksttsultultlks}|{{tdc\]bZ|z[[T[[TLKR*)({{tll{zm|z{{t}z}|{tttt{uzt}{||}}|ddc{u{{{{||ttsleku{{ttslek\UZlddVZ[}lkstt{{||tllttsrfk}|v|lddrg]v{utlddlldekdtzlekdtlllld~{{}\[[f]c|z{||llkllk{tt|lldtts{u{{{{{ddcttsultult{{|z{{}d\\{ttv{}tt{tllf]cut{{\UZrfkult|||uztllk}sle{u{d\\]bZtsllrillkmtt{ttmttd\\|||v{ult|tsltzl{|||lriuztlksztl||z{{t{{t[TTlldekd}d\\{u{d\\[TTJHFVZTuzt{||ekdf]c{{lek||lrizllztltzl|z{{t]bZ]cdu{{:97*)(kk][TTu|uzt}}}sle}|ult}|{||edk|z}{{d\\]cd|z}}~ylemttkd\ddcf]c{u{sre}ttskd\zlldc\llktslttsd\\|ultu{{ttslrilksddclksddc||lks}}||z{{{ttrfk{zmtsl{{tv{{}tts|{{t|tts|{{tv|}}}}\[b}ddc{{ttllf]culritsl}|{zm||}}]cdu{{u{{[TT{{mttv{|ztl{{tll{u{{{|z|z|zlrikk]|z}tzltllllk{tt|\[[kk]||tllVZT|u{{tt{|z]bZ}[TTtt{lri{||ultlld|zllkekd[TT{||mtttzltll{||F=C7-2utztl||{zmsrekd\{{tsleultzlut{u{}}mtt}{u{uzt|lksmtt{ttu{{{{tuztdc\tt{ult{||||tll[TT{{tddcut{||\[[{||ekdlld|{{t{||tts\[blks|lrilks}llklddllkllkf]c\[[tts|ulldu{{edk}}ut}|u{||}|ttssre}}}u}{{f]c{u{zlllddztl{ttttslksedkFD;kd\zl[TT}UMR\UZ|lksedkUTSu{{u{{|zyl{{t}{{tllkd\\||{{|ult{||]bZ{{tlddVTL{||||{{t|mttf]cuztultlksllktt{{u{edkrfktll}lri{{{tt|u}ztl[[Tztl~|{{tlldlldJHF*)(tsld\\|zztlwl[[T}v{u{{}{tt}~zll}~ttstts{u{|z{||||tlllritt{\[b|}ekdldd||llk{{t|z|ztsl}{{ult{{tcbV{tt}||cbV|u{||VTL\UZ|{{||||uyle|{tt|tllllktts|ztts||~|f]c{{~|lld{u{{{lri{{{{ztl}tlltsl}f]c{u{tts{||[[Td\\zllj]\vSKJv{sre\[[}|{{mttf]c}tts}tzlVZT}\[[ultdc\lri|{{tu{{ult}ddc}|VZTVTLuztmttJHF|z|zlld}lld}tts|ultf]cddc[TTtslf]c{{trfk>EC{{tVTLlldllk{ttfkktsl|z]bZ:97:97}||tll|u{{t|ztl{{t|u}u}|ultdc\slerfk|v{{{t|{||vtt{{{t]cdtt{uzt{ttddclri]bZrfk|{{t|u{{ultlriredu{{|r]g{{t}ldd||lddredredmttUMRu{{{tt{||srett{}{{||rfk{||{||ttslri{||}{tt~f]cv|\[[vtt{llk|u|z|||lldtt{ztf}{||dc\f]c}}|}kd\lekVZTlrisleredzlltllztlsreVTL{{tv{{lks|zuztsle\[b]cd}~uztmttttsmttddc{|||z{||sleJHF|\[[[TTdc\}lri|z\[[]cdrg]ekdtsl||ddcuzttt{|lld|vdc\u{{SKJdc\tslVTLlld[TTsre||lriaWMSKJ|zD;9*)(}tslu}{{t|lekaWMut|}}|[[T[[T]bZmttd\\{zmtsl{{t||}lriztl}{ttldd}{u{}ult||z|zekdu{{f]cztltts}ztfddc{{tsre||{tt{||lksulttt{llk{{sle{{|{{tult}vllktllcbV|z|ztltt{{||mwsresleult{tt}uzllutylelritlltlltzlkd\b[Uddc}lekedkut|||u{{|zllk{{|tslu{{}lld}UTS|z[[Tultuzttt{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\lekv{kd\edk}{{|tts[[T{{mttdc\]cdSKJleklkskk]{||tsllldllkslelld[[T{tt}|ddc|zldd}v{ultuztttslddmw{ttultv{{|||tlltsl{{t{||\UZ{{|{ttSKJttsjcVldd]bZ|}|lekf]cdc\tts{{}lri{{}yledkbVZj]\[[T|uekdd\\{{{ttddcttsf]c[[Tek]sleultlksFD;zllztl||tt{UMRfkkultu{{|uJHFred}}{{{||\UZztl{||||z]bZkk]dc\\[[UTS]bZ:97*)({{t{ttlddred}{zm}ztfztl|}{||{tt||{||ddc{{||lektlld\\lld}sredc\u{{{||sleSKJ|tlltllzllr]gmtt{||tsl}|z{{tuztd\\||ddc|ztllrittsztl|z|||{u{ut{{lld{{t}}|lekult}tt{tts{{UTSlksttslritts{u{||}|uek]|u{||tsl{{t||{||tts|z{{t\UZddcztldc\VTLVTLek]tll{ttyfltt{\[[}[TTtt{leku{{VTL]cduztu{{lksd\\|zf]clri{u{j]\edkttsllk]bZllk{{\[[SKJek]tll|vVZT[TT{||dc\ldd[[Tvlksf]c}ttsf]cJHF]cd{{lektt{fkk}v{|zsle\[b~lrisre]bZ[[TFD;||:97:97rfkkd\{tt{{t|||zult}{{lektts{{tllk{u{{{{ttb[UbVZtsl|ultztfv{{u{llkztlUTS{{sre|mtt||mtt}ek]}{{\[[lrisle{u{}rfk}lri|||}tslultmtt||llk|u}{u{}ttsllk}{||dc\{||ult|z{{ttslult||uztÓ|{||{||lldv}}ultbVUf]cldd}edk[[Tlriultultlriek]{{tdkVmtt}ztlulttt{llkUMRLKR}{tttts{{\[[ttstts}|kk]llk|||uztlek}{{f]cJHF{||VTLlri}|mttllk\[b{u{ultllkttssre{{trg]|zuztMRK\[[dc\:97*)(dc\ztl}||{u{u}|{||}uuzt{{t{{{u{SKJ[TT|zkd\u{{UTS||j]\{zmldd}rfk{{tll{tt{tt{||JHFtslv{{{tu{{uzttts|zlldd\\v{|z}|ullkf]cultult|u{tt|z{||v|ylult{u{|{u{{||ztlult[TT{tt{{[TTtlltsl{u{tlltslred}{||tts{tt|uzt{u{||||z{tt{{[TT]bZb[Ulriuztdc\{tt{{tredult|z{||{{t{zm{{t{{tVTL\UZttsd\\}ddc||\UZek]SKJ{{ttt{UMR{{td\\VZTUMRlri{ttddc||}d\\tsltts[TT|}|u{{zllri}ddcUTS[TTlektslFD;,55}yle}ut||}{{|}~|sre|z|ulri|tllu{{|z}ult|v{||dc\fkkleklks~|{||j]\tll~{u{ututtts{u{}{||uztuztllklld\UZVTL{{|z|lrikk]{{t}tllrr]{{ttt{lddf]cv{lri|~{{|]bZ}~fkk}|llkb[U{u{||d\\||tzldc\cbV{{dc\j]\ddc}|zu{{tsl}{||leklek}zll|zvsle}v{VZ[ultultbVZ}|tllSKJVZ[uztUUYUTS|ddctslllk{{}{ttleku{{lri{{{{tztltll[TT{{{ttut}ddcUUYllklritt{ztlVTL|{{tlddtslmttlriztltslUTSJHF:97*)(}{||ut}tll{{tztlultuzt{{t|{|||u|}|zlks{tt|tsl{tt||v{ddcutJHF}tts}bVU{u{{{t{u{{{slerfk{{|{{tult\[[]cd[[TmttlriVTLlri|ztl||lld|{ttd\\{{}{{tll~||}}lri{tt{||llkzll|slellk{u{sletll|u||}lkstzl||ulld|v~{tt{u{\[[}{||uzt[[Trfkd\\{u{tsl|z|uult{u{UUY\[[ldd{{t{u{utult{{t}ultj]\lektt{ztllriddc{ttb[ULKRVZ[lksf]cttslddult||{u{ultut{{tbVU{||VZT\[[{{ttllVZ[mtt{ttmtt{{tf]cSKJ{u{|\UZztldc\SKJv{tsl{{tuztuzt|\[[VZTUTS:97*)(||kd\{{tztl||srettstsltt{}|z{u{UTSztl|z{||tts{||ekdbVZekdu|uVTL\UZ{||f]cult{u{}|lekv{{u{leklksf]clldUMR{{cbVddcSKJuztddc|usle{u{}kd\ult}}{{t{{{ttdc\zllztlut||zv{{tttsl|kd\}j]\~{{{tttts[TTmttu{{kk]leku{ttuztlekedklrimttd\\\[[||{{ultwl{u{UTSedkd\\|UUYtllf]ctts}|z||UTS\[[llkUMRrededk{{|lek|sre||utddclrimtttt{{u{|lri\[b\[b[[Tlri{||lldf]cmtttlllekdc\uuttsmttv{[[Tekd:97*)(ztlutsl}||{tt||{{}tsl}{tt|zUTS]cdlritll|lkslldtslmtt||uultwltslrfk}j]\\[[uztleksresre{||{u{||{||d\\}{tttt{|z|ulks}|ulld}|z|tllu{{|||u{{|sle}{u{}lddv{|umwtll{{t}}ttsfkklri{{t{|||ztts{u{b[U{||i\Vvllk}tt{lriSKJb[U]bZ{u{llk{ttdc\uztfkkddc{u{||}tzl{zmtsl{ttztllldllktt{||lri{u{slef]c|{{tMRKsretzlsretslUUYUTS~ttsldd{||{u{\[b[TTf]ctslcbVtlltt{b[UUUY{{kd\ultJHFleklld{ttfkk}UTSJHFVTL|z}JHF*)(}ut|z||}{tt}{||v{||uzt|ztts|lri|uedk]cd]cdf]ctsl{u{|z{{tt{ult|bVUlrif]cJHFbVZlek|ultvslezlltt{}fkkj]\}{ttult{zm{||||}|~n|ztll{u{{{t|zddctllztl{{|z|}}}}{||||||||~ultzll{||llkkd\lek}sle{tt|ullkllkzll~[[Ttlltt{[TT\[[ddcSKJutredu{{tt{|z|zlridc\tt{lrif]c{u{{||{u{lkslektllylezlltslmttsleultJHF{{ek]lldzlllldekdztl|z]cd|ekdUTSultJHFVTLkd\v{sle|tt{tll{{ttts}lek{{tlks]bZF=C*)(lld|z|tslvtll~rfk{{tts{||ttstll||sremttu{{fkk|uzt{ttuztmtt}{||||z{||uzt||tts}tt{f]cJHFfkk{||ddc{tt}ultult|zddcsle}lrillk|sle||tll|{{||lrilks|u{||||{u{tll|ztt{v[[T|u|ztl|uwlzllsleuztut{u{yfdllklld{||{u{cbV}||ttszllb[U}ttsrg]ultUMRrfk[TT{||ttslldllkJHFedk{zm]bZred||cbVlkslks}|ultrfkulttts|ult[TTztlVTL{{|ult[[T{zmfkklrilekJHFdc\tsl~lddlldlri|{{tztlSKJ||mttiWUd\\lritzl}ldd{||tzlfkkLKR*)(u{{|||v{|z{|||z}{||{||lkslddlrilri{{||u||ztl{|||uJHF|rfk{tt{{kd\leklksf]cmttbVUult[TTtts]bZdc\tslv{ztlttsekd||uddc\UZsle{ttu{{tts|z{tt|z{u{tts||\UZztlwl|mw||urfk}|f]cultsleu{{}{{uzt\[[{||ut}}zllztfVTLlekddc}lddultkd\mttekd]bZ||SKJuzt\UZdc\kk]{||zllv{|tts{{t{{tUTSdc\tt{JHF]cdddcjcVlriyflu{{{{[[Tmtt|zlri|zlks{{tmttVTLredcbVlksdc\ttsuzt||tsl{||ddcfkk]bZJHF*)(||z|u}|~}sre}|z|tsl||tt{|u{{mttlekulttsltts{||lldslelldultf]c}fkktt{f]c{{tlritll|lddultultttslld}{u{{zmtllultekd|{zm|uultult|ttsddc{{tedkred{{}tts}|llk{{}{||ult|u|usle}sleyfl[TT{||ddc{||lri{tttsllksi\V|u{u{{tttll{u{{{rg]tll}v{ttsredtslztltslVZT\[[ekdu{{ek]ultbVZf]clek|ldduzt}rfklksu{{ult|z|{||lld[TTf]clri|{||]bZddcllduzt|llduzt}bVUtlltlltlluv|zfkktzltslllkllklek\[b|zVTLsle\[b:97]bZrr]ut}ztl|\[[{tt|kd\lld{{tultu{{tt{ultu{{lksmttedk{{||{||tll|zf]c||kd\tlllldlld}llk||{{|zultedkekd{u{||JHFtllUTSmttultuzt\UZ}|zd\\ult]bZd\\tts{zmtts|||[TT||lld|||z|z{{|z||u{{dc\{u{llk}}|||v{||||||lks}{tt|uultultleklek}||ututfkkddc}wlj]\{yfj]\f]c|uekdllkv{ultd\\i\V[TTv{v{ttsutek]ldd||\[[ult{{ttllfkk|f]cuztldd{u{uzt}u{{|UTSult{{t]cdVZ[}uztJHFMRK{{t|zSKJ\UZlld}{{llduztllktll|JHFJHFVTLllk\[[&&ek]{||}|||{{ldd||z}{||}|lriultlksmttlriUMR{{sle{{lriult}bVZtslfkk}{u{ddc{tt]cdUTS|mw{||d\\|dc\llk{||lri||{ttu{{ultldd}{ttUTSVTLrfk{u{slelritllztllld{||}ddc{tt|ttsv|b[Uuzt|{||sle{{tttsulttsltllultred|ulddVTLcbV}||ldd||}v}||ttsttsddctsllekSKJd\\{{t\[[dc\}ult{||llk||v{{u{mttlldf]cbVZf]c}ddcttslek}\UZv|uultredUUY{zmmtt|z{{tult||||~lrilritsltsl|z|zf]cu{{{tttllllklddekd|ztzl|ztl}\UZlek\[[VTLslemttMRK%&tsllld{tt||ultuztuzt|z|UTS|{{|[[T\[[]cdlekd\\{ttleklrif]cldd{{}sle}mttSKJllklldsle{ttddc{ttj]\llklritlluzt|lld|}{ttbVU]cdVZTlldultslef]cdc\ztl||{||||mtttslmtt{{tlltt{|tll{{sleztl{u{|||ukk]v{dc\v|f]c}|v}f]c}|||ukd\||kd\}\[[ztlsre{tt{{t{||sre[[Tlddkk]{||bVZ{{t{{tzllf]clek{tttsltt{ztllekult}{{tf]c|uddc{{j]\{u{f]c\[b|zlek|mttlek]cdtts|z}[[T{ttlddlldlld}ekd\[[dc\lriu{{{u{}llkmttf]clddddcMRK*)(VZTmttztl|u}|}{{t|zlekllktsl|z}[TTd\\{{{u{}f]cttstsl{tttslmttJHFlld[[T{{llkj]\VTL||ldd|z{ttllkult|z{||MRKutll|v|j]\}lldsleulttts}|}|z}}tt{|z}{tt}utrfkb[Utll[[TlksbVZ}|{ttrg]}}ulttt{tts}}lksrfk|j]\{{tllkllk}ut{u{lri}ddckk]|{u{ttstll|lekb[U{tttts{zmuzt{ttuztztlldd}{{}}|tsl[[T||}tllyl\UZ|}[TTVZTtlllri|tllztlrfkultd\\ult|zu{tt{{t{{tlld{||]bZtzl{{lekmttlldztldc\>ECtts{u{}|||z{{|zuzt}SKJ|]bZVTLkd\lld]cd\[blek{u{{tt{{ekdlldult{||{tt{{t{ttSKJlld|lriuzt|{tt||u{{u{{{{|ulttt{lri|zllttsttstt{kk]ut}{u{tlltts}tts}v{|umttldd[[Tlldsleztlultllk|lddztl{{tmtt{tt{u{zllut}{{t||}||tsl{||sle[[Tlldlri{{{{tt{{u{lksuzt{||sled\\SKJ[[Tuzt{|||}{u{|tsl|z{|||||lks]bZmttslemttedktslmttldd{{t{||ultttsj]\llklld{tt}lek{{ttstll[[Tmtt}lek{||{{tlldlld]cd-1+tsl|{||Ĥult|||z}}|lddu{{uztllktt{lek{u{|ztlu{||{||}}}kd\lld{||u{{zlllkstzlmtttts{||ldd{||mtt|z|}}ddc{zm|z{ttlriddc}}tt{{{{{{{tllttsfkktsl{||{tt{u{d\\SKJu{{rfkv{zll{{t||{{tu{||ttskd\tsl||lekut|u{{ztlsre{||]bZtsl{||tlluztuztsle{ttedkzll|ztsltllj]\zllslelld|{tt||tsldc\tsltt{lrikd\slered{u{lddddc|u\[bllkmttSKJtsllrib[Uedk{{ultedk}|ztll}zll\UZllktt{ttslksmtttt{[[Tultlri{{tlrisle\[bLKR%&}{||Ħ|{{{tt}{{{{t||utll|zVTLlddmttmttlksttsult|z\[[ztld\\tlllld{{tsl{{sle|lld||{ttUTSlek{zm{{LKRekd|ukk]|z{ttttsuuzt}||{{t{|||u|fkktts{||{|||z{||ttsu{{lddlddd\\tts~[[Ttsl||}}}|u{{t\[[j]\lriSKJ}||}||ztzl}{tt}ldd|{{ttll{||lddrg]{u{lrilri\[[|mtt{{t|z{{tVTLbVZztl{{ttsldc\]bZllk|ttsldd{u{|tt{u|u{||[[T{{\[btt{b[Umtt{{{ttrfk{u{UTSlritlltts}ult{||ddclri{||tsl|b[Uttsllk[TT\[[ek]FD;}~|{{t||{tt|lri{u{llklri\[[{{{||{u{dc\{tttslzll||{tt}}||sreut{||ddc}ttslrikk]llkllklld{{tUMRttstslultuzt}{ttultlekekdlriddcu{{}lldtt{uzttts{{t|}lddult~|z}SKJ{u{v{sre|ztl}||||mttllk}{ttv{}ldd\[[lldjcV}]bZkk]bVZ{tt}u{zmVTL\[[|\[[f]clddekd|sle{ttutf]cVTL|UTS]bZztluztlridc\}rfk\UZ|z|u{{{{tts}u{{tt{u{{|z}|lrilddf]cVZT{||UTSttsVTLtsl~dc\ultu{{ultllkUTS)+2|||zl{{t|||z{{ddc{||lks}uzt{{t}{u{{u{utlddf]ctllztluVTLult|d\\ultVTL}{{llkllk{tt{u{u{{ztlttskd\JHFlri|tll|||lld|tllsle|ztl\[[}{||tt{||zll{{t}llkdc\yleutlltts}{tt}uzt}{tt{u{ttsdc\{||{{tllkztlztflddlrillkddcek]|zdc\|zdc\lddUTSf]clekred[[T{{|u{{t}edk}|srett{{u{lrimttuztddcekduzt]bZedk|ziq]lks{||sletllutult{||uztu{{dc\tts{{dc\tts\[[|zddc{ttuzt}{u{tll\[bLKR|zu}v|||Ĝ||||fkk{{{||{{}ult{u{tsltt{}tslldddc\rg]llk{ttlldsleutult}llk{||d\\|u|{{llkdc\]bZttslek|uldd{u{}cbV{||{ttu{tt{||{{||z{u{ttsult{||fkk\[[u{{{u{{tt|{tt{zm{tt|u|ldd\UZsled\\kd\{tt{{tlldmtt]bZekdtts}bVZ}llklldkd\SKJddc{u{ztlllktzlb[U{u{{tt{{tu{{lri||r]g||ucbV|z}||zekd|z|zmttuzt||d\\UMR||lksf]c{{t]bZ|uuztmtt[[Tttslri|zdc\JHF}tll}[TT{ttultd\\MSSLKRv{|||tzledk\[b}lks||||llkztl|z{{t||lld|utsl{||}sleu{{|z\[[ttsu}ekdllktt{ddctzltsljcV||{|||zzll}||{ttu{{zll{{t||{tt|tt{tslttstlltt{tt{\[[ultllk}lksu{{t|}tts{u{||tts||}|{ttsle{tt[TTkd\tsl{u{{{tkd\{u{v{JHF}|ztllri{ttultbVUdc\{u{lek}ttsttsut||{{ut{||ztl|zsle|tzl|]bZ|]bZu{{\[buztJHF\[b{tt]bZyle\UZ{||tllredVZTek]fkklddlekedk|ttsu{{]bZ]bZ|zv{ult|||sle\[bMRKUTS|cbV~}|znsle|{||lldllklri|u{|||u{{ult{{}{{lkslldd\\ut}}ztlutv{lek|ured{u{{u{{tt}lddldddc\sle||z\[[{||ult{u{\UZllkf]cf]ctzlsreSKJ|tzl[TTutsle|u[[Tu{||tsltsltsluzttts}|u}uztldd{{tldd||ztl}f]cuztult|u|ztsl}ult}}|ult{||d\\}ult|{{t||uyle{|||usle{{t||tsllldFD;uztllktzllld\[[lld}dc\bVZSKJtzlztllriultztlkd\{{tkk]ztltsluztu{{mttv{u{{{||lksddcllkMSSlldult}{{tUMRf]clektll{{tlld{||u{{tll\[[dc\]cd]bZlriutult}~UMRf]cJHF?;C|}}u}|ztsluztUUY}lksultlksmtt|||{u{}{{t|||z}ldd~{u{cbV{{tuu{zmj]\||ttstts|ztllf]c}|lrilriulri{tt{||zllut||||||z{u{{{ulttll{u{u{{tsl{{t|tllf]c{{||{tt{{zll\[[||{||uu{{b[UslejV[|uztl}ttsv{}j]\|v{tt{tt[TT|u}|ylett{sre||tlllddiq]{u{|||kd\{{ttslf]ctll{u{b[Ulksztl|uzt{{tmtt{||\[b|lksUTS{||\[[|lkssle\[bllk\[bUMRttsuzt\[b{{lekdc\tt{u\[[{{t|[[T{{t|{{tultldd}tlllddbVZldd\UZJHFlks||u}{{t|z|uyleult]cd{{tlekultedklksu{{|dc\lek{||{{tlri{ttultlddUTS|||sleddc\[[lri|lek[[T{tttll|u|uztJHFlkscbV|zllk|z}}|kd\|ztll}tll}{{||{tt|ddculttll[TT{u{}}|zn{||{{tlddmw}||}ylebVZ}|ekd}{ttkd\zll{tt{u{ult[TT}[TTlri{u{{tt}mtttt{ultllkztlUTStll{tt{tt[[Tllk\[[ttsLKR[TTtzl\[[SKJmtt|mttddcu{{lekdc\ultlks{u{ult[[Ttzl{{t}fkkfkk|{||uztuzt{tt{{t}ultkd\tllJHF*)(|zzlī}|}lld}ult{u{llk|lri{tt||utddc||{u{f]c[TTlldcbV}UTSn[[Tlrikd\{{lri{{tlri{zm{tt|zll{{t}|z||{{t|}fkkuttslultu{{}}ddctt{||lddldd{{d\\ultv{{ttlriut|z}uztztlzll||tllttsuzt|ulddztltts||lek|uttsek]||}}}lek||ztlslewldc\uztztl{ttuzt|zllklddu{{|{{t]bZ{u{SKJUMRmttSKJ]cd]bZ|zmttlriMRK}f]clldJHFdc\UTSd\\mtt|tlllriekdlri|\[[tlltt{dc\lridc\{u{{{lddlektll}d\\lddJHF$|lektsl{{t\UZUTS|{ttlri|lri|zltllutv{||ttsslebVUldd|zdc\|j]\dc\redzlluztttsJHFlek{{sretsl{||{zm{||}sleult|uzt}tts||ulttzl{||tt{|lriv{{u{|||zmttultek]{u{ttszllv{lekutslcbV|zuztkd\}zll}tsl|z|uv{red{{r]glrilld{u{{u{}|[[Tkd\}|u|zj]\lddf]ckd\{u{}[TTdc\|ek][TTlld{{t{||{u{ult{|||mtt{{tUTSddc|z\[blrimttuztlriu{{leku{{lksmttlri{{{||{{t{{|zllddcttsuztllkuzt|zlekdc\ztl{u{ult}}{tt{||ttsultVZT*)(|utslwl}Ǥ|zĜ||tzl|z||z[TTVTL[TTlriu{{utv{tll||v{}}zll}lld{{tlldlekyfd~}kd\tsl{tt{{t{tt||v|uztllklddcbV{u{SKJlri|ztzldc\{u{{zm{tt{tt}tsltsl|z|zutsl|utts||}ultult|ttsuzt{{t}|utsl{{tlltts{{tult|zdc\tslv{||{{t|uut{{tuzttzl{zm}||u|uuzt||}|ztllztfb[Uekdttsj]\u|zllk{u{~{u{{||||[[T|]cdUTS|uf]cbVUb[U{{tj]\llk{||}{tt[[T[[Td\\llk|z{tt{{|lks{{MSSlriVTLbVUf]cUMR>B9|||]cdtts]cd|ek]}{{t|z{ttb[U{u{ult{ttr]Z{ttMRK*)(ultmw¿wl{||{ttllku|zFD;ultu{{u{{fkkUTS{ttzll}d\\{u{lld}|||}uzt{ttkk]UMRrfkutttsSKJztlrfktsl\UZwlllkttsb[Uldd{||{||kk]}ek]|ultlldllk{tt}slesle{tttsl{u{}}|ut|uztu{{{{{{t}lri||ttslriult{tt{{tkk]{{tultttsllddc\{{t{zm{{tj]\zllv{{u{tll|tzlb[U{{t}|tll}|}ult}lrilriVTL{zm|u|uultlddzllztlf]ctts|z{tt{||uztlldtsl{||fkkek]tts{zmddctllVTLultuztbVUlriuztekdf]cttstt{u{{UUYJHF]bZ}{{[[Ttsl{{mttv{{tldduztttslriuztuzt{zmllkf]ctllkd\lddv{rfkztlv{leklekJHF,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\Vu|||{u{|sreztf{u{|u|z{zm|tsl|z|z|}|tll{{t}~{u{}fkku{{tllult{tt\[b{{t|sle|lektll|zu{u{|u}{||tsltslrg]|sle{{t|tslkk]ult|||lld}ut{||bVUrg]kd\lek||tsluzttts{u{zlmtt{zmztlj]\tts{{zlekdtll|yl]bZ|u{||fkk|\[bUTSD;9lksmtt|u{{lksmtt{{}{||ttsuttsltt{|ztlllekredf]cf]c}{tt}tlltllMRK*)(||vƤtts}ttsVTLttsuzt{tttts]bZ|uztllk{{tztl|uztd\\ldd|||uztl}utedkttslldldd}}}f]c{{tldduttts[TTSKJlriekdu}ttsv|}ukk]||ztlult|}}{|||{ttlrikk]{u{|tll{||}{||u{{{{tult|u}tslv{{{trg]{{t||ut{{td\\ttskk]~tts|vsre|u{{tdc\kk]|||d\\{u{slered{tt{tttll\[[{u{lld{||VTL{tt|ttslldztllks{||lrittsuztlddtll|zllk{||VZT\UZlrislef]cu{{{{tlldc\UTSlrilks|{|||{|||zddctsl}ekd{tt[TT|{tt{u{}{tt}dc\JHF*)(}}Ǧ|||tzl}}uuztuzt}tsltts}ddc|z}|zlridc\||ttsuzt||ldd{u{d\\zll|{{tll}ttsyletll|mttVTLtt{|kd\uVTL|uwltt{|ullkdc\tslult||jcVmw{zm{u{{||{u{{||{{ttsl|||{||}tts|z{zmtll{u{|{{t{{t||||{{t||u}yle||red||dc\uzt||slekd\mtttzl\[[ult||sle|||z{{tb[Utlllld|||ztllddtts}|zmtt{tt{{mtt|tt{}redv{lksekdleklksztllekuztdc\[[Tekdlek}lld{||[TTtlllddlek{ttut}}|]bZJHFF=C~|~|ēllk{tt}}lrittstsldc\tts|\[[[[Tkd\VTL[[Tr]gek]{ttlldllkut|ttszlldc\{||rfktsl|||tllllktzl||wl{||redsleSKJ{{t|zllsletsl{zmlekf]crg]vtts}{||sle|z}u{{{ttut}tt{}llkllk|lld{tt{ttultf]c|u}sre{|||u{ttllk{ttJHFtts{zmrg]{{t{{tjcVdc\sre]cd{{tutttsut[TTddcsref]clldultu{{kk]ztl}ultu{{|lri]bZlldfkkVZT]cdllk{tt|uVZ[mtt}llk{ttmtt]bZedkdc\{||fkk{u{lddzll{{tllultyfdredldd|||JHF*)(tsl~wl|vu{{}{||dc\uzt]bZ{|||tzllri}|u{tt{tt|}kd\r]gztltsl{||llkVTLtt{}uzt{||sre{{tsletsl|lddtt{{{kd\sre|ztll||{zm}f]cVTLztl|vsleu|}mtttslultd\\lksldd|ztts}tsl[TT|{zmdc\ztl{tt|u}{{tult{ttlri}zllulttll|uf]cult}sre|lddredSKJtslcbVtll||||sleVTLb[Uddc|tll{{tllkuzt|zSKJlri{||{ttlri{{kd\uzt}JHF|lri}f]c\UZ]bZult|}}lkslrimtt|zttsSKJlriuztedklks|||ttsttsrfkd\\{u{}}{||:97*)(}}}llk{{tuzttll||ztzllri{zm{tt{tt|utztltsl}{||{zm{||{{{u{|uzt{{tVTLf]c|z{||d\\{zmdkV[[Tddc}|u[[T{{{ttsle||f]c{u{}{tt|tsltt{ultzllddc{tt||{{tu{{ut|utll{zm|||wlv{yl}{ttsle}{{t{tt{ttlddekdut}{{tredkd\VTLsleldd{|||u{tt}|z{ttlldlriztl{{tVZ[tts]bZ{||}tll}{zm{tt{||ztlfkkrg]tt{mtttslddcMRKlkslri}tlltts{{{{}|{||ekduztttsedklrilks|lri[TT{{{u{||kd\{tttlltts{{t:97*)(||}}||}}}}}|u|z[[Tkk]|z|z}{zm||uztlu|z{||f]cttstll{{tkd\tzlf]c\UZ{{tut{tt|zekd}ttszlrg]u||}{||utf]c{||lddkd\tllsle|z||{||{tttts}|||{u{|z|z]cdtts{{|||ttsttsult{||ztlwlzll}{{t\UZ{{t{{tn{||wlldd{zm{u{mwzllbVUkd\lddslef]c[[Tredtlluzt{zm\[bj]\VTL|z{{tVTLlri{tt\UZek]lld{{tt{ddclddUMRlldztltt{ddcleklddf]cv{lksVZTf]ccbV{{lldddc{{ultvlksfkk|zuztlld\[[mtt{||ldd|ztt{}llklddztftts|lriVTL:97*)(}|}}~}u||dc\llk||{{tiq]|zuzttzl{{t|u}sle}ttstlltsluzttzld\\{ttlddrfkkd\{{tdc\{ttutu{{tllrg]UTStllsleultred|u{{t|[[Trg]j]\tllldd{{ttsl{ttzll|uddclld{{{||{||lek{{lldultmtt{ttdc\{tt}{ttuzt{u{}ztl}tslulttts|zultutrg]{{t|uVTLSKJkd\|||{{tztlttsd\\ztltllzllkd\f]clld[TT\UZultVTLsrelri]bZ{ttd\\:97{ttekdntt{ztljV[{u{VTL[[Tdc\|lek|{ttultldd{||lld}|UMRbVU}mttFD;llkuztf]clri{{ult{tt[[TVZ[nv\[b]cdtsllkstsluztf]clddd\\lkstsllek}bVUzll||tll|ddcb[U:97*)(ǜu{zmzll}|{||VZT|sleulttzlut|u{{|]bZ[TT{{ukd\sletsl{zm}{{ttts}{|||ddc{||SKJzllslesreUUY|u|UTS{ttVTLJHF|{u{{{taWMmtttsl{u{}|tzldc\uztut{||}{tt}ultut}||lek||{{llk\[[uzttlllldlks|u|z||}}||utll}u||z}VTLvek]tll{zmaWMlldVTLkk]rg]\[[{tttts{u{|u{{tult||[TTultbVUSKJ}dc\dc\{||ldd[TTlrildddc\|u||v{tzl{{t{{tutll{{t{tt}v{~}edkVZ[\UZVZTfkklldUUY{|||z]cdekd||mttlekVZTlksuzt|u{{lekf]clddultsleult||ztl{ttsreJHF74,}}||v{{{{{ttsl|||{tttslddcMRKuztsre\UZ|||}ztlulldVTL||{u{}lddf]c{{rfk~rr]}v{||}||tzl|z{||lks|{{|u||}z|{{t|tt{ut{tt{{|z|z||tt{mtt||u{{tztl||lek}lrirg]|z{ttddcwl|z{tt}dc\|u}wlcbVkd\ztld\\tzl{{tlldkd\tllllk{ttsred\\llklek}redkd\SKJekd\[[dc\\[[UTSsre\[b{{dc\rfkultult}llk}UMR\[[lldddc{||{u{|{{t{ttulttll}||z|tt{}MRK{{mtt{||tsl{||mtt|tts}{{UMRSKJred|lddd\\ttsu>B9:97}|}}}||u||usre|u{||}tlllrilritslultmtt|z|utsltslrfk{tt}|}kd\[[T|zkk]}redUMRbVUrfk||VTLldd{ttut|uut[[TVTLb[Uztlf]clksut}|zred|ulritsllekzll||z{tt}|||ekd}|tts||tsl~{u{sle{{yleut}|f]cttslriUTSd\\lldtsltzlllk{yfslewltsltll|lek|uuiWUslettsslelek||ultult|VTLztlkk]}{||]bZulddtt{tts{zmbVU}f]c|ttstsl{u{}lektll|zaWMlks{{{||}fkk|\[[VZ[ult\[bttsekdf]c{{{||srett{j]\|uj]\lddlddddclriJHF-1+slev|u}{zm|ztf}{tt[TT~|utll[[Tr]Zrfkult{||llk||UMR}}}tllbVZ{zm}tslkk]uzttslUTSmw\UZ{{SKJkd\ztfdc\{u{|uut||}lld{tt|z}|zll{{t||ekd\UZ{{rg]{zmjcVlldult|||lri||{zmu{{tsltt{llkmttUUYredu{{llk|zuzt{||}|dc\}||lksf]credult{{tsle{ttrr]tt{||||{zm{{twltllztl|j]\VTL|}vd\\ulttllultf]cuztlri{||[[Tztlf]cutek]ekduzt{{ztltllult|lritt{ztllek{{t|z{tt}{{{{\[[||lks|u{{{{VZTllkztlult{{t{{{{tts|tsl}lddbVUbVUtts{{tuzttslvMRK*)(wl{tt}}||||{{}|ljsleutyfl||{{}}}|}ultuztztl\[[vlldddc{ttut}ttsb[UlksttsbVUUMRj]\zllztfiWU}d\\}|utult|lddtslSKJlddred||i\V}|zv{}lldedktsl|uzllddclksztl|}{u{llkkd\~llktsltts}d\\{{tlldllk||||v{|u{{|srekd\{u{lek||uzt{{tddcttsfkkv{}UTS{{t||~uzt{||}kd\kd\rg]lritzluztzltts{tttll|{{||f]cddcut|lrif]c}ddcuztu{{tts[TTllk{tt{u{bVUlek{ttldd{{tJHF*)(zllwlü¿wl}|}}i\Vtslzllllk||tllekdlri}u{{tslelldlrilldaWM[[Tj]\}|zdc\ultutSKJ\[[VTLtllztlv{lekUMR{||\UZzllusledc\{{{u{ut{tt|ullkd\\|{tt}{tt|||ttsfkkv{tllleklks|z|||ult{{ult{||{ttlld}lddUTStsl}}{ttztff]cUTSd\\lri|tsllldVTL[[Tsre{u{lldtslddc{tt}slekd\llku}{tt{{t}tsl}|vkk]llkuztult}ultldd{ttttstts{zmtsl|||lkstzllkslekdc\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}{ttVTL}d\\uztyfd|udc\ut||}|f]c{tt|ttsUTSu{||kd\|sle}{tt}||||}}lektsldc\{zmtt{{{tt{|{{||bVZ{||{ttttsd\\[TT[[Tulttll~tll{u{||}VTL|ztl{||aWMbVUVTLSKJcbVlek[[TaWMMRKrg]{||}d\\v{}{tt{{tVTLub[U{tt\UZ{{tUTSkd\{||ult{{ttslb[Uult{{t|{{tbVU}lek\UZzll|tll]bZ{{t{u{tts|z}ttsf]c{{\[[\[b]cd]cd\[b{u{{{{{uzt|tslu{{{{utztlkd\ztllld[[TD;9:97wl|utult{tt}|ulld|ubVZuzt}{yf}lri}}ttsu||ztl|usrelddkk]kd\[[T[[T{tt|ub[Ured}ultv{|}|||f]cr]ZultcbVjcV{||ultred{{tlldrfklrillk|zrfk}}||||}tllu{{edk|zlld|utddcmtt||~jV[edkzlllriu{{tt{sleuzt|uult{u{rg]mtt|zu{tt[TTbVUb[U[TT3+*kd\kd\ek]cbVlld}ztl}{tt|uttslVTLtsl|u|z{ttv{\[[dc\b[Uddcb[Ub[Ulld\[[{u{lldultllddc\tsllekllk~sleuztlritslu{{ultlddv}}|}|{u{f]cllk}lddlekmttmttdc\tt{mttedktll|}lri\[[{{tuztutslezllkd\red{ttdc\uztlldUMR:97}ljlj}}sle}d\\|ztsltzl|uv||ztlttsv{{{uzt{{lld{ttdc\{{t|lldrfk{||||}||ulldlldbVU{ttv{yleek]{ttddc||]bZtsl{zmlddutdc\aWMddcttsredtll{{tzll{{tlddutb[U}uzt}{ttsle\[[||llktts{||lrifkk|rg]ult|ullk{||llk||ztllkd\llkuztf]c{{ttslsle|ztllultVTLj]\{ttrfk|ub[UvVTL|ulld{{tdc\|uzttslsledkVu|llk{ttv{tslrg]lldVTLlrivttsllkb[Ullkttsrfk{u{llk|z|{{d\\ldd|ulriuultf]cldd|tt{ddctt{{{edklri\[bu{{ultd\\lksek]lkslri\[[{tt}}|tlllddi\Vlriwlj]\||tzlVTLJHFwlv~}|¾Ʋtts}}ttslddtll{{utultlrileku{{t||ttslriulttts}ukk]SKJj]\ldd[TT}|ztt{||zllbVUVTLbVZ{tt{tt{{t]bZyle||d\\|{{t|u}sletsltlltll|ztllek{u{{tt{{tttsttsu{{ultttstllulttt{ddcllkulttlltt{|ulttsl[TTtlltsl||ultztlkd\|ullkkk]UMR}srezll|uyle}SKJllk{ttsreVTLuuzt{{tztl\[[{tt{tt}|j]\{tt|sletllzll}}LKRuztutljedkv{|uttslridc\|u{tt|utsltsl~lksttsf]cztl]cd[TTtzl{||mtt{{u{{UUY]cdkd\uzt|lriUTS{||d\\{tt{u{yleyleyleJHFkd\red{{t{{t}JHF*)(wlüü|||}|ult|rfkjcV{{tldd{|||zultj]\lldldd{{tcbV{ttwl{{tcbVSKJ|ukd\j]\lld{tttll}kd\tsluttyg|zdc\uttll}tll{{t}f]csleuzt}||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]{{tFD;74,~~}|||u{{ttsl}sretts}bVUddc}lek||||u{{ttsl}|z|u[[Tj]\\[[tts|u|mttultbVU}VTLcbV[TT}rfkekd\[[uztj]\MRKultrg]sle{{t{tt{||tll||tts|||zj]\yle|||z|llk|z{u{d\\|ult{|||z}}|[TT||ztl{zmrg]d\\ekdztlwltsl}||}ut}utdc\kk]}{{t|||ultlekkk]{ttsle}|yle||[[Tek]tzltllultultutb[Ulri\[[bVZwld\\sleultztl{u{}{zmuttll}|u|tsl{{tMRK{||{||lri{||lddekdd\\f]cddc{tt}{ttcbV|u{{t|u|uVTL-1+}}uzt{{t}}llkdc\uztfsrerg]lddttsulturfk}{{t{tt{||u{{tzllddultsle}}ttsVTLrfkf]cv{|lri{||{||lld|uztlkd\ztl|u[TTdc\|utsltllbVZ||}|tslsre|z|cbVkk]{||{tt{||tsl|utts{||{ttuzt\[[|lksztl|uekd{tt||f]c}dc\{||lldmttrfkldd{tt}|zll}|ztltll||{{t{tt{{t||ukd\kk]tslv|red}|utllztlddclri|z{||uzt}{ttzllztlddcllduzt{{ttll{tt}|zllultldd{u{lldr]g{{sleztl{{uzttsl|u{|||v|{u{{u{{u{rfklri|zulttts}VZ[|zlritts{|||z]bZtslsleztl}||vdc\llk}|ut{tt|z[[T*)(tllwl}ü}}}|{tt}ztf{zmuultb[UlldVTLrg]ultzlltsltllultslef]c}|zllk{{tztlbVU}tll\UZJHF[TTtllllk[TTldd{u{f]c{tt{||sleulti\VVTLVTLkd\ztlekdcbVcbVttstlllddtllut}ldd}}ttsult||{tt|f]c{{t{{}{{|znv{u{||ult{u{|}tts|rg]{tt|jcVSKJjcV{{tf]c{zmtsltzltll\UZzll||}ultv{|u}|||}{||zllf]cdc\tsl{{|u|[[T}{||}|ek]~|slef]cmttzlltllbVZSKJ{||||{{{{t{||\UZv{{ttlekutztl{tt}VTL}{{tu{{ultult{ttuzt|z}{ttb[U|utllyle{ttutv}sreD;9*)(}||v}~sre}}|||}|zltsl}tt{v{}VTLultulttt{|f]c{||kd\}srebVUbVUult{u{\[[sleultlld||b[UtslbVUSKJFD;]bZSKJsrekd\[[Tlddd\\ztltzlttskk]sleut|u{ttvztl|||z|zlksf]ctt{fkklksUMR}tsl{{lldleku||||lldsletslb[Uztfldd{tt{{t{{tlldultcbVut|u|uult}j]\{tttts|vrg]tll{ttd\\uzt{{tuztrg]bVZlddlddtts|u}MRK|tslrfkv{UMRbVZ}}|{{tll{tt}sretts}f]cut}|{{tdc\dc\}||||ddcf]cf]c{||{{ut}zlltllredj]\|utslj]\red||ztlJHF*)(~utüütsl||ztluztztlutkd\rfklddutJHFuzt{||{||uzttzl{{t{{lrizllrg]{||lddlrijcVttsv{ultf]cSKJtll{||}|{{t{tt[[TUTSVTLj]\llklddlksttsv}{||r]Zekdddc|||ztl{||||}j]\{ttllkuzt{{|u{{{||{{lksedk{u{tsl|z|zttslks{{tkd\lksttsedk{tt{u{{{tultllddc\redredut{tttts||ttstllkd\yfdzll|uultdc\d\\{tt{u{}ldd{{tttsv|lddllk{tt}|usre{||tsllddlek|uUMRultbVZtts[[T{u{||tsl|tllult||ultbVU{{td\\[TT|tzlfkk}sre{||lri|uldd{||{||||}|{u{wl{zmtlld\\utwlv|rg]rg]FD;74,}zj]\ü|zv}||{{tslellk{{t||{tttt{{tttts{zmztl||tll||}|||zlddtts[[T{{ttzlkd\{tt{u{[TTd\\[TT}{tt{{tddc[TTd\\ekdrg]kk]bVZllkldd[TTtzllritll[[Td\\b[U{{t{tt{{ttts}|}}|{u{||u{{{{tllktt{{{|}tts}|vtt{}|{u{tll{u{{u{}||llkdc\red}zf]c}{||ut{{tUTS|utllsreyletts}|yfd{{t||sleyfl}{{tut}{{||v{{u{}v{VTLv{{edktllf]c[[Tslelddllk{zmu{{ultztlrg]{zm{{t|tll{{t|]bZtt{|zlek|}ddclekd\\kd\llkddc{tt}|uztldd\UZf]c}|v>B93+*||ü}}||ztt{u~lld{ttkd\tts{ttlldj]\tllv{f]ctsl{tt{ttrg]ddctll|}|llkiWU]bZtlluzttsl{{t{||ultlekdc\}|JHF{|||ttsrfktllJHF{||v{srellkddckd\b[Utslslekk]d\\{|||lekyleztl}ddctts}u{{uzt|zuztddc\[[|z|}\[bf]clksldd||}}}|j]\lldi\V{{tzllkd\ldd}|i\V||llktlllld{||llk}|b[UbVUutbVZ{ttsrettszll}ult||{tt}lek{{t}[[Tddcttstlledktll{{|}srecbV{{tsreu{{kk]tll|vzll|u||||ult{tt|{||{||n{u{}ult|tsld\\rfk}|{zmtll{zm}|zllyleztlkd\kd\:97*)(}u|||ztf{u{yfdut{zmulddtslv{}}}llksle{{|uldd}tzl|uddclri|FD;d\\u{{]bZllkd\\rfklddlddsrezllSKJ}tsl|zsleVTLtsldc\|lddsleVTLzlllldrg]srelddultd\\{u{||{tt|uztl||mttllk|{{|}||ddclriuzt{ttlkslekUUY}||kk]ldddc\}tllsrekd\bVZultlldv{bVZbVZlddlri~kd\v}{{|}|f]clddultldd{||llkd\\kk]{u{v{|||||{||tsl{u{VTL{zmbVUddcttslriztltllUTSulttsl|vttsrg]||tslv||kd\[[T{{tll|lek||{tt|vutztfzllsle||kd\wl:97*)(lddut}}{{tuut|u||}ttswlv{{{t|u|u}|sle{||f]crfk{{t||}zll{||d\\rg]redlddztlllkf]c}rfk[[Ttll}tt{j]\VTLkk]lldslettslridc\||tll}dc\tyg|ztllddj]\mtt{zmut{{t||f]cv{tlllddd\\}}ekd|{{tt{|z{u{tlllek{||~{{{{tllkleksle|zsle|u{ttllklriredkk]VZTzllredbVZ[[T{{t{tt}ultddc{tt|utredrfk{u{{{{||}lriztl]bZ\[[utVTL|lldlriddctsl{zm[[Tf]ctsl{tt}v{lek{||bVZ}{u{ztl{{tkd\uztuzt|z|{{||ztt{ut{||{{t{zmlldlldd\\sletll|uzllldd}|yle|}>B9&&~{tt}u{{t|||utrr]redtsl{u{tsl}ztl}|{{t}{{t{||zllsle|tll}}ult{tttllsleultllksrettskd\\[[tllf]csreztld\\ttstll}{{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]\ttsUTStts{u{{||{tt~ult}|uztttszll{|||u~{zmztl|zllsrelri}|zekdekdslellkldd|u|u|tzl|u{zm|{tt}|vredkk]i\VD;9*)({{t|v||}u|uutztl}}yleb[U[[Tzllf]czll~{ttulttsl{u{kd\{tt|zkd\||zll|ultlldzll|v}|sledkVv{dc\dc\{tt||}lridc\kk]mttSKJ{{trfkFD;sre{{ttll{{t|[TTb[Usle}b[U{{tsre||tll{||tll}~v{||tt{lldultuztmtt{{{{{{lrilks|z{u{uztult||}ttslddlks{u{{{tvu{{{u{|}yle{||tsl{{ztlkd\d\\f]cuzt}tzl{||bVUrg]}|v{tttslkd\}|||{u{{ttrg]kd\[[Tlldtsl]bZult{tt{{sleztlztfztlut}|||uztlsle}lek|zwl}tll}ek]{||{||tsl||{||{tt||JHF}i\Vutztl}|wlredFD;*)(v|}ut~vldd{ttubVU{||tsltll{{t{||ultuztttsu}|{tt{|||u}lri}sleldd}FD;{||ult|z}lri{ttttsllkekdu{{lldb[UlriutUTStygtllsreuzt}ztlsre[TTaWM|zztlrfklld||}tll}tll|||zlkslrilek]cd||lkstt{}fkkllk{ttultleksle{{{{t{{t|z}{u{ultrfktsltt{rg]lldutUTSzllyleslekk]{{t{||lddutlekf]c{u{{u{r]g||||{|||}tllredtzlsleVTL|z{{ttllttsllk{ttv{||]bZ{{vulttsl||}tsl{{t}}mttmttu{{{{tlddlldtzlllk{ttj]\lddsle|||uztlsletslrg]JHF*)(~{{t}}|uzll}{{t}|v|z}{||srelri}}}|u|z{{}{{tyfl}slellkr]ZbVZllkred{ttddc[[Tlld}lldlld||tzltll[[Tddc{||rg]dc\b[Usresleslensre}{{ttll|lritzlzlltll}tts{{ult]cd|z{{||u{{|mttlriultuzt{{ultf]clks\[bmttultlddztldc\kk]{ttut}llkddc|sre{ttutzllztl{{{u{kd\d\\ut{u{utred{tt{||ztltllkk]\[[lri}ult}uztwl|zmtt}tt{mtt]bZ}tts}sretts{u{{||v{ztl[[T}zl}lldttscbVlldttssrerg]sle{{tutztl|ui\VzllutllJHF!¾ƣu}{{t}{tt{{tttsztl|u{|||lld}tsldc\dc\kk]tsl|ut|||}zllllk{u{{ttb[U}{{ttsl{{lribVZlritlllriVZTUTStlluztf]c}mtttslkd\||vuztyle{zm{u{JHF||||{zm|}{{||lkslksekd}|fkkdc\ulttt{|lddd\\tsl{u{tts|uVTLn}ultf]cult|zlks{{||ztl|u{{tlekttsldd{||lddrfkbVZdc\{{tu{{tll{{t{tt|ut}||z}|u{zmkd\u{{ztlrg]||llku}}|||}{ttlri{tt}|}{||sre{{t|z{{t||sletsl}{{t{{tztl[[Tu[TTsleultb[Uztl}|{tt}v{ult>B9*)(||v{v{zlltts~dc\lekylev{{{{{ldd{||{{td\\[[Tuztllkn}ulddsle|zztlu|u||tts|ztts{tt|u{{t[[T\[[|||ldd}|tts|||}|sleslejcV||kd\tzltts|u|v}{tt{||{{{{}{{tslmttmttmttmttuzt\[b\[[{||lddlekultult|rfk{ttldddc\}tsllldttsldddc\[[Tlldlld{{t{{[[TbVUkd\ttslddedkzll\UZd\\tll{||uztlriultzll\UZ{{ttyg[TTMRK\[[llk\UZ{ttult}wlkk]||ttsztldc\{{tulld||tzl|z{zmkd\|lriiq]lldtllsrebVU{zmztlztl}|utllyle}D;9*)(}wl|wl||kd\{{t{||{tt{{tu{||{{trfkrg]}}{{t{u{wl|{tt{u{d\\|uztlu|ztl|SKJttssle}bVU[[Tultllkultlks|llk|u[[Td\\tts|u{{t|u|u|u{{tf]csle||{{tsleztllldv{ztltsltlledklld{{{{|ztt{|mtt{{mttu{{{||{{llduztd\\\UZlks[[Tf]clld{u{llk{{tlddcbVultlddult||}dc\{{t{tt[TTUMR{ttb[UmwVTLrfk{u{VTLSKJ{tt{{tv{vredldd[TTtsldc\|utsle}z}ekdllkllkldd{||{{uzt}sre}|vlekllk}|zll}||tts|{{t}|ztlb[U|{tt{||{{tlddtts|uutztl||ut||wl}:97*)(||zutll{||tts||f]cultttssleb[Uvu]bZ[TT|zddcb[U|z|u|tsl}kd\{zmv{||llklddsle}ultttsb[U}cbV}||tlli\VVTLSKJkd\tll{{t|uyletll|u}|utslsle{||b[U{tttsltsldc\{u{{ttlks{{{||uzt{{mtt|mtt|z||z|{||llk{ttlek{||{{d\\bVZbVZ{u{|z}|uzlulttlluztdc\redUTSztfkk]SKJ|lekkd\f]ctllVTLmttd\\tsl|||u\[[kd\{||{ttsle}ldd{{v{}lksmtttllsleultztlultUMRlddutllkuztttszllsre|}|u}}lddztfsre||]bZred||u{{twlztlztl||tslwlJHF*)(Ƶ}u|v|u}yle}||uuztmtt{{td\\||u}{zm|u||u}|{||f]csresre}ultllksle{||ultultuztlldd\\{u{VTL]bZ{{tsre{zm}JHFSKJdc\dc\|uztf[[Ttllkd\|u||}}lldkd\ztlj]\{tttsl{{t{ttttstllddclddlekmttu{{mtt|tt{{{{{ttslkstt{|}||ttsf]c}bVZylelri|zsre{||kk]{|||uldd|zkd\rg]|vsreztlrfk|}rfkztlkk]b[U|u}zlltlltllf]c{{trfkrg]rfkuzt|z}{u{leklektlllek||ttsmttut}|vzllnllk}|ultf]c}|lddtsl{u{}}tll{||}wl}{{t[[Tdc\tlltsl}|u|||u}{tt~ztlD;9*)(uut}lldwl{tt{u{zll{{ttts}MRKsre|z}|udc\||{{tlriuut}|utsl}|||zll||||ztld\\ddcsre\UZ{{t|}|u{{tdc\j]\f]cVTLslelddttsuzt}}b[Utll|vyleztlkd\kd\wlf]ctsl}}d\\||}{ttllktts{{n{{mttlkslksultlek|mtttt{ult]cdv{bVZ{tttt{tsllld{{tzl{{tutslf]cj]\llk{{t{{tut{{tu{{tlek{zm|urfklks||kd\}|SKJf]ccbV||sreldd}slesletsl|uzllttsultlriekd|{tt||{tt{||{ttrfk||}{u{}tll|ud\\|u[[Ttsl|usrekd\lld}lldrg]u|v{kd\||r]Zsle|uredredVTLcbVFD;*)(|v{zm{{t}}{{tu|u{u{||{{taWMllk|{{tredllk{||ut{tt}tzlSKJJHFVTL{tt{zmb[U|ult{ttutldd[TTult{ttd\\slej]\kd\|zudc\slelddkd\f]ctslb[UJHF|tts{u{dc\{tt|u}llkvtts|lddtts{{ttslcbV||{{t}ttslks||{{{{VZ[]bZfkklksleklkslrimtt|\[[\UZUUY{ttldd{u{{{tcbV[[Ttllultldd{||sretsltts{zmkk]lld}||{||ud\\tll|zv{kd\b[Utzlu{{tsl|ztsl||tll}{{tkd\|vVTLlldslelri{tt{u{lksmtttt{|z|}||{||tsl{ttult}{||uztkd\||}|}bVU{ttd\\ttstsluuzttsl|{||{{tuztf]cult{zmzlluzt}ztlrg]d\\j]\tllrg]rg]}|||{{tztlUTS*)(}|u{ttrfk{{tztltll{{t{||rg]{{t{||zll|z||tts{||{{t\[[llk|u}||ztygv{ttsj]\}||u{u{bVUztl}VTL]bZlddllk\[[UMRtll[[Ttsl{||dc\{zmlrij]\tll{zmtsltlldc\{{tztl}{ttkd\VTLlldbVUb[U{{t}|}rfk}|VTLsre{{|tt{|{{llknv{||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{{lrizllzllsletts{ttv|z{{tlddj]\ztl{zmslesle|}ztltsl{ttSKJlldek]v||sleutsleSKJ*)(}ƨ}{zm{zmtll}|||tll{u{lld[TTlrisle}|{{t|zek]{tt}|usle{{tlddzll{tt||{ttkd\{u{{{tttstts}lldSKJ]bZuztkd\tsl}{{ttllVTLd\\[TTD;9{{tlldv{sre{||kd\ztldkVkd\|b[U{{t}ztl|{{tlrislelksmttmtt{{VZ[{{fkkmtt{u{ulttsllksd\\d\\llk|ukk]sreuztttskd\tt{\[[lldredztl{{t}llksle|utll\UZ||ult{u{{tt{||dc\jcVtslult{{t|u{zm{{ttts{tt{u{j]\d\\edkekd|{{{||tts{{}u{{{{ttts}uzt|{ttv{|{||{{t}ttslldttsult{{t}lridc\b[UcbV|llkkk]|utsl{ttutztlrg]ddc||redD;9:97wl}||}}{tt||||{tt|uuztrg]llktts{zmultb[U\[[[TT{||kd\{||{ttsled\\||uv{tslj]\dc\sled\\||kd\lek{{ddcldd\[[dc\[[Td\\f]cslesle{ttb[U[TT]bZrfklddut|bVZj]\ztlztl}|kd\|z{zmztf|z}}rfktsl{|||zkd\tt{{{lri{ttlri\[[|mtt{{]cd\[bttsf]c{u{lks{{f]cddc\UZ{|||lld{{t|kk]kk]{{tlrildd{{ttllddcult]bZ~uzt{{tb[U}f]cf]c{ttj]\{ttsresle|ulddult{{ttts||u{|||u|zultUTS{ttttsttsf]c{{{u{ztl}ut{{{||}{||lrizll}uu{|||uuzttts||{{ttsluzt|||sre{{twl{{ttslztfkd\ztl}|sre||{{ttsl{||FD;*)(vvu||redredu{u{||}{ttztl}{||}lld{{tred[TTldd{ttslelekrg]sledc\tsl|||}tllv{[[Td\\|uztltll{||}uztf]c]bZlddb[Ulddd\\{u{{{tutulddvredVTLkk]lddbVZ|usleldd}|ldd{ttllk||u|u{{t}{||sleutztl||lri|{{{{tt{]cdult{{mtt{{|tt{edkf]clksllkekdmtt{{tlks{u{lek\[[d\\ek]lldllkkd\|tslsreldd\[[d\\sle}llktslsleddclddtt{utv{{ttultldd|uVTLkd\UTSu|}{tt{||uztldd]bZtsllks{{{u{lksult[[Tlektslllkuzt|ztzl}lek}|zlld{u{||b[USKJd\\mwFD;[TTllk|ttsudc\{tt{zmek]llkcbV[[T}{{t]bZtllsre{ttjcVyle}sleSKJ*)(}|}{ttlld{ttlld||}|z{||{{t|z{{ttts{||ult|u}|v{zmtygrfk{{t}|{tttsl||zll||ztl}{ttldd[TT}{{tddc{||tsltlltsl{u{ek]lektllrfkztl{ttlddkk]kd\ddcf]ckd\b[Uekdd\\zllaWMMRK||{||lri{ttj]\{zm}{yf|zkk]}{tt}uztddc||zlksmttuztllkmttf]c\[bultekdlksult||iq]b[U{u{}{u{\[[ldd{{t{{t[TT{{tlldtsl{zmlld}dc\sleddcd\\aWMlri|{{tVTLlldtllr]gtt{}lddd\\tslutddcztlddcb[U{||[[Tlld{{t]bZ|||u{{{||\UZ\UZSKJkd\ekdtll{tt|zf]c{||lksfkktslttsb[Uf]c{||v{{u{{ttllktsltllaWM|z{tt{||ztl{ttj]\tsl||dc\dc\lri{zm{{[[Tred|u||lldtslsre{zmtsltllcbV{ttkd\ztl{{t{ttmttlddD;9:97||uzt{ttv{|{u{|u{zm|z||{ttultlri|z||z}||{zmtsldc\red{{t||{|||slered{u{{ttredlldslelddlekj]\dc\SKJslelritslb[U{||ddcuzt{{t{{tldd{{t[TT{tt{zmSKJ|utsle{{ttll{ttztlv[TTslelrilld{ttj]\}|kd\tslllkztlbVZtts}{{tdc\lkslksddc{{{{llkmttu{{ddc\[[UUYUMR{{{{uztmttlddlekdc\ddclekllkult}lrilddlriu{ttd\\lek{{t{||ztlldd|zkk]VTL{u{j]\b[U\[bd\\[TT|ub[Ured{||[TTllkVTLb[Uredb[Uj]\]cd{||j]\tllttsekd{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|uztl||{zm|wl}{{tlks}{{t{|||zztlsredc\sre{tt}|ut}{{tzllekdttslddllktll{||kk]{{t|uultulttll\[b]bZbVU[TTtslf]c{||tsltlltll}lldkk]tlld\\kd\j]\|uFD;tll{ttsleVTLb[UlddVTLztl||ttsultkd\cbVdc\{zmusletts}tll[[T]cdslelks{{{{edkddc{||u{{mtt\UZ\[bJHFVZ[lkstt{ddclks}lks[[Td\\lekllkf]ctts}VTLtslttsbVZ[[T[TTzllkk]||mttzldc\lks||VTL\UZSKJd\\lekkd\zlllddlldddcSKJVTL[TTtsl}\[[dc\tslVTLVTLlrildd\UZlldd\\{u{llkllk{ttttstllbVZlkslridc\uztmtt}lektlluztlekj]\b[Uu{{d\\{tttts[TTVTLtslVTLkk]ddc|uddc}{{t}tll||ekd|[TTdc\lld|uultttsf]c{||kk]sredc\kd\lddztlddcb[Uutlld{tt||sleJHF*)(}|uu|{tttsl{{tt{{ttsletsl{{tzllztlllk||UTSkk]dc\ekd{ttlddtslulttsltslkd\|z|zkk]{||d\\{||lddlri|utts}ttsSKJddctllult[[TVTLSKJllkJHFSKJ\UZdc\ldd|tsllldtslb[UUTS[TT]bZVTLj]\b[UVTL{tttslVTLzllztlztfldd{u{lrilddJHFb[UVTLkd\redtsltts||{ttllk{{tsllldUTSttsekd{{]cdf]cllktts{{\[bfkkVZ[}u{{lksddc|{u{{tttlledkuztlekutuzttsltslVTLtt{\[[d\\[TTekdj]\{{tlddkk]tzl[TT\[[d\\b[Umttllkllkldddc\\UZlekbVZlldtllzll}tslj]\[[Tdc\lldttslldllkuztkd\edk\UZVTLb[UJHFf]cUTSu{{ddcb[Ukd\UTSlriuzt]bZttslddMRK{ttUMR[TT{ttllk[[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]lldtsltslu{{sleedk[[TVTLrfkf]credkd\kd\]cd|zsle}lldtts{||ekdf]ctlllld|zslelldtts{tt{||tllcbVzll[TTdc\d\\{u{]bZbVU{tt\[[VTL[[Tkd\\[bb[U[TTtllslekd\|z[TTutztl\[[b[Usletsl{||tts[TT[TTlld|zd\\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{ztltts{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||uzttts{||{{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[[Tddcu{{{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\\[TTztlJHF*)(||{{ttzl{||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{||{ttttsdc\uztllkttsu{{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;\UZJHFJHFSKJSKJSKJ*)(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|ztlv{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;9VTLdc\[[TVTLjcV||SKJ>R.VTLJHFGSu]cd|z|zlrityglldsreD;9SKJsre{{t|u{ttlddf]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\\lriowd\\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;9SKJJHFVTLJHFvu|u|vlricbVJHFtsl\[bSKJ7-2[TTuzt|lldllklrib[UJHFb[Uultult[[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[TTVTLtllllkSKJtsl{{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;lddJHFv{fkkVZ[VZ[\[[slelldlkslriJHF[[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;9lldbVZJHF{zm}{ttlddMRKmttiq]zl|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]cv\UZkk]jcVVTLMRKVTLsreUMRFD;UTSlekllkUMRUTS]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,SKJlldf]cLKRuslev{JHFVTLsreFD;ZbNlldf]cmttUMR{{ekdttsttstll{|||{||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]cv{lekUTS]cd>B9MRKVTLVZT{{tlekfkktlltts{||]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]bZtslek]JHFzllf]clri]bZztl|g\rq^è|~tllultuztddcf]c{u{{tt{{tuztutllultfkkf]cSKJv{dc\{u{ddc}JHF{{lrid\\|z\[[UTSUUYlksJHFddcD;9edkVTL:97lld||{||ttslldldd[TTUTSj]\b[UVTLSKJ:97{u{lddSKJrg]b[Ullkllk{{t{{D;9JHFMRKVTLUTSuzt[TTddcD;9:97sle[TTdc\SKJHR>SKJrfktslmttJHFdc\ttslrilri|z|lek{{t~MSSmtt^fsfkktt{mtt{{\[b{||[[T\[bultkd\\[bVZTmttlek~mtt{{mtt{u{JHF[[Tdc\|llktlltsluzt{u{ultllkJHFUMR]cdcbVVZTddcF=Cb[U||tlltlllddlld{{tdc\mtttll}zlldc\d\\SKJ[TTlekrfkbVZwlaWM74,JHFlriD;9ddctllekdttszllu{{u{{VTL{zmb[U{{u{{tllutll]bZ]bZztlcbVultUMRF=CSKJiq]MRK3+**)( *)(JHFredsleb[Ub[Ukk]cbVtslVTLFD;ZbNdc\jcVztfFD;]bZbVUtslb[UVTL[TTtsl}VTLZbNkd\rg]j]\{tt|vcbVFD;tll|z>B9SKJ}}]cdjcVmttkk]ekdultǜË{{{u{{||}ztl{{|uttsllk\[[b[U\[b]cd|z{u{\UZ]bZlkslld}{||llkVZTMRKF=C>ECrfk[TTMRKttsJHFlddllk|mtttllj]\redUMRJHFSKJcbVVTLFD;ek]dc\j]\lldJHFlekttsuzt]bZSKJ]bZult|u[TTUTS]cdVTL[[TsleVTLD;9aWMVTLtll{{tuzttsl{||lri|zzlllksOS`]bZlks]cdtts\[b~\[bddcUTS{||||{ttddcedkzllf]c{{fkkUMRttsJHFllkVTLlddztl{ttttsdc\lri]bZddcttsVZ[JHFrfkf]cllk[[TSKJ}lddrfkjcVslekk]lld|||SKJ{{UTSv{\[b[TTb[Uuzt[[T\UZkjVJHFD;9VTLllkbVZ{{ddc\[[\[[|lldddcrfktzl{||b[UFD;d\\VTL{ttd\\UTSFD;\[[FD;&&%74,>B9uzt{tt{yfztl{zmb[UaWMSKJVTLJHFVTLVTLVTL|zkk]VTLkd\lldbVUSKJ[TTkk]sleaWMVTLkd\SKJj]\tllutd\\ulektslVZ[SKJzllv}aWMtts]bZUTS|}}]bZdc\|d\\ztl|tts{zmj]\f]c{tt}\[[\[bf]cf]c}|||mtttyg{||UUYtt{ttsllkUMRUMRnv\[[}ddctt{{{t{{t\[[lddUMRredkd\lldaWMb[Urfklddsletllldddc\lldvUTSJHFuztv{tllkd\||LKRJHF]bZb[UuMRKUTSkk]JHFbVUdc\{{sleult|ztts{{t{{tulttts]cdMSS>ECMSSlddmttf]c}ult{{t]bZdc\f]cSKJf]c[TTleklrif]ctts]cdD;9MRKFD;[[TSKJbVU[[T{ttlld|\[bekdlritslUMRlldttsbVUtts}|||ulldiq]{tt||lkslektll|vFD;JHF\[[dc\ultlri}llk{||tts{{{{b[UztflldddcUUYiq]zlluddctsl]bZf]cultf]ckk]\[bC8.D;9]bZJHF!FD; 74,VZTtllwllddwl[TTSKJrg]C8.dc\sreaWMaWMPF=JHFFD;{ttSKJSKJ[TTVTLek]i\VSKJVTLVTLSKJ|ukd\VTLsrellktsl\UZ3+*}||zrr]tzlrg]ekd|zlldvut!VTL{yfu{{|rfk[TTlri|uj]\|zLKR{||tt{|FD;}||lks}ultlri{||lrif]cuztedklksf]ctllttsllkUUYVTLdc\dc\SKJ[TTd\\llk{||||SKJsle\UZf]cylemwrg]ekdddc}VZ[JHFVTL{{tslekk]tll\[[ekdd\\VTLb[U{ttSKJkk]kd\{u{|uldd{zm{ttu|z{ttlldultyltzlddcMSS\[bMSSUUYddc\[bMSSlks{{mtt\UZlld{{tsl{tt||f]c]bZ~ultfkkztfMRKMRKtt{SKJr]ZVTLj]\sle{{tlkskk]ttsdc\JHF]cdlritll{tt||ztllldtts}|f]cf]culti\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{||vvu|v{{||}*)(&&nddc|}||VTLD;9tll|u{{||SKJtzl{zm\[[ztf}{||VTL[TTb[U{{tztl[TTSKJUTSMRKf]cUMRllklddultlekddcztld\\VTLwl\[[rfkkd\}|{||b[Ukd\red{u{iq]|u[TT|tslekd[TTJHFD;9[[Td\\|usle{||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]cbVZztftzlred~{zmsleFD;sletsl{u{ddcJHFUTSSKJf]crfk\[[d\\JHFJHFlldMRK|ult{{tll{u{{{ekdsletslmtt}|||}|z|zzl||lks}UMR\UZlekb[U\UZJHFVZT?;C3+*:97SKJ|u}ztlrg]r]ZcbVd\\SKJi\VjcVcbVcbVVTLVTLaWMztl[TT[TTsrejcVredb[Utllred{ttredrg]cbV[[T|\[[:97{u{Ɣ]bZ{{|lks}|dc\iWUred||tslredcbVf]cfkklri}|lri]bZldd\UZj]\lddllduttslekSKJUTS\[[{u{rfkbVZJHF[[Tllduztwld\\[[T\[[tll|u||{{tlldf]cutb[UUMRztlbVZ}JHF[TT\[[uztdc\|u}\[[srelddkjVnVTLaWMj]\VZTllkd\\ekd}{u{{u{[[T}{u{f]cMSSn{{~ttstt{\UZJHF\[[|z|zultlekf]cvddcekdJHFmtt{tt}|{tt{||SKJkd\|ztzluztkd\j]\F=C\UZSKJ{||{u{kd\uttlltllult{u{ztlwl\[[{zmuztl[TT\[b\[[\[[llklri}UTS\[[tll}|mttiq]FD;]bZut}ddcVTLddckd\{tt\UZtsl||tyg|f]cUMR\[bd\\|VTLUTS>B9JHFUUY3)JHFj]\|u|uslecbVdc\jcV}aWMSKJb[Udc\rg]nrg]d\\rg]lldb[UztfaWMSKJlldd\\||VTLdc\j]\¿VZ[JHFtslu{{]bZ}~^~Y3+*}|zVTLiWUyle|z}|slesle|}\UZ]bZ|ztzl{{llkmttj]\dc\{{ttsltts\UZttsJHFSKJd\\lriult{u{{tt||UMRd\\ut{tt}lddldd[TTut}ultkd\lddttstllUTSSKJUTSddcb[Ulri|z}lrisresreJHFldd|{zm\[b{u{f]clrilri{||uzt{{{{uzt}\[bJHFVTLfkk|z{{tult}lriwl{u{tsltygmttlriVTLmw~sle|zbVU{zmVTLf]cbVZldd}|v{zllf]cSKJutult}zllllkcbVkd\{||b[U}}SKJSKJllk]bZekdd\\f]cFD;VTLaWMcbVj]\ddc{u{\[b~d\\ekdFD;|z}|}}tt{D;9lksJHF:C+MSSJHF MRKttsi\Vlld{{tkd\f]crr]rr]ultzllkd\VTLrg]VTLrg]j]\|uj]\FD;sletllu\[[{yf[TTUMRaWM}|VTL|u|u¾UUYJHFnVTL}JHF{{LKRr]g|zkk]kk]|{||d\\lld{||{tttsl}{||]bZ{{redtts|ldd{{lek]bZbVZlks|{{tllk|||z|u{tti\Vredd\\|j]\\[[tsl}[[T||lks\UZtt{slev}|z|uf]cuztek]ztlkk]tslSKJ\[[{zmztl}{zmuztfkktt{{{tts[TTUTSlld[TTtts|mtt]bZtt{ekdtslllk}mttd\\UMRekdtlltllleku{{MRK]bZ|kd\|zkd\wlcbV|ztslekdlddttslldyleultzll{ttutSKJzllttssle{tttslldd|{ttultlriuztVTLJHF[[TUTSFD;JHFkk]rg]|ztsl|z|z{tt{{td\\tt{fkkVTLredtts[TT\UZ:97SKJVTLFD;:97%:97\[[dc\llkztlb[UjcVd\\kjVd\\aWMdc\VTLPF=SKJylelddVTLSKJVTLdc\{zmrg]{yfrg]bVZjV[zllwl{{t|u||\[[74,ldd}rr]b[U}j]\lj}:97SKJztlnjwl||llk~{||v{kk]{{||{zm}{ttmtt[[Tf]cldd}{u{tllmttllk}tts{{tsl|VTLut|z{||rg]}{||sleVZTFD;red|vztfsle\[btsltts{ttldd[[Ttll||u\UZultlldkd\cbVztlj]\bVUlriuzttsl|}{tt{{JHFiq]llk[[T{u{{{|mtt{{ttsekdVTLddc|ttsj]\~ddc{ttf]c{||]bZMRKmttu{{|z}{||tslllk|utsltts{tt\UZ{tt|bVUllkredrg]}ut|v{ttutbVUd\\VTLtllttslks}}¾Ɯ|f]c{ttdkVkk]jV[llkf]c{zmfkkVTLzldkV}|UTSekd:97r]gUTS:97ultedkJHFD;9dc\,553+*[[TD;9JHF[TTUTS|u}{{t||zll{zmutrg]rg]kd\SKJVTLVTL[[TVTLVTLldd[TTVTLsreusreiq]VTLsleutred||lldwlztl|\[b:97wl{tt}|}zlJHFjcV.1SKJŲultf]clldv{||v{|tll|u|z|wl{ttrfk}ultlritsl}tzllrilksSKJf]c{tt}UTS|zred{||v{tslutb[Uztl{||[[Tzllkd\i\Vldd}ultuzt||tllb[USKJ[[Tllkv{yleldd~[[TMRKkk]d\\SKJkk]j]\}{{tult}|tslu{{uzt{||v{{u{{{|LKR\UZlddllk{{{{lksnvmttUTSVTL]bZtt{llktll}}|tslMRK]bZ]bZiq]]cdtzl[[Tsre{zm{{t||ztts||rg]f]c|v{dc\llkSKJv{{tt}llkztl|ztslztf}j]\rfk}sle\[[ultekd{{{{lrizlJHFtzltslyle|b[Uuztlrilrilld|ztt{]cdlrisreztlf]c{{tll*)(SKJkd\VTL3+**)(D;93+*JHFJHF{{tztl}ztfVTLSKJjcVVTLSKJb[UVTLkk]jcVwlj]\kd\i\V[[Tkk]u{{ttslZbNzllr]Zzllyle[TTkd\{{tLKRLKRf]c}}tt{j]\JHFUTSldd]bZ|u|z{{tred[TTslemttmttuzt{{t|z{{t|{{{{t}{||{||ultlld\UZllk{||lddb[Ud\\v{uztutlri{||dc\jcV{{llk||{tt\[[kd\{ttb[U|tsl||sleSKJr]glldf]c\UZVTL}|{{tVTL{ttlksSKJtsl[[TJHF{{tlrimttuztuzt|z|ultllk{{{{lks{{}|edk{{|{||sleddcddclld|f]c{tttslVTLVZ[tzltsl{ttddc||z}ut|mwUTS{{tslelekv{}}ttsutsre\[[b[U{tt}{{tslelksd\\ldduztmtt}[TT|zttsJHFz}llk|{{\UZek][[T||tlllks|mttSKJzllekd\[b?;CFD;"[TTslei\VsleutVTLrr]bVUPF=VTLjcVd\\lldVTLsrelddi\VVTLSKJwlzl}|lrirg]b[U{ttbVUut|v|ukk]|zVZTUTSult}zrg]uj]\j]\bVUMRKSKJ{ttutztl{{t|z}|usleu{{{||{ttu{zm{tt|{||}{ttlri|uv{d\\lek\[[]bZ[TTf]c}uztbVZ||wldc\lddd\\{zmtlltsl{ttj]\ztfkk]SKJ}|{tt{ttJHF[TTd\\ultekdJHF[[TSKJ\UZdc\dc\SKJVTLultult|uu{{{u{||z{tt\[b\UZultlksu{{{u{kjVu{{\UZJHFj]\]bZ]cd\UZ{tt}tzldc\{{t{||sre|z|uredf]cSKJllkf]cVTLJHFSKJbVU~ylebVZFD;kd\{yfd\\{zmzll|rfku{{d\\r]g{{tf]cJHFultf]c]bZ]bZek]{{t\[[{{{{llkf]cslett{edk{{tldd|u|jcV{||ekd\[[VZT[TTF=CFD;74,lldf]ctllwl|utVTL[[TVTLb[UVTLb[Ulrikk]bVZddcSKJsle{ttVTL{zmu|ztsllldlddtllv{rr]wlztf{{twlfkkMRKtts}|tzl}jcVVTL|zF=C?;C}tslsle||z}u]bZ|{{t||rfk{u{tsllddekd||d\\}lldllkbVUzll|z[[Tsreultulddtslwl|u{{ttslf]cekdPF=bVU}j]\[[T}lddtt{f]c{tt:97lldUMRultekd]cdVTLbVUbVZfkk|ztltslSKJ{tttsllri|u{{lrifkklkstt{JHFVZ[g\rmtt\[b{{tt{d\\[[TVTLVTL{zmcbVtts{u{bVU{u{uztVZTttsuztuztlddf]c}[TTtslMRK[[T{{v{d\\||tslf]cutrg]VTLkd\{{tlek[[T}tygllkljVTL[TT\[[|zldd|dc\lriedkekd]cd{{\UZ[[T}|uzt{{tmttttslriVTLslelldr]ZD;93+*|zkd\{yfFD;JHFSKJjcVMRK|u|dc\utkk]SKJtsl]bZbVUkjVsre[[TtllD;9aWMslesreultj]\sreusreredttsutultwlu{{t]cdMRK\[[{ttldd]bZ]bZzllwl|}||SKJFD;}u{tttll{{t}|tll|||zred{||cbV]bZ{u{ztl\UZ}|z}{||tsldc\{tt||}slekd\ultsleztlult|vtll{ttllktllredUMRtslVTLtts{tt{ttekd]bZaWMredllk|kd\u|u{||ultlek{{ddc]cdf]ctsl{{lks{{j]\VTLFD;[[Tldd|ultllk{||lri|{{t{{t{|||zd\\tzl{{t|zu}[[T3+*lektllyfltsld\\ldd}|ut{ttwl{u{VTLcbV}||[TTVTLVZTuttsl{u{{yfmtt\[[{u{kjV}|tzl|lkslldkd\llku{{|ztt{VTLusleJHFbVUUTS:97UTSD;9VTLiq]JHF%PF=b[Ulekrg]}|z|||utslkk]kjVVTLdc\llkdc\JHFb[Ukd\[[Tb[U{ttwlwlvtsl{zmred|vsle}}\[[JHF}ultdc\dc\kd\VTL}{{[[Tdc\b[Ukd\lri||}tzluzt|zsretllr]gzllri|u}}|zttsVZT}|{{tsl[[T|u}||llktll|tsl}}lddredaWMtllcbVJHF[TTult{u{j]\UTSllkztl|tzlkd\ult{{tztltslkk]|u{||lkscbVmtt}lksJHFuztmtt|ulttt{{||mtt\[[{zmSKJMRKlekultult[TTlritsl|ztsllri{tt||zdc\b[Uedkrfkred[TT}}v{[TTkk]|uutwv{lld||SKJd\\tll{||j]\mtt}tsl{zmztl|z}f]c]bZu{{{tt||ztlredu{{tslu|z|UMR7-2SKJFD;MRKLKRtt{3+*73JHF[[TutsledkV[TTPF=VTLFD;bVZu|u{zmtsl]bZ{||i\VztlSKJedkwl|zr]Zljzll|vlj|u}|v{[TT:97tsluuzt\[[}|lld]cd~f]c[TTb[Uyletzl{{ztl[TTbVU|{{tddclrisreVTLtllultkd\u|z{zm}lritzl{tt{{ttslkk]}redtslutztllri{zmaWMujcVd\\SKJVTLkd\{u{\[[lri{{tf]cSKJ{{[TTrfktts||lriyfllek{{tult{ttsresre{zm}sretll{||lrikk]{||{{tultf]cVTLVZ[|z]cdmttllk}ttsdc\MRKjcVtslztlultf]ctslult}dc\|zVTLttsult|||uztliq]lriSKJu{{UMR|zSKJf]c}{||}f]csre{u{ldd}ultuzt\UZVTLlrilld{u{ddcek]lddkk]b[Usle}\[b{zmztl{|||z}]bZu}|zttsmttlks[[TVTLFD;74,UTS3):97iq]dc\|z{{tVTL|ucbV[TTVTL|zsle\[[VTL|uztl}|edktllwl|utsllldd\\d\\}|ztl||u{zmuv{UTS*)(ztfVTL|vlriVTLllkr]Zb[U:973+*rfkyfl|ubVUVTLFD;red|ultult{{ttslv{lrilksuzttt{}zedkaWMek]|uztfzll|tll{ttwlkd\rg]sle}|ztllrir]gSKJf]cb[Uekd|u{ttd\\UTSulttslsle|kd\uztlkskd\SKJlld|zlld{{tzllldlld}ddcf]clksJHF]bZmtt\[[tt{}{{u{{bVZFD;tslddclld|uu{{lks{{t|{{tuztekdUTS~ztltt{uzt{{tztl}kjVuztultjV[|vjV[v||utf]c{{tcbV|{||ztfultb[UttstllddcMRKlriVTLFD;lld|llk{u{llkmttllktt{}lriekd]cdf]cbVUVTL>B9FD;:97FD;&&C8.{{t}kk]ultsleulttslJHFVTLVTLsre]bZVTLbVZlldlddcbVlld}wlttskk]||||}|wlbVU|usrei\V|u}>B9:97jV[bVZu{{i\Vekdllkkd\aWMVTLJHF|tts{u{sle\[[tzlr]gtslldd|z||||lri|z|SKJ}{|||zkk]tsl|}VZ[|{zm}ztflld{zm{||}SKJb[U|[TTredzllztlldduylelj{u{tll||llktllultb[U{{JHFtsl{||lriuv{]bZ}|}u{{ttswlsle|ulld}ztl}|udc\ekdrfk{{mttF=C>EC]bZf]cdc\\[bVTLVTLUTS|ui\VF=Clldiq]dc\[[T||{||uuztuzttsl]bZredult|rg]f]c[TT|v{}|z|uv{}|{zm||redbVUUTS{u{lld|||lri|zkd\d\\kk]u{{ult\UZtts\UZtt{u{{{||lrilld>EC%FD;74,FD;SKJVZT3+*&&C8.yle|z|||z}JHFJHFlri]bZVTL:97VTL{u{tzl}lddrfkllk{zmlri|VTLrfk}|v{u{}utztfMRK*)(ut|z}{zmJHF|zllkuztlekttsi\VD;9D;9}{{cbV[TTedk||b[Ulrikk]ddclldVTLekdSKJj]\F=Cj]\{{sle]bZlld{zmrg]ddcf]cj]\j]\ddcldd}tzlztlsle}ut{||~fkk}|tslmttf]ctslUMRSKJlksslef]clddddc{{tslttslriuzttslzl{||utsre||uztVTLtllultddcedkekdLKRu{{lkstts{tt{{j]\MRKVZTrfklektsluzt}ttstsllkstts|lld{||ldd~}mtt{{lek||tts||wlb[U\UZtllrfklddv{|z}j]\|uSKJ{{JHFddcredulttt{ult{zmultlddutlldllk]bZ:97aWM3+*C8.Q?@F=C%&&&tlllri{zmVTL||VTL|ztl{u{JHFVTLlldJHF\UZ[TTtsllddtlld\\tts[[Tsre[[TVTLkd\kd\}rg]}sleutMSS:97tsl|wlekdJHF|ztt{uztdc\|rg]74,bVUUTS{||ddcekdlritsl}slellkVZ[{tt\UZ{|||VTLSKJ]bZFD;[TT|zmttrg]ttsd\\rg]}|{ttkk]tsllldtslv{{zmkd\lddmtt}}{u{f]cultUMRztlultj]\}kd\llk||lri{||ttsf]c[[Tsre{tt{||ttstsl{tt{||}lek{ttuztMSSmtt{u{ek]{u{{u{f]ckd\lddd\\SKJtslf]cdc\{{t[[Ttllf]c\[[u{{mtt{||ekd|vkd\|u{ttVTL[[TVZTlri|u}|{u{tsl{u{{tt|u|zllkultlddslej]\{u{j]\}tzl}UMR[[Tj]\{ttultf]c\UZslerg]f]c{ttvfkkf]ctsl\UZ}{u{{{:97lldmttF=CFD;>B9FD;|zj]\|z|zwlsletzlaWMrfk[[T[TTlri{zm\UZlddcbVtsllldSKJttsttsVTL[[Ttllsre[[Td\\{zmrg]lldrg]||v{zmJHF3+*{{trr][TT||llk{{t|uC8.JHF{{tuzt{{t}lksdkVlld|\[[|ztltzl|zlri}{u{utult{{ttslkd\jcV||usler]gyledc\d\\|ulld{{tsletllrfklddllkyleekd{u{edktzl{zmlekf]c{{VTLrfk]bZ|z[TT{u{tzlfkk{{tredlriv{lld[[Ttslzll|z{{t}lek{||{{{{{u{ttsttsfkkd\\\[[zll{u{||||]cd||ut|tslJHFmtt{{tuulttt{kd\{zmsre{u{\UZlekult|lrirg]iq]||ttsldd[TTult||lldredlldv{||kk]u{{VTLb[U\[bSKJ{{r]gUMRuVTL]bZJHF\[b{|||udc\kk]ultrg]\UZtsltzlddclddu{{tts{{tVTLredUTSUTS]bZdc\]bZrg]SKJrg]{yfkd\i\VSKJsrelddSKJ:97{zm]bZttslriukd\dc\rg]PF=bVUv{ztl}tsl||ut{||ddcb[Uttslddkd\lrilritzlutts~d\\dc\lddjcVVTL{{t{ttztltsl|ztl{{t}|}rg]mw{zm{zmredrg]v{lddredultv{fkkd\\kk]|lek\[[kd\}tll|zek]uzt}uztlri|ufkk|{tttsl|{ttldd|ulttllb[Ukk]|fkk|z{tt[[Tslelri|z{||{{tVZTdc\\UZ||llk}||ekdttstts{u{{{tttsztluztv{tlld\\sre{ttd\\}{{tldd[TTlldbVUtllutllktzl|ubVZlekllkSKJlri[TTttsd\\{zm||tllbVZkd\}]cdu{{:97{{JHFD;9|]bZ:97dc\{||rg]wlekdtslztlllkultsretts}|mtt{{{tt|z{||||d\\slesrett{}b[Ub[UcbVrg]cbVjcVwlrg]ddc*)(zllu{{lldsleUTScbV{zmHI/ultultredf]c{zmtts{{tultultdc\{||tts}||cbVtt{{{ttsutvddc||f]cUTSkk]lldVTL{{t||ud\\ztlsre||vbVUutlrilldVTLVTLd\\kd\b[U]bZ{{JHFd\\ultek]tsl||}lri]bZdc\lek]cduzt{{kd\b[UUTSult}slelekek]tsl{{tred{{t{zmj]\lkscbV{{t|zultkd\lekUTS{{ekd{{{||{||tllek]tt{}{||lldlek{{tsl||zmttf]c]cdddcztl|u|zuzt{{f]clks|{u{zllultfkktlllldsle|u{{||lrildd|ubVUttsultztf}tllrfk{{tcbV{||mtt|UTS]bZUMRD;9\[bekdzllVTL{ttedkSKJ>B9f]c{zmredVTL}}b[U\[[{{fkk{||lks{{[[Tllkdc\dc\u{{}dc\lri{zmljsle~[TT:97uztttsj]\f]cVTLbVU{{t{ttFD;JHFyflzllmtttsldc\d\\kk]lks}llk{|||z|{||uztultlritts{ttult{||sle}{zmslesreVTLtllsrei\Vwlultlldztllldtllkd\VTLSKJ|}lektslzlllriVTLd\\{ttultuzt\[[VTLrfkttsttsuztkd\b[Ulri}{zmrfkJHFJHF74,b[U{{tVTLllktslsrelriutsl|zultbVU{u{ekdmttfkk}{{u{{f]c}JHFcbVllk}{||{||lld}||z}|{{u{{JHF]bZredyllksllksreztf|z{{t{u{f]cd\\lldsle|z\[[tllztlred{tt}tllek]bVUtslv{{}|ultekdlekylelldtzl{||slemttuztMRKVTLJHFFD;FD;tzlD;9lldsre]cdJHFJHFddcaWMrg]VTLtsl|edklddlek{{llkUTSddc{tttzlult{||llkult}|{{tSKJi\V{zm{||}VTL:97v[TTjcVkk]kk]VTLbVU%UTStsl|{{tlrid\\lksuztldd{||}zlekddc\||\UZultkd\v{VTLddcleklldultkd\rg]|u{{tlddlrid\\}wlred\[[sref]c|uVTLSKJVTL|uultredfkkd\\|dc\lldlektlllld[[Tv{f]c{ttlrid\\zlllriultztl\[buztddclldrfkuztcbVllk}{||ldd}|z||}mttlks|tsl]bZ|tts}tts\UZtts]bZultlldlks|u||tlllddllk}fkklld\[blldtt{d\\dc\}|v|uedk{||[[T{{t|r]g}|{{|zrg]llk|u}||rfktt{{u{zllkd\}|tt{sretll|\UZddcek]|z\[b>B9\[[ddc\UZVTLJHFC8.JHFFD;ddcylecbVztllriztlllkddclek{ttttsllkllkttsddclek{tt|tslsrerfkcbVv|v|v|uVZ[JHF|u{{t}||{{~lldtllkk]vsleD;9UMRultsle{{tuztu{{ultutldd[[Tddctts}b[Ullk|ztslllklldlldrg]cbV|uVTLj]\{{tztlztlredd\\u{ttFD;cbV{{tultztlSKJ]bZMRKkk]}u{{tsl|zu{{}tts}ylef]c]cdlridc\{tt{zmultlld{||tllllk{u{[[Tdc\]cdlkslks{{tt{lksubVZldd\[[{tt\[[]cdut}tll}|lksċkk]ttsuztllk{{t{||edkJHFutuztlekv{~tlltsllri|||ultj]\|utts{ttldd||b[Uslelri{||||||{{tslemttjV[tslllkmttSKJMRK]cdJHFD;9JHFSKJD;9fkkaWMedkv{ddcrg]{zmlld{zmtts{u{bVU|ztll}|lddtts}lldtslrg]b[U|ztl||v}rg]UUYLKRv}|[TT{ttuzt|ui\Vrg]FD;VTL[TT{||dc\|z||tts]bZ\UZ}|tt{dc\}}jcVzlllrilksekdd\\lkstsl}srerfksre{{tutjV[}{||u||tzlek]cbVmtt[[TlekSKJlld|zut|z[TTtsl|slelldFD;sre|||z{{t|u|v{}{ttultuzt|MSSmttu{{ttsllklkstt{{||}lekuztuddculttts{{lddĄ|zfkktslztl|uzttlllekdc\||VTL}|||{ttttsu{{||wllks|zkk]}sle~v{redrfkntslcbVztlu{||||UTSFD;ZbN:97:97SKJ[TTcbVsreSKJVTL[[T{u{[TTsleultwlcbVdc\{ttlekztlnvmtt}tllf]clddcbVdc\kk]}||uwl|u\UZ>ECztfrg]iq][[T}llkztlkd\ttsredFD;{tt{tt||zekd{{|||mtttll{{tekdkk]tt{utekd{{ttt{}|{{tjcV|||wl{{t\[[d\\lld{||iq]rfkvdc\d\\[TT\[[ttsllk|v{f]csle{u{|lldSKJd\\tll|uztfllduzt{{t|ztlbVZddctsllld}|z{{ddclks}ddc\[[{||tt{{{{tt||lkstt{{{t{u{lriztlrfkf]czllztltsl}ultldd|z||dc\b[Ukd\{zmtsl}|||}lriSKJrfkultf]c}lks|u}}|||}{zm}|zttsb[Ullk\[bFD;%UMR[TTtzlJHFVTLVTLlri}|kd\}|llkttsllkddcllk|ult{{{u{u{{lksult{||u{tt|uv{|vUMRJHF{{tj]\|uttsb[Ub[Ured|v|u{ttztlD;9FD;{{sle|zllk[TT|zv|mtt|z|{{t{||{||lkskd\f]c{u{{tt}{ttrg]|uldd{u{}|tllkk]tsl[[TVTL|z~wtlllritsld\\JHF|tsl||{tttts\[bekdllktsl|ulritlllek|zdc\lldttsd\\bVUtlltts[[T[TT{{ttsVTL{u{lridc\}||||lddf]c{{t{{mttfkklldmttuzttt{lksVZ[{||ztlVZT|llkult\[bv{||{{u{{|||f]csretllllkkd\{||d\\llkulttts]bZlld[[TSKJultv{{||{||tzli\V{tt}fkk\UZ{u{tll||redvuztdc\{||ekdj]\tlllddVTLMRK[[T>B9\[[kd\tsl\[[MRK*)(u{{{||redj]\ttsekd[TT[TTddcedk\[[tts|ztts|lekldd}~vtll\[[,55|jcVzl]bZttsztl|utFD;sref]cVTLd\\lekttsӛ|z{{tf]cult|{ttd\\}tzl}tll|redu{{zllkd\wl|}i\Vw}{zm|||lldbVUttsb[U|tygredzllv{\UZ[[Tkk]{{lkskd\rr]llduztmw||d\\ddcultzll}|ylesle|ubVU{||SKJ}|[[Tult}||zllllkttsutuzt\UZMSSMSS|UTSUTS\[[ult\[b|{||{||ultedkddcv{{{t{||{||mttutt{llk{|||zf]ccbVtllmtt|z\UZv{jV[sle[[Tkd\{||ttstts{tt|uztlkd\ttskd\r]gtslsleut||||zut|ztts|lrimttut|{ttek]JHFJHFFD;JHF{||MSSMRK}JHF|zdc\UTSyfllekf]cmttredllktts{tttll|v{zm}{tt}MRK:97{tt|usreSKJsrezll{{t|u|ubVZsrekk]SKJrfk}}lks|zedkUTS|||lritllddcrfkf]cult{u{{{t|zddcf]c|ulri|zrfk{{t{tttslzlluzll|ttsb[Ullkdc\uVTLd\\f]cddcekdf]cf]c|}tsl{ttv{tt}lldSKJtllbVZztf}|ultdkV|zllv{{{tv{ttred{{t}ult{|||ultllk>ECMSSUTSllkddc{{mttfkk{tt{||ekd{||f]clksddctlltll{{tultult}Ц|uuztsre||{{t||{{t{{t{tt{||ttsztl{ttkd\|ult{||lld||}{{|ulddult|ztzlztluztl{ttyfllddtll{u{VTL\[[FD;F=CUMRd\\[[TZbNedkUTS|u{{t{||rfk||z|ttstsl}lriu{{]cd{{t{{tkk]{{tuttll{zmllk7-2}cbVkd\wl|tzlyfd{||SKJPF=kd\|z{{]bZztld\\|ztsl}vd\\lldf]c{{rfktlllkstts{{}tslMRKlks{tt{zmtll{|||[TTredkd\}uddc||||u{{lldbVZ[[Tek]\[[{u{leklek}|zultsleekdtllkd\redllksleuztcbVlldFD;lekj]\ztl|v{tt|||}ult||i\Vredrfkult{ttultlrifkklld|z]cdmttultuztult^^qf]c||}fkk}||uztf]c{|||f]ctlltslddclri}}{||{tttt{ultlddzlluzttzl{u{v|}ddclldlld|ut|utslekd\ult|kd\{{twl|ulriztllek|}tll}lld}|kd\VZTVTL:97UMR{zmekdUTSFD;MRK]bZ|zsle{{t|z{{tztl{{tllkd\\sle|ttskk]llklddlektslztl{tt{zmv{}||}VTL*)(tzlljcbV|zzlltzlkd\sre}|74,D;9{{ttll}{||}ultjV[yfd|z|}~||tsl}}{{|tt{[[Tddcek]sletts|{zmultsle\[[kd\tslVTL|{{tlddlddulttllJHFultredtsl{{bVZmttlriv|mttkd\kd\dc\|z}{{ttslUTS{{t{ttljtlltll{u{ttsultredlddkd\{ttult{||edkultJHFmtt\[bfkk{tt|zult|{||vUTSdc\llk|vv{u{{mtt{{|{{}v{{tt[[T|u|||}}|z}|{zm||{{tmttttszll|uztd\\{{ttslztf|ztsl}}tslsle}{u{kd\d\\}ekdrfkJHF||bVUlekb[USKJJHFFD;MRKSKJVTLJHF|\UZ|f]c||u}|llkekd||lri{||kd\MRKred{|||ztts||ultu{{{||{||kd\|u}}{{tsle|u}JHF-1+|zrg]kk]jcVvb[Ub[UVTL3+*ttsVTL}tts|zmtttt{}llktt{{tttslf]clkstsl{{||vultttsdc\f]cut||redi\Vkd\zllVTLldd{||[[Tllk||ttssredc\bVUttsSKJ}ultllklriredztltsl}d\\ztl{ttdc\d\\|uztl}|cbVkk]kd\||}|wlkd\ult{{ultlldfkk|JHF\[btlluzt{{}|{{t{u{ddctll{||lri{tt||z||}edk|zslelek{||tsl}}{{t{{t{{t|zdc\rfk}{||llkult|{{tslett{{{|}|bVZlldlekztluztkd\D;9VTLFD;[TTsleUTSf]c&&\[b|u}~sle|}}lldztlttsttsutlld|v{yletsl|:9774,|u{{t|urr]rg]tslyle{u{||VTLSKJ}}|}tt{lriuztult|z|||dc\d\\[[TUTSrfkldd|}j]\b[U{{tkk]{tt|kk]uzt|zttsf]c{{tsletsl}d\\v{|z{{ult{||}uzt{||jcV\[b||{u{ultut{{ttll}|}{u{f]c}lri|lri]cd\[[ekdtt{{{tsl{u{{||||ekdtll~llkwlultwlult|z}|ultult{tt{{t{tt||sletsldc\{||lek{{t{{t}|tllmwmttd\\mttztl{u{{{t|redlldtll}|rg]uzttygC8.dc\[TTldd\[bmtt\[bkd\rfk{{t[[T|ttsv{{{tslellk|ztlutüSKJ:97kd\kjV}ztlkd\}d\\tsl|zuzt}{zm[TT{zmuztu|b[U{||{u{{{{{t{||tts\[[ek]|u{{ulksult{{t{{uu{{ut}||b[Usre||sre}tt{|||uult{ttsretzld\\lrir]Z|zuttts{{t{{{ttek]tslkd\d\\tlltlllddf]c|llk}|||lddsre}{{|]bZ{||{u{|z|}mtt{|||zttstt{}tllultldduf]cttstzl|z}ut{||ldd|{tt{{t{zmuzt{u{||{tttts}lddldd{{t[TTllk|u|}u{{~ztf{{tslekk]D;9ult{{|zmttUUYd\\fkkzll|uuzt}{u{\[[~ddc]bZ[[Tddctsltslb[U|{||v{ztl[[T74,{zm}}|z{zm|zllduzt|||zztlldd[TTddc|{u{{u{}}VZ[u{{|ldduztdc\lkslriult{tttsluzt{{d\\}}ult}zll{ttldd}{{t{{lddtsl{||u||kd\|uultj]\tllllkrfk||{{t|{ttlld|zrfkj]\v{mtt}lekrg]}ztltslldd{tt{{}reduztkd\b[Utts{||{{|{u{~mttlks[[T{||llkdc\rfkmtttt{|}f]c~tsl{{tt{{zm}|u{||v{}|u}lld|lldututttsut~mw{tt|ddc|lks{u{|z}||d\\sred\\|z|vtts\[b>B9f]cJHFtll{||uztkd\tsl{{}|z}{||lld{{t\UZmtt|llktslSKJVTLkk]kk]{{t}|tllVZT-1+|||ukd\tzlVTL[TTllk}ulrilks{{t|zlks|sre[[TUTSUUY}zll||lri|cbVslettslrikk]lddlkstts||u[[Tttsekdlddtt{[TTztltts{u{ut|zuutll{u{lddkk]vlddredbVUtlllld}tt{||||z|b[Utts{{t{u{sleSKJd\\d\\}sleldd[TTddcek]utllk{u{{{t[TTkd\|slelrimttlek|||{{{{{||llk{|||z|{||||{u{}{{}|zult{||{{|zlld}{||}|{u{{u{||tsl|||{zmd\\f]csle{||}{u{uztbVU|zkd\tsl|z]bZtll}}sletzl{{lddtzltt{SKJJHFFD;llk|ztsl|ztt{sleztl{u{kd\ekd{u{[[TbVUtts|ztsltt{lldlrib[UaWMcbVdc\tsl}tsl|vJHF3+*}|uwltsltslsletlllri|u{{sle{||ddclri\[[ttsf]cUTSzll~{u{sre||mtt|zf]cttssleddctsl:97ek]VTL[[Tttslri{|||{||v|||z{u{zllv{}ult|uztlultsreyfdsleredd\\kd\bVUttssre|]cddc\{||ttsredredUMRd\\|ud\\yle~|u{tt}{u{ttsreduzt}tll{u{\[b]cdyllks||}llk{{|}}||ztsllld|uult|z\[b}{tt|zsleult|uv{}tsl}{zmsle||u{u{utlld{{tult||}||tts|udc\tt{zll|zj]\[[T}|SKJ}SKJVTL[TTlrimttddcwl{{tu{{tt{||{u{v{b[Utsl{{}lldlek|ultttstslv{{zmtsl{ttJHF*)(}uzt||f]c|udc\|ulritllUTS|ulri}SKJvlldekd\[[UMR{tt}lks}{{tredlldSKJ{||tsl~uztlri||z||ult||zllztl}dc\|}rg]|zd\\tlltsl{ttrg]ultSKJ{|||{{tsre{{t}||tsld\\mtt{ttsleldddkVbVU{||{||mttuztllk{{}lld{||[[TbVU\[bd\\\[bedk|]bZu{{|ztts|u{u{|}{{zll{u{|zleklld[[Tlld{{||zztlutVZT}}{tt[TTkd\ek]}}|}}|ttstsl||{u{}||||}|||||ubVU||rg]ztl|ult[TT{{tslelrif]c{{ldd{|||z{{t{||d\\f]ckd\VZTtts{u{{ttv{lksVTL*)(sre|lriztl|uVTL{{t}{tt[[T|zb[U{tt]cdut||}|}zl}vsle[TTUTScbV|udc\{||u}u{{v{}tsl}tllut|zek]zll{zmv{{tuzttll|v}bVUztlslered}ldd}sle|llddc\{ttllkd\\{ttkd\tll|zj]\}}{tt}llkllk||v{}tll{{ttstslmttf]c{{mttuzt{{|z|{ttVZ[{tt}uztv{~||tll{||ddcv{}dc\{||rfk}}ztl}tslztf{{t{ttkd\sle|u|zult}ċ|j]\}red|utsl{||utlldtzl{{tSKJutVTL{{t~f]cJHFlritts}ultj]\}llktsllks|{zm{{t}tsl~\[b)+2}|}dkV|u}sreVTLsle|ulrimttztl|\[[lrizll|uuztVTLlld}lrif]ctsllri{{{{{u{tllsle}{u{}sle{ttj]\}ldd{zm|u||sledc\|vj]\]bZtll{{t{zm{u{|ukd\ttsedktlllddsleztf{u{||v{tttsldc\v{|u{u{uedk{u{ttslldult{{t{|||zuzt||||zlksu{{{zmlek}tt{}ultlks|{|||tts}{{ultyfl|usre}yfdztl|u|u{tt|z|zrfklri{ttult|{tt{{tuzt}lldztfVTLSKJsleuzt[TT:97f]cmtt\[[lri{{tmtt}{u{||}ek]tlltt{[TTu}JHF*)(lriztliq]lld{u{VTLtsld\\|uzt||uztu{{u{{tllulttts{||rfkldd\[[{{t{tttt{u{{|zultred||{{tllb[U{||tts{zmslei\V}{ttutddcddckd\|ud\\}tll||zllUTStll|zusle{u{tts}}{||{ttf]ctllwllldsle|||z{u{ultttstts{tt||||lks||lriu{{||VZT]cdu{{{{]bZ}{u{tlllri}|sle|ulttts{{tJHFztl{{t}ult~tll}|}ljlri{zm}|zllkd\|z||UTS{tt{||tll\[[}|{tt{u{|z]cdztlVTLSKJ}MRKSKJuztd\\mtt|tt{|}}ttslkstlltsl{{t|ullk||tts|MSS*)(cbV}{{t|cbVdc\sreztlekdldd|u|zJHF|[TTred[[T}~{zmllk{{tut}|{{lks}|z}wlv{yflf]clld{|||uddcdc\uztb[U||{||}|tllkd\lekut{tt}tt{|lektllztlrg]tts{u{lldv{{{tddcVTL||ult|sleiq]]bZlri}\[[v|sle||{tt{{tu{{u{{fkk}mtt{{\[btsl{{tkd\lekultddc{u{UMRuztuztu{{tllk{u{iq]tll}{{}{tttsl|ttsuzt}|||b[Utsluzt{u{||ult}{ttedkSKJslett{u}slecbVrr]SKJdkVMRKf]ctzlmwekd}ldd}tts}{||tll|z{{ttslztl}ult[TT*)({{tlks{zm{tt||{{tuzttslyle{{t|zultuzt{||f]c{ttmtttlltzlttssle]bZ}lri\[[\[[uzttt{tts{tt|uztttslddb[U|zddc{{tlriztl}ztlttsztllddb[U|uslekd\{{t}|z{||{{j]\|VTLtll|z{u{ttsllk{{ttllztl|z}tlledku{{ddc|z|ekdmttmtt||tllztlztlultulttts}v{|}|{{t{zm{{ldd||~|u|udc\|||u||}}u{{}}{||||tlltts|lddedklldztlkd\|ukk]b[U{tt~mtt}tts{||llkVZ[{tt||mwmttuzt{||||}ddc||[[T{u{{zm{{}}|LKR)+2ud\\}|usleuzttt{VZ[VTL}\UZ|u|u{{|zlriuztcbV|u|}|tsl\[[|zu{{|ulksu{{tzl|z|ztl{u{{{tlrittsvtslsleylelrirg]ztl|uult}ztlcbVf]cd\\|u{zm}|{u{lldtslddc|zu|tsl{||d\\sle|u{||sre|ud\\|vkk]tlltsluzt}sre}|||{u{{{|tts|ztl}{||}tt{sre}ddctslult{{}tll|z|z|u}}yle{||llk}f]credlddldd|zuultdc\ztl|zVTL{u{lek{{tv{llku{{v{lek}v{|{tt|llk}}kk]ultf]c[TTJHF:97sre|{tt|[[Tb[U||lldtlllrilld[[T|z}tzl{||mtt{{t~ult||u||}tsl|dc\\UZ\[[{{ddcztlVZ[ztl}}|z}lriddc}{{tsre}{|||z{ttdc\tts|lldkk]ztlSKJi\V[[T{{ek]||{ttzll{ttj]\|zllutztlllk{tt{|||ztl}zllllkdc\lldultUTS|ub[Usle}sre||{{t|z}{{t{||\[[{u{{|||]cd|{|||{{t{u{{zm}zllred|{{t|tzl{||{{||{ttwllri|||uvutlri{u{{tt{||{||{||ult}|||{tt{zmyle|uzt]bZ|zu{{ult]cdf]c|ultdc\|lekredsrev{||{|||zbVUrfk{{tlld|uldd{ttzllut:97JHF{{t|sle|||||u|ekdlritsl|||tll|VZT{{t||}{||b[U|sre}lekttslri\[[lkssleVZ[{u{{tt{{t||lri{tttllVZ[|||f]c|{||sretsllddsre{{tsre{{td\\{||lldd\\|v||b[Ukd\lddtsllldb[UUMRtllred[TTtsl{||}{||{ttut|ukd\tt{uztldd{tttt{fkkmtt{ttu{{{{ulddtt{{|||utslvrfk{||{u{tts{|||vvv{{{t{{{{t{{ttzlzll||lld}||\[[||ttsMRKztl|lkslks}bVZult}}ut{u{{u{SKJlrifkkred|u|}||utlddJHF:97rg]|z|tzllri}tll}{{t]bZVTL||llktts|d\\tt{d\\\[[yle{tttlllksttslldVTLleku{{edkd\\UTSult{u{slelrilldu||}{ttztlldd|zttsv{lld}j]\jcVkd\VTLtzl~ult{zm|u[TTjcVult{u{{{tdc\}bVUldddc\{{ztl|utslrg]}||}{{tlddztlkd\sle{|||zult||{u{ttslriedkUMRtll{{t{u{}|rfk}{{t}ultiWUzllrg]utztf}|ztl|ukd\|u}u{{ttsmttllk{||ulttsluzt}|zultuztzlllddttsVTL[[Tsref]cJHFultultzll{tttll{u{|z||{{tsledc\|zw{{ddc||tsl{||ztltll|vlddultldduD;9,55|UTS{||lld\[[{u{tll|zuztult|u{ttv{lkslks]cdddc{{tcbV~d\\wlf]c||utzl[[Tmttlld\[bttstt{lrittstsl|ztl|zlldc\{||sleVZTuztlri|tts{tt}|MRKwl{{tsletllkd\tslsle{u{lriwltt{}tlltlllldutb[Uredllk||}{tt{{t}}|ulttzlf]c{{tsled\\|u{u{\[[]cd}tts}{||edk{u{kd\|z}}kk]ttsut[[Tztl|}{u{{{t}|b[Uztl|uek]}~utztf{||{||tllulttt{tsl||usreuu{{lld|JHFdc\tsl[[TUMRMSSUMRultlks{{t{{t{ttldd{||llkuzt{{ttts{ttlld[TTv{ut}lldldd~:97*)(|}ztlu{{|d\\}|u|tts{{tUTSttsredldd{u{llkekdtt{{{tlld{||ttstllv{mttdc\||ekdlrikd\{ttlri|tts}|ztll}tzl}{u{LKRd\\rr]f]cd\\ddcf]cutdc\kk]ztltt{srekd\[TT[TTj]\ultsle}ut}|tslult{{|||uulttsl}{yf|uzluzttllrg]|tsl{u{{ttvdc\{tt{{{u{{{{ttred}ztl|u{u{|u|rfkllk|u|ttsutzllrg]}jcVsrev{red}ztlkd\}VTLtslv{kk]lriedktll{{t{{mttd\\VZT||||[TTJHFf]c{{f]ctslutlri|{||uzt}|u|wlult{||ut}JHF*)(|||mttztl|uut{{tlri{||d\\ldd]bZ}}|z|z|uuztlrillddc\{{tztlrfkkk]|[TT{||tts{||{ttlldllkmw\UZ{zm{u{||v{tslsreztfwlkk]ddcdc\ultzll{ttv{{{tkd\dc\d\\d\\[[Tkd\rfktslVTLuttslb[U{ttulttllztltllut|zlrif]c}{zm}d\\f]clri{|||zlldtt{{{|||}|tts}uztsle}ult}v{}}|zlldc\dc\{||||mtttllv{{tt}|}|kk]slev{utztf}|zsreSKJllk{||kk]ldd|}|z{{lekttslrilddlriv{ttf]clri}|{u{}||~ztl}{{ttts|z{u{{u{}|||}:97*)(}{tt}|}||{||llkkd\{u{tts\[[zl{|||u{{tslerfk{{tdc\}ek]f]c||v{zll{tt{u{[TT{{tllkzll{ttllklribVUultf]cdc\{{tVTL|||lri{zmkk]|lddtll}VTLred}f]c|zsle||tllddc{zmbVUudc\[[T{{t||}ztlttsultttsfkkllk|z\[bttsmttlrittsultutult|u{{tttstll{{tredf]c}|\UZ|ztsldc\{||ult{{tv{ztl}zllb[Utzl}dc\}wl{zm{{tuzt{tttzl{tt}{{tuztu{{}tsl{ttfkk}|{||sle]cdtts|u|z|edkf]cult}}||u||vlddultultredwlJHF)+2}ultv{slelldlek[TTlksv{|}uztu{{{u{}||umtt[TT|zlek{||{||lldultddctslslejV[{{trfklekv{f]c||lddd\\d\\b[Ullkrg]{{tkd\|}|ttstts||slen|u}lddlddtllkd\utrg]f]cztl|u}b[Ullddc\||}{u{llk{||tsl|u{ttddc}{u{ddctt{{{ttt{UTSv{lek|zddcd\\kd\ztl¾ƣ}ult|vuzt}}{||{ttd\\||sresretslv{}{{t||lld|z|ldd}uzt||{u{tts|]bZ|u|z|u\[b\[bbVUkk]|tsllld{u{}|dc\{zmzll\[b*)(zll[[T{tt|uddc{tt||ult{{t|u}edk{||tt{|uztl|zulttzl||ztltts]cd|z|u{{llklddtllmtt|}tts{u{}tllUMRllkttstll{ttmwSKJ[[Td\\cbV|uyle|ulld}ttssle}{u{zllrfkf]ctsl{tt{tt{zm}|||kd\llk||zzlltsl{zm|{tttlltsl|{{t{||{u{lriv{ult{|||||ü{zm{{tf]c||}{{tlri|v{lekf]cwl{|||{{tsre|zddc{{ttsl}llk\[[}ztl}}fkkultllksle|z{||VTL\UZ}lddedkUMRf]c{{tult{||utttslddllk~uzttsl~|z}j]\|tt{f]c*)(tll|umtt{u{}|{zmtslf]c|zlrikd\[TTtt{|ulri}dc\}{tttts{{t|||utt{~{{VTLv{|z|}}utdc\kd\\[[ut||{{t|ulriv|ttsttsllk|zj]\{u{i\Vsre}||VTLylellkztfmwlddtsl{zm|}{u{vutullksre}d\\kk]}ut{ttut{||ekdtsl}|{||{{t{{{u{{{t|tllv{u{ekd}|kk]ttsrfkv{||zlllriut}{{t{u{tsl{{tu{{ddcttsu{||{{t{u{tlllek{{|d\\ult{zmultlkslks{u{rfkdc\}lri{{t}{{tut{tt|llk{zm}||tts{zm{{ttllrfk}{ttsre||{yfztlJHF?;C}tzlulttll[[T\[[ult||tll|||z||lriekdlldu{{ult|ukk][TT{ttkd\ddc|u{{t||tllek]ddcw[[Tllkd\\f]c{u{llkutlrittstllultsle{ttj]\{||ddcsleztl[TTredlddzll||\[[v{{||{{t{ttlldu{{{||lektsl||ztltsl|z|{{ulri|llddc\{tt|ztfult||lks{{t|{u{tllllkdc\|zulttll}ult|lldlritll||kk]uttts{||rg]||}}|||{||}ukk]v|ldd||~]bZult|slellk}|z}{u{|z]bZ}|JHFlksult||tll}{{wlvslettsut{||ttsztl|uztl{{tek]:97*)(tlltslekdult}|ultkd\mtt||u{{kd\{u{lddekd{{lekVTL{{{|||lldtll|z||tslult|ddc||}{{t\UZllk{u{}ultj]\r]g{||||{u{j]\}tsl|v}ult{yftzlutbVUllkzllf]c||uttts\UZ{{tztl|||lld{{tzltts{{tttsut{||d\\ztfzllult||{u{lksllkztl{{t{{tllkv{{{utkd\lld{{ttzl|u{{t{u{dc\ut{{tjcV{u{lekmttuzttzllrimtt\UZmtt{ttztltt{tll|UUYUMR\[bultuzttll}{||lksulttt{lddsretsl||tll{u{utv{}{{t|z||lldVTL74,tt{||v{[[T]bZlekztllri{{ult{||llkultkd\sleut{{t||}{||b[Umttultf]clddttsuztSKJ[TTultultllki\V}{ttj]\||dc\}{{tVTLutSKJtzlb[U{ttSKJ{ttkd\bVU[TT}{ttuztzllkk]tll{||lddbVUutkk]lritts}|z{ttrfk{tt}ttstll{{{ttkd\ultttslldsle}|}u{{tzl}edkv|redut|}{||{zm}}{{t||z|zllk|zddc||{u{u}tt{lri}[TTf]clek{||lld|zmtttt{{{t||tt{{u{redd\\}{u{tslztlulttllut}}{tttzlmtt{zmJHF:97{{t}dc\ztlztlllkdc\|cbVzlultllk{||ult}v||}tt{{tttt{lriztl{||tll|VZT|ztt{fkkllk||[TTJHFf]c\[[lldultf]cf]c\UZllkultlekyfllek}{zm}wlSKJd\\JHF{{t|zsre{{t||red{{t|usre{||}|cbVtllzll{ttztluttllllk||{tttzlVTLtll]bZkd\u|lld{tt|v{}|{|||tt{{ttmttultzll}lddlddddc||tts}u|uredu{{ztl~}||{ttb[Ukd\}kd\|}|{{ttts{{tlritsllriz}tslultztlzll}||{ttztl||z\[[lld{u{uzt{tttll|{zm}|ulttll{zm{{ttllJHF*)(ultcbV|ztts]bZred{ttj]\tsl|kk]ultf]ckd\bVUdc\d\\|z}|}|zll{{t{{llkuztowlkstt{u{{UMRd\\lddv{UMRj]\ultmwtsledkUTS||||tt{tll{{t[[T{ttredztllldlri}tzl{{td\\u|u||u{||ldd{tt[TTd\\FD;rr]{tt{tttlltsllldd\\ztl{{tztltzl{{t|zztlrfk{u{{{ztllddj]\mtt{ttlektt{\[bllk|z|||tll{||{||u}ģf]c{{tf]cldd{tt}tll}cbVddc{u{||ztltts|}|ztl{{tu{{lddlrimtt]cd]cd}edkj]\|uredultuzt}|dc\tlllri||ztt{u{{{{t|||}tsl}|z}|umtt{u{{zmztlddcztlult{ttztl||kd\|uultf]c{{||>EC:97tslSKJ{{tVTLwl}|{u{d\\rg]|z}mtt{{tbVZ{u{sre||{||zll|z{u{uztulttll{{tldd}{tt|zUTSult\[blrilldf]ctllmwtsllekJHFuzt{tt[[T{||kk]utSKJredv{llk|zvd\\tslultedk}||b[Uztl}kjV|utll{{t{ttdc\||{||lldu}}tts{tt{{t}|{|||{||ttslektt{{tt{||}{{tv{tsltsl{tt}{tttts{zm{tt{{t{tt\UZred{u{uzt}{ttbVU{|||]bZultult|zultdc\llkkd\tlledkttsultfkklks\[blekllk{{kk]ekdtts}{||{u{uzt{{tdc\|z{{tztfllk:977-2}llk{u{|{u{tzllld|zlldu{{ttstt{lriult}]bZkd\{tt||tlllld}|z}rfk|z|{||llktt{lksf]c{u{SKJ}{ttlldtll{ttv{|z|zuzt[TT||llkwlrfkVTLsle||slettslldtts|zsle||aWMSKJFD;ztlultu{{[TTslelldkd\|utslttsuzttllb[Utyg{{ztlsrekk]{{tddcsle|ztts}{tttt{{||ddc{||{{tts~}{{tf]cmwwl|uuztbVUlldddctsl{ttsle|uult{||rg]|}lri{||mtt|ztt{ddc{||rfk}ztlzll||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{ttu|zuzt||{{\[bJHFJHF\[[f]cd\\\UZb[Ud\\ttsd\\VTL}{zmtsl{|||u{{t|f]c]bZslelddddclld|ztzl|utllaWMsre{{{zmj]\tll||tslztlf]cb[U|z{||}dc\|zllek]tslut{tt|lriv}tlliq]tsld\\{||{{t|z{{}}{{{||}{u{||}{{}}sle~|||u{{t|||z\[[v{}ztl{||tsllldj]\ttstzl{||wl}lld||lldmttlks|lksuzt{{ttts}{{t||lrir]glldmtt|zlddv{tt{{{|~{{t{{tdc\VTLtllVTL]bZJHFJHF|z|]bZSKJd\\ultddcd\\b[U||zlekttssleultuzt{{t{{||zllkldd|ztts{u{ldd}|z|zMRKddcult]bZlddultf]cmtttsl[TTultd\\lddu{{}tllj]\f]c|ukd\{||{u{[TT}|{u{sreztl{zmcbV||tzltzlultkd\{||llkzllutultkd\VTLsle|zdc\||ztlsresrekk]tslutslelddulttlllddllkSKJiq]tsl}{tt{{{||llk{{|z||tts{{tkd\||{||}ult|zuzttsl|{{t|u}ldddc\ldd|utt{tt{tsl||{{t{{|ttsut}sleut{||ekd|ztsl}ztl{u{llk||}v{{{t{||{ttj]\tts}|zttsddcSKJ*)({||dc\lddtllVTLf]c{u{uztttstslu{{lriu{{f]cu{{lld||||dc\b[Ullkuzttzlddcu{{d\\ddcJHFVZTSKJv{tt{[TTlks||tsld\\[TTddc|utts{||red{ttd\\sled\\}\[[zlbVZ}|||||{||v{rg]rfkkd\|kd\{{tslesrelldred|zsletslztl{tt|u}|}{{t|u{tttsl|sle|v{tsl{tttts||{u{ttstt{mttv{llk{tt}ztl}|z}¾ƣ~}{tt{||ttsut{||}}}ult|lri|||zult|dc\{u{}|u{zm{tt}{ttttsu{{j]\uzttslv{}uztbVU||ztl{{t{tt{{tut{ttllk|u{{t|z\[[dc\:97&&UTSd\\d\\u{{ztl|{{t|z|mttsle{{tlldsletts{ttekdekdsrelrif]c{{mttsle{zmzll||lddlektlledkult{{t\[[|f]cttslddtslkd\sleSKJ\[[leklldtts{u{tll{{t}ztlrfkttssleVTLtllsleztf{u{uzt}f]csredc\}sre{u{{zm{||}|lldkd\{tttlld\\sre{{t||ttstll{u{mtt{tt{{{{{tt{{f]c~ttstts}|tsllriǔtsltsl}|ult|u{u{{{t{u{tts}{{llk|||z{{|mtt\[[||mttf]cd\\|z|uttllmtttll|mttztl{ttu{{tts}|lrilektts}|{||{tt{{t|uuztutv{lks{||{{JHF:97*)([[TSKJJHF\[[lri{||tsl{ttlri|z}u{{kd\v|zf]cf]cVTLek]kk]ultd\\VTL}{||f]ctt{edklddedkuztVTLmttldd||kd\lddzlllks|||{||{u{||lddtlld\\u{{|f]c[TTtll|||u{zmj]\zllj]\{{ttll{{tSKJ|z}|ldd}{ttuldd|z{{{tt{{t{{sle{||uzttts{u{||{{{tt{u{tsltslllktt{lek|vtt{v{}||}|{||{{|{ttv{}zllmtt|JHFlldlks{ttsleldddc\}tts{u{lldllk{||tts|zlek{{ult|uztlv{|utzl|vtlluztttsllklld{{tSKJ*)(lkslldVTLUTSsref]ctllbVZtzllldmtt|z{{t||zlld{||\[[}{||tll|zultlld{||mttdc\MSS{{}lriztlsrezllttslddztl{||llkf]cllkultVTLsre{zmzll|f]ctsl{||{u{dc\SKJultlldnf]c{||}v}ult{|||tts{zm{tt{||{tt{tttsl}|kd\sleulttll|{{t}utllkllkttsllk{u{ddc|u|||z{{{u{}|z}]cd|uztkd\{tttsl{tt|lek{tt}tzl|tll}|redUMRtt{UTS}}}|tlllri{u{u{{tt{uzttts|tslv||}kk]|ldd{u{{||JHF3+*||UTSdc\}|ut[TT{||lkstsl|z||z|z}lri{{|z{||||ekdrfkkd\utts||mtt>B9JHFlks|tsl\UZ{{\UZfkkVTLult|ud\\\[[ultek]llkbVUj]\tzlztlslekd\ult}ldd{tt{u{tt{b[USKJiWU{u{{zmVTLrg]sreedk||{tttts}|zlltll||rg]ztl||ztlbVUlddu{{}kd\lldtsltllsle{{t{ttllkedk{ttttslldedk{u{tt{llklks|sre}Ӕ|zu{u{{{v{lrif]cdc\|uwsretts{ttultvtllult|z{{tv{ldd{tt{||{{lkslek|u{{{{t}{{tult|zllktslmtt|llklddlek{{{{t|v{||vkd\redulttsldc\sle}lekJHF{{tlldkd\UMRUTSlksSKJUTS]bZ||lritslkk]tslllk{tt{||||}|ut|zv|z|ztslllkj]\|z{u{tt{\[[|zllduztkk]||tt{lek{u{dc\f]cuzt|ucbVu{{tzlddc|dc\sle|VTLb[Ulri{zmvek]lldsle{||llkd\\JHFttsb[UbVUztl{zmtzl}SKJ]bZfkk|ztll[[Ttslult}|}llkyle|utll||v{ztld\\{||yletlllriwlj]\uztldduztult{{{u{{{lekmttddc{||{||Ĩ|zu{{tsl||tsl}tll}tts{{t||[[T{|||ztll}mtt|fkkv{|ztlllrilddw|{{u{{lrillk{{tlksylelks{{tsl|lksv{{{}ztlztlbVZ}ztld\\}{u{}srelekedkJHF:97llklldj]\lek[[Ttslldd{||lekdc\dc\{ttb[Ulkstsl|u}}|{{sle{u{tts}lld}lddmtt|mtttll{{slef]cJHFlks|b[UJHF{{tD;9u{{|tts{||b[U]bZ[TT||dc\||ttstsllldllkztl{{lekbVZf]c||v{}|||ztfrg]VTLd\\lldllkttsf]cu|z|u}lld|utll}zllrg]j]\{{td\\|zztltt{uztv{lldlldmtt}{u{|mttllk\[[{{|z|{{lks||{{tuzt{u{||ultddcslerfk{u{{tt{{ttzl]bZmttlri{tt{tt\[[mtt{{}tt{fkk{{t}ztluzt{{uedk}{u{lriultn|{{lriut{{fkk|u{tttzl{{tv{{u{tsllddcbVSKJlddf]cJHF*)(\[[[TTSKJdc\}[TT{{tlddSKJtsliq]b[U{{tek]slelldlrittsultlld]bZddcttsf]cttsu{{ultUMR|ulddult}|z{ttyfl{|||utsltt{edkSKJlksuzt{{tJHFtll\[[kk]||lld}{zm{ttddcb[U{||zl{||b[Ud\\VTLf]c\[[b[UUMRj]\|u{tt|uredsre|{||uztkd\kd\}{{t|tsl{u{lritlllld{ttzllyle|tslttslldekd{{yl]cdultuztult{{{||tt{uztlrimtt||ċ}{{{u{{{|}{tt}||}{tt}|zmttddctzl{{ultf]c||UUYldd|rfkmttf]cd\\edk{u{||||lld|umttf]c}ttslri||llk|ttsred{{t}{{t|tll\[[{{tkd\ek]fkkFD;3+*VTLb[Ulrisreldd||[TTJHFd\\\[[||sre{zm|ztlutztlztllldult|uzt{u{uztult||tt{llklektlld\\[TT\[[[[TbVUztlb[Uttsf]cf]c{||}[[TVZT|ztzl|z{tt{u{{zmrg]ztfkd\dc\{{tultlrikk][TTtts|dc\ek]\[[mwiWUzlltsllldldd|lri|tslut}|srekk]kd\ekdv{bVZdc\}tygb[U||redlldlekult|ztts{{t{{t}{{{{]cd{{tt{{|||z{{tt{{{}|{||edkUUY{{tt{ultuztult{||{{tldd}{{tredztltsltts{tt{u{}tslu{{lksmtt}]cdttsut{{|zrfk|utt{{u{lksttstllultttsf]czllri{u{uttts|]cd{u{{{tllkSKJ*)(|zd\\\UZ[[TJHFultddc|zsleut|zv{ultlldzll|zkd\{{tv{}kk]f]czllddcnultulttt{kd\{{f]cult\[b{||\[[llktt{dkV]bZ{u{|zslesleztlekdlri{||[TT{zmslewl}}|{||wl||dc\~wl}n}kk]tsllriv|ztsl}}ztlcbV|zd\\utult}edk{{ttlltslb[Utlltll||mtt{{tuztkk]lld{{tlks{{}{{{{tt{||tll{{t{{mtt|{{}ztl{u{}ttstsl{tt|||z{||ztlultnv{||lri[[T{||{{f]c[[T{{tlritsltt{|u}|z{{||{||{||sle{u{{u{j]\j]\v{{{t}tll|uztuzt{||D;9*)(f]cVTLlriu{{sre{u{ztlVTLttsddc[TTuztlritzluztlriult|z{tt{{t{||d\\llklri|ttsv{{tt||ultult}uztJHF[[Tutlritlldc\tt{]bZkd\tsl{u{redslelddtsl}sle\[[{{tbVU{{tztfrfklddsre~r]g{|||{u{lri|lek[TTb[Utsl[[Tsledc\tllrg]|z|u{tt{u{kd\{zm[TT||ztltt{uztlri}tt{}{{||edk{{{{|}ќ}tzl{{lks{u{}tts{u{llkv{{u{tll{u{tll|{ttultllkttsu{{|{u{lks~edklks{{lksb[Uyle|{ttut|||ztt{|tlltts{{ttslu}}||{tt||tts{||{tttslfkkMRK*)(leksre]bZ{ttlddkd\d\\UTSUMR{{tuztmttdc\{zmvtllldd|SKJu{{|||uukk]\[blksedklddbVU{tt{zm{{{u{{u{tll|tzl|[[TbVUlriFD;ttsredkd\b[Ud\\{zmVTL|[TTllk||{||b[U{tt}|sle||kd\lldn{{tlld{|||}lri|ttsb[Uek]ztlrg]uztf[TTttsvzllkd\llkuztddc|u{tttt{tsl|ttsfkk}{u{{{{{}||}mtt|ttsęttsrfk{u{zll{||wl|zuztlkslri|zttsf]clekekd|z|lkslriultlksdc\tsl|}UUY{{}kd\sleult{{t{{||{u{{{{||f]crfk}|lriztltt{~|ddc}||{u{ttsultddc{ttultsre\[[||JHF*)(llklldkd\llduddcd\\UTS{u{ddcttszllddc{zmtll{||tts|u}lkssretsllrij]\j]\{||lek}}{||[[Tf]c|zzllkd\ttstsllri>EC|z{u{uztztl}{{t{{tslebVZu{{ldd{{tlld|zlriVTLVTLultkd\||j]\||]cdv{VTLdc\dc\tzl{ttuztyle{{tllkut||}llktsltllztl{{tek]sle|ut}ldd|lld}{||mtt{{{{lks|tt{{||{{|}}|zttslksnvmtt|z{{}|}mttztlult{u{|||{{t||llkddctts|v{lks{u{{{t{u{{{ultlksUMR|lri|z]bZUMRd\\b[Ullk|z{zm}ldd}|{ttsrev{||llkd\\{ttsre|}{{kd\ldd|||v}|ddc\[[d\\[TT\UZ[[T}74,74,lddVTLb[Uuztdc\ddc{u{u{{dc\d\\tsl]bZddcredlritllsle|ekd|leklekultu{{b[Utlllri{{tt{SKJUTS{u{{tttsllldtt{ylttsztltll|kk]\[[ddc}}ulttts}|zj]\|uztlu{{tll|ttsd\\fkk{ttult{|||{zm|lksdc\}|ztf{u{ttsutult[TTek]||ztl{ttkd\ztl{tt{zm|uultldduzt{{|{{tuztllkultf]c|nvfkk{||{{u{{|||}tts||{{mttdc\{{|{ttultzlltllllkttsu{{ekd}tzl}lldttsf]crfk\UZd\\\UZ|ztsluzt]cd|lks[[T{u{|uzt{tttts{||{tt}{u{bVU|v{|||uult}|zult{||}kd\|u|lrif]c|tt{JHF3+*bVZllkj]\tll]cdlld]cdult{{tUTS[[TlriVTL|ulksd\\j]\ttslddlddlddutd\\uztttsedklek{u{|v{|{{tslellkVZTlri|zzlddcttstll|u{{sreb[U{tt}sled\\tts{ttldd\[bldd{zmtt{vtzlf]cdc\lri|ukk]{yfd\\llkf]c{{t}tlltll{u{utj]\zll|sle{{tv{{{tsl{{|||z||lks{||red}{ttultă|lddtt{sleuzt|fkk}}lld{||{{{u{MSSf]cUTSf]cmtt{{|u{{edkedktsl||}}wl{||ult}bVU[[T}tts]bZ}|{||v{{tttsl{tt[[Ttsl}|slev||ultuztuzt|tllUUYddc\[[:97&&red{zmJHFVTLMRKu\[[[TTVTLJHFVTLtslsle[TTllddc\i\Vtslttslri\[bddc||ult{tt|||}{{lksSKJedk{{}lldsle]cdbVZUTSVTLdkVfkkFD;aWM]bZVTLSKJ||uztlrilddldd}tts{ttddctll||redf]c}zlld\\tzl{ttuztdkVVTL}JHFredf]cult{||tll{u{lek{tt{|||utll||ldd|z}ttsut{ttf]c|u{|||z}||v{}lks{u{|tt{}{||{{v{ult|rfk}|u{||{{}{tt{{||zd\\{{]bZ}lld}|{{JHFulttt{tzl{||{tt||lldldd||||zsre|{yff]c|}{{lriVTLek]}llkcbVldd[[Ttlledk\[buztztl[TTUTSedk:97&&\[[SKJVTLzlVZTek]FD;ultd\\|zlldsreslekd\jcV|llklld\[[}uzt{tttsl{||tllf]ctlllldut\[[ultSKJ{{{zm[[TVZTlddJHFu{{lddVTLtlllldd\\tsltslv{ztllrillkttsj]\lriUTSb[Uldd}ldd}ultzllf]ckd\lritzluztwllddtts|utreddc\uttts{{||}wl{{t{{tddctlllri}redddc{{tztltsluzt|u{{}{{{{u{{{{{{{{edk~|||tt{lrimttekd{u{rfklks\[buztu{{f]c[TT}ult{|||zttsult}|zb[Utts{||{tt}}|u|zldd\[[|u]bZkk]sle}ldd{||{{t{tt||ztlllek{||JHFJHF3+*edkek]lldb[Udc\lld\UZVTLVTL[TTlddlld{{ttllldd|}yle{||{{t|{u{{u{{{fkkr]Z{{s_qrfklekllduztv{uldd|MRK]bZVZ[llklldutekdddcztl]bZUMRztfdc\}JHF\[[f]c|}{||j]\tllkd\d\\||{ttttslks|}}|lldllkultlddlld{ttv{rg]{tt{ttlldf]c{{ttllllklddred|{{tu{{mtt{{lks{{{||lrisreu{{||z|zulttts}}}u{{ztl{{tttsj]\uzt|ubVZmttVZ[|ztts{{|uf]ctllekdUTSlks~[[T{{tlks{{ttll|lddtt{}ultedktt{{{t|u||{||lldlksultb[Ulld{{t[[Trfkult|lldekd[TTtslddcFD;*)(ultddcSKJD;9JHFcbVf]cSKJ[TTldd\[[tsl[[Trfk}|lld{zmuzt{{tlri{tt\[[{{f]c{||}ult}bVZbVU{{tult]bZultldd[[Tlddlld[TT|ub[Ulld|u{ttek]ddcddcVTLSKJFD;kk]ult{{tddcuztVTLtllbVZ{||[TTtsllddlritll}|{{t||bVUttsredredzll{{t|z{{tztl||zutkd\ztledk|zllduzt|{{}}}|{{{{|f]ctt{ult{||mtt~{{}|}||{tt{{d\\{||f]cv{r]g{{wl{|||z]cd|z|z{{|z{||f]ctsl||lld~||{{lld||}||tsllddrfk}ldd{u{|tt{||lri}{||{||d\\kd\tsl\UZlddultu{{uzt|z}|f]cVZT\UZUMRlddVTLFD;FD;[[Tut[TTfkk}[TT[[Tlek[[TztfVTLcbVdc\tslfkk|zmttek]||tzl{{tttstt{ddc}VTL\UZ|lriedkdc\|zztlttstllekdSKJttskk]|uztlldSKJ|utsltlld\\f]ckjV|SKJb[Uztluztulttsl|zsle{tt}lks[[Tkd\red|kk]u{{lddllk{{sledc\f]c}ulttllztl||llk{||{{}mtt}|{{nv}ult{{}|{{}|||tzl||zult||lks{tt{||ow|{ttsle|ultredekd|z]cd|mtttslmttedkuztcbV\[[|||f]c}|v{[TT{{tll}{{d\\}}{{t{||ddcddcrfktsluztddcultllkdc\|uUMR}tsl{||tsld\\ttsddcu{{{u{{ttlekVZTddcD;9*)(dc\VTLFD;D;9ek]kk]bVUult{{tlksd\\lrilriVTLlks|uj]\cbVlldVZTuztMRKu{{{ttlriu{{u{ttmtttts|mttf]ctslult}|ulttts]bZ{ttultztl{{tztl]bZ{zmlri\UZ}{u{}|d\\uzt}|}|sre}f]cv{{tlddSKJddcvek]VTL[TTdc\llkddc\[b||tsllldredUTSlldkd\redVTL{||[[TFD;llklddtsltsl{{f]cfkktsl||llkultlrifkkmtt||{{mk}|{{lks{tt||zlri|{u{}{{t||z]cdlks}{ttlek{{{u{mtt{||VTL|z]bZtslultdc\|v{{ult{u{||tsllek}{u{{tt}{u{slev{f]c{{t}||lriztledk{{|sle{u{d\\{||mtttslultdc\|z{{kd\ldd\[[tt{\[[SKJ&&j]\}f]cVTLJHF]bZzlltll]bZllklldtzlsleuztultVTLtll]bZ[[Tu{{tzlllk|z|z{{td\\{||ekdlld{{f]cedklldbVUlddult[[Ttt{SKJ{ttlddu{{lriUTSdc\rfk|tsl{{ttslzll|z||{ttttslldddcMRKf]clkstslekd|{{ldddc\{u{FD;Q?@ult}dc\||z{{t~mttlldult}|z{zmf]cuzt}{||UTSylerfk{ttdc\sle{||VTLtzlbVUlddllkdc\ldd||ztfllkldd}u{{mtttt{uztnvedklkstt{lks}}|u{{||{{u{{ultyltts\[[lkstslllklri{{{||{{ldd|zlks}mttlrirfk\UZd\\\[b{{tslmttlkslks{tt{tt|}||{||{{ultult{{|z|z{{t{{|||z||{||}{{tddc{tt{{kd\lri|lld{ttttsztlfkk]cdllkbVU-1+ldd{{tF=CsletllSKJ{zmzllldd\UZslelldddcd\\r]Z}}|JHF{zmfkku{{}lriuzt}|tt{kd\{||VZTlksllk[TT|uzt}lddtlllriUUYVZTVZTUTS{{tslettskd\VTLkd\tsl[[T\UZ|vkd\|{{tsle||SKJf]csre{tt{{ult|rg]}lddtslbVUlriv{d\\UTSslekk]||{{t}|{ttttsek]{||ztlttslddjV[\[[\UZ{ttult|{{{||fkk{{nv{||u{{{{}{{{{yl{{tts~tzllldlrimtttllztl}zll|{{bVZ|{tt{{[[Ttll|z[[Ttts|z]cduzt{{t{{UMR|d\\{zm}|sleldd}{u{{u{}|zddc{||{{ult|zkd\red}|tzlsle[[T|z]bZb[U[TT\[[UTSf]cFD;*)(f]c|uSKJ]bZlddJHFddclldddc\[[~tzlekd{||ulttzlu{{llklldtt{ekdlkszlltt{uztu}|tsltllVTL{ttztluztVTLlri|{tt]bZJHFb[U]cd]bZmtt{tt{zm[[Tlld{u{sreult{||]bZttslld[TTcbVVTLb[U[TT{zmi\VbVZtll}sletlledkUMRek]kk]VTLlddUTSutultkd\{||cbV{tt|ztllbVZuzttsl{|||lldvtsllksbVZ{||ulttll{{ultmttfkk{{lksmtt|~ekd}||{{{{ldd{{}|zztl{u{{||{{utf]clriUUYmttUTSdc\]cdtts{{ekdleklekttstzlwl~lks|{{tsl{{~u{{}}||u{||tt{fkk}|ultlri{{t|u}}||ztltslVTL{ttultfkkUTSMRK*)({tti\Vkd\FD;bVUPF=dc\UMRdc\sle}tsl{u{ttstlljcV|utyg|u{{d\\mttekd}}|}uzt||zb[Uddctll}}\[[{zmj]\[TTtllttsu{{lrillktllztld\\v{|ztlVTLttstzl{{{||[[Tb[U{{t}\[[VTLJHFlddiq]d\\VTLlld]bZSKJJHF||||f]c}}ddcd\\tll|ulld{u{|mtttsl{||mtt|mwtts[TTtll|z|ddcMSSleklks|}|{{{{nv{u{{{}|zNjlks\[b{tt]bZult{{t}ttsult{||{{{{tJHF\[[LKRMRKVTL\[bJHFu{{u{{red~|zttsv||ttstt{ult}||ekdddcedkldd{zmmttultdc\|llk{{sledc\{tt]bZ]bZVZTb[U*)(f]ckk]}|FD;UMR{tt[[TVTLSKJVTLj]\VTL{u{||tlllldkk]ztltslmtt\UZ{u{{{{||{{tutekdbVZUMR{u{{|||ulek{{uzt{{tekdJHFUMRldd|z|vf]c{||ztl{ttVZ[~{{ttll{tt[[Tkd\}FD;VZTd\\lddb[UtlllldlddJHFultekdudc\tsl||dc\{{tkk]{tt|ultredtt{|ztsl{{tzllLKRmtt}bVU{{lriuztmtt{{tt{}|{||{{|{{|Ѩ{{|}|zfkkf]clkszllvÚlldred|||lld|{tt{u{{||uzt|z{tttt{JHF~}zlluztlriVZTlrillk}|llk{u{|uztl}ult|}f]clld}{{ldd|llkttsekdvtll||{ttleksletll||JHF{||zllkd\JHFUTSlekutfkk\[[ddc}JHFSKJbVZkk]b[UPF=3+*FD;[TTD;9JHFlddtsldc\{ttdc\ut{u{{||||ttslddddcult[TT|è~iq]tllb[UddcUUYf]c{tt|zddc{u{dc\v{tslultrg]|zekd[TTlks{||lek||b[U[[TUTS{ttrfksreslej]\ttsUUYuzttllVTLleksreutwl\[b|ddcultlld||\[[{{{{t{{tlksredult{||tllmttrg]ttstt{{u{ult{u{{{u{{{{ǔtzlu{{ylMSSuzt{{t}}}tts||z\[bu{{{{t|[TTmtt\[[{{UTSult|zlddllk{{llk|uv{ttstt{ultztlv{|\UZ}rfkldd||llkmtt}mttu{{ulttts|v{{zllSKJd\\lriu{{ek]|zsleztl[TTVZTllk:97*)(u{{SKJJHFSKJ3+*SKJD;9F=Cf]crfkVTL|{tt~ddcsrejcVlldlldedk[TTmttulriek]lri|ztl{tt}|u{{[TTd\\VTL{{tultu{{u{{ttsfkkUMRb[Ulld{tt\UZ}VTLv{ult||redlksi\V[[Ttyglddult|uuf]c|ztlltslVZ[tzl[[T{u{ult|u|tts{{t{u{VTLlri{u{ddcultkd\u{{mtt{{||{{|{{t}~|\[[tt{{||}|ddc}}}UTSVTLb[Ulriuzttt{lri[TTultultult{{tlllrilks|zlksutf]c{{ult}tts{||{tt~||v{tzllkssreUTSddcnVZ[lks||ldd|||uzt{{{u{}{||sle[TT\[b]bZsletslVTLekdztlu[TTu{{llkUMR*)(\[[rg]bVUVTLVTLkd\tts|rfk~tzl|||[TTtt{kd\VTL{{tsl|uf]c[[T{{ttsmttek]{{tuztlriVTLlekttsslettsuztkk]r]Z}|kd\f]cJHFddcfkkf]cUMR{u{lldult[TT[TTrfk{{td\\|ultlks|u|tlllldkd\{u{|zuttslb[Uddctsluzt|u}v{{tlltts{||ttsutzll}{{ldd{u{}llk|u|}{{{{}|mtt}|ddcttsult|z|lkslks{{uuzttllmtt\[bmttmtttt{ultlks[TTuztVTLddcfkk{tt~lddyl{{ttslri{{|ztlult|z}|{{t{u{{u{tts{||lritt{ddcu{{\UZtsl{tt}ult}}{tt{{tt{llk{||ddcf]crfk||}|tslbVUf]c|u\UZ{zm|tts[[Ttsld\\|{||MRK:97{ttdc\D;9SKJVTLVTLf]c\UZbVZv{uzt{||slekd\ekdlkstzl}uztlrifkk||tts||\[[ekdtll\[[\[[mttv{ttVTLdc\rfklddtll{u{|tts|UTS{{tv{tllbVUVTL\[bttsult\[bllk}{{ttllddc|UTS|zVTL|zultrfkult}i\V|{{ttt{utlriztllriu{{lddlj|{||{tt{u{}}ldd}{{t}|uttskd\tts}tts|zlks{{|z|edklri||}||æ}lriultttsd\\{||f]c|tt{}u{{lks|mttlld[TTekd|||{{{{tekdek]ddckd\ult{u{ttsldd|tlllek|zuzt|sre{u{[TTtslultult{{t|||z}tt{lksmtt{{{{llk{{ttstsl{{t}rfkVTLtllVTL]bZ{||||tllf]c[[TddcMSS*)(tslb[U[[TaWMJHFSKJuztVTL[TTultddcdc\{zmlldcbVUTScbV}|\UZ{ttult}u{{tll|ttsztl{{tdc\tt{{tt{{tekd\[[srekd\||v{u{r]g|zddclkslldyld\\ttstlltll[[T[[T}|{ttlri|zVTLrfktllsreldd{ttUTSkd\UTS]bZu{{uzttlllld{{sle\[[|uztf]c|ttsddclek|{u{ttsttskd\edklld{||{{\[b|{{tt{{{{{lks}\UZ]cdldd|z|tt{||lriedk\UZttsttsmtt]bZlri|u{{\[[|zkd\lddu||SKJtt{u{{ultulttt{|{|||ult]bZ}UUY]cdldd{{{{t|zlek{{|lks|zuztulttt{tts}ut||dc\|urfkv{{||{tt|z]bZUTSsle[TTllkUTStt{LKRD;9lldkd\[TTVTLPF=VTLVTLf]cultf]cddc{{tdc\{u{kd\lrilldtslkd\VZTred{u{uztu{{|lddldd{tt]bZMSSlddkd\|{u{lks|zdc\}ldd}}lriUUY|z{{:97lksult|zult{{td\\mtt{{tllkrfk[[Tdc\}|}|{||u{{tsle||lek||}tll{{t|z|u{{tlld|zuztldd}lks|]bZUTS{u{{||tts{||mtt\[b||Ù|~|{u{{{||u{{ekd|tllmttd\\lksrfk}{{rfku{{llkekdlddztltt{ekd{{t}|tll|z|zmttrfk||fkk{||ddcultultrfk{{}{{}[[T{u{u{||edktzlult{tt|{{tts{{u{{|lld}|{{tddc|uJHFJHFlddttsult{{tlritsl[TTllkdc\ddcFD;:97UTS]bZd\\VTLSKJrg]lriyle{{tekdlrilldkk]]bZedktsluzt{||edk}{u{|{tttsl|lld{tt|mtt{{t{||[[Ttts\[[|z{{\[[ekdUTSf]cUTS|v[[Tlks{ttlks[[T}SKJr]gSKJUMRkd\}b[UultekdllkaWM}||{{}{u{zlluzt}|zlddtsllddlek||{ttuzt||uztllktt{|z{{{{tmtt|lks|Ī{{{{{{tts{{~ċ\[[tllf]cekd||}u{{tt{{u{{{tts{u{lrittstt{mtt{{mttlekrfku{{\[[|ztldc\lldkd\|lldu{{d\\||ult{{tllF=C}}z~}{tt|}{{llk|zuzt{u{|mtt|}llk{{|rg]VTLFD;[TTUTSekdlddztlllkllkdc\[[TUMRztlUTS:97:97sreb[UlddSKJsreD;9lddSKJldd{||lldsrezllf]csleutuultlld{tt||]bZlri||tsl|ut[[T[[T[[Ttsltsl{{tldd}ttstts~uzt|MSS\[[[TT]bZ[TTi\V|{u{{{t||{ttsrej]\leklddcbVrg]{{t{tttlltyg|uttslldmttdc\UTSf]cut|z{tt|u{||{||ddcultedk{{|zlks|}|||^fsх{{{{{{|ult}tsllksu{{mttmttlksddc{||}mttlkslrimtt}|lritsllri|{{tsre{{tredlld]bZ\[bUMR{{{{redv{}{u{||uzttsl|]bZ||tlltt{mttv{uzt}lksmttuztekdllktlltzlek][[Tlldslettsv{|ddcekdtslztlultdc\,55||FD;74,{{tlrif]c{zmlriFD;\[[VTL{|||zsle|zttsjV[tslrg]tslslej]\sle||lekllk{{ttzlllddc\|{||ek]b[U{ttlrivlri\[[ekduzt|utt{{{lri|kd\UTS\UZdc\[TTlldbVU{{t\[[lldVZTultyle}cbVkk]lri{zmzll[TTsreztlf]c]bZ|UTSlri]bZztl{||tsl||d\\{ttmtt{u{tt{}]cdtts{{lks||}{tt}|}{{|}}{{|zultmttttsuzt}edk|zmttUTS\[b]bZdc\tsl{{nv]cdd\\\[[|z{u{tllj]\|ldddc\|mtt|z}v{lks}v{{wltt{ylv{}ut}llktllulttt{~tzl}|}nvddcmttlksd\\lrilddd\\ekd{tt{{tddc{||}{tttzltts{zmj]\\UZUTSUTSJHF74,lridkVSKJVTLJHFbVZVTLbVUtllu{{d\\srelksztlkk]tslztlddclri{tt||ztlfkk{||tzl}]bZmtt{u{llk|zFD;MSSlrilri]bZ{{tlllkslddllkddctll\[bultuzt\[b}tsl}lks]bZUMR||b[Uultrg]LKR{ttkk]UTSlddVTL[TTUMRlriu{u{lld{||{tt|kd\tzl\[bek]tt{{{u{{|mttÙ}}{{|zulttt{tt{UTSultlksu{{}|lksekd]bZ]bZtsl}|mk\[b\[[kk]|zultztltlllri|zddcultttsek]]cdMRK}UMRv{~{{ultv{llk|zmttmttf]c|ek]\[bultllktts|{{}{{lksVZTJHF{ttultUTSu{{tlllld{{tedk||sletsl{||kk]SKJSKJaWM|ekd*)(kd\kk]bVUVTL:97D;9\UZbVUllk]bZtsl}f]ckd\mttcbVldd\[[ztlztllldmttcbV|dc\b[Ulld|]bZ]cdekdJHFu{{MRKVZ[llkkd\edk{||{{|lddldd{{lks|zllktslztlutUMRjcVj]\lddbVZ{|||z|uf]crfkrg]\[[ldddc\{||mtt|z{{t[TT\[[\[btsltts|||{||lek|redlldmttu{{uzt{u{{{lkstsl}{{u{{{{fkkmttu{{|mttmtt}~{||~~{u{|nv{u{|{|||u{{|ttsult{u{mtt}|mttfkk|mtt|z|ultmttleklldllk{||VTL}UTS[TTlldVTL{||utJHFtllJHFtslkd\lkstslu}JHFleksle}ttsuztlri\[blksu{{tsl\[b}f]c||~tt{{|||tts{tt{||mtt|uztlldf]clrilld{{tztl]cd\[[redVTL[[T|zrg]FD;[[Tdc\SKJ:97*)(UTSVTLaWMVTLSKJJHFf]ckk]llkSKJlrikd\zllrfkd\\lrilriVTL}yle|ubVUmtt{zm{{tkd\tts{{t{tt||z||lddlrilksekdmtttzlult||{{lrimtt}tt{|zredrg]lrifkk{{tlddsle|utsllri}|}|D;9||lldulttt{[[Tlddttslrid\\b[UJHFd\\lldtt{{ttuztkd\{{f]ctsl{{t{u{{ttult{{mtt||{{tt{]bZ]cd{{mttmttmtt{{nvmtt{{|lks{{}lrif]c{u{[TTedklekuztlks]bZlrimttmttmtt~u{{mtt{{{u{||ztllkk]lddb[U||{{tultlekdc\MRKllkrfkf]cf]cUMRtll{{||ultuzt||}mttlksVTL\[[u{{tslultttsult{{{{edk}mttVZ[tts{{uzt\[[tlltsl\[btts[TTztlVZTkd\VTLb[UyleUTS[TTJHF>ECSKJVTLJHF74,[TTrfk}b[U}f]cllklld{||UMR\[[VZTi\V]bZlriekdVTL|ztll|zfkktzlfkk[[Trg]ekd{{tll||{u{g\rUTSedkkd\u{{mttmttSKJult|z{u{ddcd\\{u{lddsleldd|z]cdred|cbVd\\f]c|zmttd\\\[[utttsu{{uztuztttsult|z{{t|||lri}mtt|zlkskd\{{Å|{{lks|}{{{{uzttsl|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{{{{lksttstll}uzt{{\[[d\\ek]d\\edkllklddtsllri[[TVTLb[Uultlddu{{UMR*)(aWMVTLd\\VTL[[TD;9[TTb[U{u{]bZ{{tttsztlSKJlld||tsltsluztddc|u{zmekdkd\ddc\[[lldttstygb[U}sle\[[|zlri|uzt]cdlri{{|z]bZf]c{{lrimttb[Ud\\\[[||lldlld{{lldtslsleekd|zldddc\tslj]\VTLv{u{{MRKVZT|uztsre}|z|z{||||{{ttsl|{{ultmttVZTtt{{{|}}}}~|lri|z}ultult|{{lldu{{uzttsl}|nv{{mtt{u{ttsekd}lddddckd\uzt{{SKJttsUMRdc\D;9{ttMRKsle{{}{{tll{{t}lrid\\kd\{tt|}}{{t{u{}|u{{mttu{{tlllks|{{f]c{||{tt{{{{lrilkstsl{ttlld{{tmttultkd\rfk{{]bZkk]tllVTLUTS]bZ]bZ:97}VTLtzli\VJHFi\VUMRVTL\[[\[[mttnv|uzttll}|bVUultlld]bZedk|sre{ttkd\bVUf]c}|z[TTtll[[Tllkd\\||}u{{edkVTL\[b\[bVTLdc\{||||ztlttsred]bZek]cbVllk]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]cSKJttstllztlddcttsekdlrilksSKJ]cd|[TTlriddc[[T{u{lksylttszll{|||ztsl{{{{|{tt}tt{lri|]bZmtttt{tllddcuztbVU\[[tsl|zsrecbVyfdlddred[[TJHF*)(kd\VTLek]VTLMRKD;9{{t[TTlddJHFVTL\[[tt{{u{{||zll}ekd|tts}tsllekkd\VZT\[[{ttSKJ{{tzll|u|ztsltlluzt{tt}u||\[bcbVnfkkbVZSKJzlttstllkd\}VTL|zlek[TTtsld\\]bZult[TTUMRultrfklri]bZUMR|lriVZT{tt{{|z|ztslult||[[Tfkkuzt}tts{||{{mtt{{nv|{{u{{f]c{u{}uztedk]cd|zVZ[mtt]cdddcuztfkklkslksUTSSKJtsl{{t]cd{{tuzt|ztts||fkktt{lrif]ctts[TT[[TVTL{u{ttsmtttzl{tt||}{u{{u{{||u{{{{lkslksttsf]c]cdlks|\[b|ttstsl{tt|tll{||uztlld|z[[TVTLJHFlld[[T]bZultUTS*)(dc\[[TJHFaWMD;9D;9jV[FD;JHF\[[b[Uf]cultd\\lek}tt{ultiq][[T}zl|ek]u{{}uttzl|}rg]j]\}zlllddek]mtt{{tttslri{u{|tll{{||lldMRKSKJF=C{{trfkr]ZtllbVU]bZekdsle{tttlluekdtlltllv{ult{u{\[[ultfkk>B9tll|cbVekdu{{||{{|ttszlllddmtttslttstt{{{ttts|{ttmttlriuzt|\[b}}{{~u{{lkskd\f]c|z|mttVZTnv|llku{{ult}f]c{|||zllk|z{{t]bZsle||dc\||\[[{tt\[b[TT}tzl|VTLek]JHF{u{{{{ttuzttsl}~tll|ztl|]bZ{|||u{{{{{ttu{{mtt]cd{{||b[Uekd{ttfkkZbN|z\UZekdSKJVTLldd[[Tdc\VTL:97*)(slejcVD;93+*JHF74,JHF[TTult}|ulldttsult||ult[[TttsUTS[[Tek]ddc{{|z|uultultultlksuzt\UZlritslek]{u{tsllri]cd?;C{tt[[Tsle{tt|ulriJHFddcdc\ddcd\\tlluVTL[TTttsd\\ultttsb[Uult[TTUMR[TTlri{||ttsekdfkk}|}}tllllkēmttuztztl{|||zu{{tslmtt{{|}|}}ã|vlks]cduztmttu{{{{tts|fkkmtt|{{edk]bZlks}|}rfk{{ttsl]bZ[[TUTS~u{{|uekd[[Tdc\u{{VZ[lrilekuztuzttsllrilriultd\\|tt{mwtslVTL{{{||}tslllklriult{{}tt{lks]bZ{{{u{{||f]cdc\SKJtsl|llk[TT[[TztlVTLsrett{d\\JHF*)(j]\cbVJHFSKJF=CF=C[[T[[TbVU}{{t||{u{tlllekllktll{zmdc\kd\{{t{{tlri]bZwl}||red|}sleSKJlektll~}\[bultleklritsld\\{ttddcv{mtttllb[Ud\\kd\b[UbVZdc\lddF=Cf]clekmttf]cmttttsu{{lri}|lldtsl{u{fkkuztf]c|{ttlld{{|{{}}|tt{{{tÜlkslek~mttlddmttUTS|mtt|ztt{{||{{lks{{ttllkk]uztVZTddclekbVZtslkd\lksVTL]bZtlluzt[TTtll]bZekdu{{{{{{|zlri{{{u{lld{u{v{ekd{{tzll||}|{{tts}f]cmttf]clri{{mtt]bZedkmtttt{dc\]cdu{{ttsllk{tt|zztl]cdlek[[T{{trg]VTL[[TSKJldd\[[*)(sleJHFbVZJHFJHFVTLVTLkd\[TT{{t||ttsrfk{{{{ttslllklrillkttsu{{f]c}}{{tek]lksfkk}ttstzld\\uzt]cdultttsd\\UUY|||zddcdc\UMRdc\mttrg]leklddlri{ttjcV[TTj]\ek][TT{tt}|llk{ttv{}|ztt{\[[]cd\[[||{||{||tsl|ztt{{||ekd}|zsle|ekd]bZ|zdc\}||{{{{{||{{|ultČlks]cdlksmttlri\[bmttmttult{{t{{{{t}tts{{t]bZ[[T|zuztllkf]c{{]bZek]tsl\[[JHFmttmtt|{||ddcztl[[T\[[}lld{{tllduzt}lkslld\[[tsl}uzt|{{lks{||VZ[{{||leklddlri{{[[T{{tsl{{t]bZ|{u{{zmedkddc[[Tdc\VTLztl\UZlddLKR*)(ztf{{t{ttUMRVTLj]\|zrg]v{f]ckd\tts{u{fkkv{tt{slekd\dc\ttsuztlks{u{tt{{||{tt\UZ|uf]ckk]{{t{{\[buzttslmttlkstsl{||SKJ\[[[TT|[[Tdc\tllkd\lkskd\uttzl|u{zmtsld\\kk]lld{{ultf]c||ult]cdlkslks{||lek}uċekd{||ult{{|ztts{||{||{ttlks}||}|{{|{u{\[bѣř{||u{{|mtt\[[tts}|mtt]cdfkkddc|ultlriv{||d\\[TTkd\kd\fkksre\UZJHFmtttts{{VTLb[Uutmtt\[b\[b|{||u{{|[[Tlld}}{{|u{tt{u{|{tt{ttmttunvmttmtttslvultmtttt{||uztu{{ultmttUUYult{{t{||]bZsle\[[UTS[[Tllkdc\VTLVTLVTLd\\jV[SKJ\[b74,red]bZlddekd[TTSKJ]bZSKJf]cb[Utslddcztl{{rfkvultdc\kk]{{tkk]dc\ult{{t|ud\\}[TTtzllri[[Tekdtsltlltts|z|zfkk}u{{{||uzt]cdJHFlksdc\[[TtllSKJtsl|zmtttllVTLsretll|{zmf]cllk{{t{ttUTSztl{ttllkf]ctllf]cSKJJHFultu{{JHFtt{}{tt{u{mttvdc\leklldkk]{||edk{{t||ult{{mtttts|ztt{uzt{{mk{{{{}lekd\\|}f]clks|z|z{{tfkkVZ[|{{^fs]cdmtt\[bult{{f]c||tslddcJHF|uutf]cult\[[lkstt{{ttultnv\[[]bZekd]bZJHFddcultkk]|{||tll||tslult\[[|SKJf]c|{||tslmttlks{{mtttslultyl\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]cSKJsletsl{zmu{{}[TTSKJ||bVZlddllk{u{SKJf]clkstt{MSS{u{||uddclkstslult{{t{||{{{{\[btt{{{mtt}}lksmk~tts{{t}ttsu{{|tsl]cdu{{{ttlks]cdUTS}nvmttVZ[\[b\[b|}\[[|}|{{{u{MRK{{f]cllkkd\{{lkslksmtt|z^fs\[[mttu{{{{t|zVTLtsltslVTLfkk{{ultuj]\u{{|f]cultLKR}lddtts}lekuzt{u{|lksmttlri|lriuztlekultd\\dc\UMRek]sle[TT]bZSKJ\[b[TTMSS-1+VTL[TTPF=UTSddc\[[lldutred|z|z||u{{{ttbVZlek{zmj]\VTLmttdc\tzl|{||lek}{{t{{t\[[}UMR}tt{|z{{fkk{{|zwlVTLtsl[TTlksvSKJ|zddc{||}lddj]\tts|vJHF[TT|urfk{{tultslettstll{ttMSSf]cult\[bldd{ttultf]clek|z{||||}lld|uzt{||mttedk|z|{{mttuztllkult||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{ttu{{u{{|z[TTtt{{{|u{{ekd{{t{||tllfkk{u{VZT|{||ddc|ultldd{tt|zekdddcUMRztlfkkSKJVTLdc\D;9JHFlldVTLlddJHF,55sled\\:97JHFredbVUlri{u{tllUTSVTLlriultf]cultult]bZ{{tsl]bZ|uf]clekultdc\llkVTLVZTlek{{UTSd\\{||tt{}ult{{tJHFf]cult{ttsleztlrfkredrr]sletts{||{{rfk{zm\UZJHFddc{{\UZLKR}{u{ldd|zmtt||lksut|u{||{tt[[Tmkuztlks{{Č}~mtt{{t{{t{{}]cd{||{{ult{{{{ttstt{{||]cdtts]cd|znmttlkslksultu{{}}}uztg\r}edk||f]c|{{|lks\[blksnv|z{{}|tlltsltslulttt{}mtt~mttfkk}ttsfkkttsu{{{{{{\[[mttmttUMRllk}mttuztUTSfkkUTSSKJ|ztsl[TTSKJ[[Trg]aWMlrilddcbVultLKR,55wl[TT\UZddcJHFtll[[Tultllk]bZtzl{ttult[TTtsl||SKJmtt|zttsek]lddllkd\\{||d\\mttJHFVZTbVZlksmtt|}}{{u{{lks{ttsle[[TUMR?;Cf]cSKJ}lekttstt{f]c|UMRkk]ztl}|VTLuztf]c||VTLlddldd[[Tekdd\\mttlks\[b{|||lksldd{{tts}|zu{{{{||||}tll}||tll{{{{љu{{b[Ulld{{||ult~|z|mttlkslddmtt|{{nv]cd|\[b|zlek\UZlkslek~}}lks}lks{||{{LKR{{\[b~|mttd\\lri}{{t||lks{u{|tllf]cfkklriu{{ultu{{{{|||mttlkslkslks]cddc\\[[dc\[TTultddcsre{ttlrikd\ztlVTLMSS:97tzl}ultSKJVTLVZTVTL[TT[[Tf]cutllkdc\lekb[Utts}tt{|||mtt|zuztlld|f]clksultult|zddc{ttJHFtsl|u|u{{|ttstt{}tlld\\iq]lriUMR|d\\llktlllri\UZ[TTsle}\[[ult}ztl\[[||]cdJHF[TTVZTVTL\[[ekdSKJ^fsmttSKJdc\lddult}|}{||uztllklldtll{||{{tzlltts\[b}ultu{{ulttt{lek{u{}{u{|v{}|lri{{|}mttlektt{v[TT{{t{{t{{tztl]bZ{{||tts{||JHFVZ[lksnMSSmttmtt{||fkk\[[|ldd}|nvultdc\tt{edkUUY{||{{mtt]cd\[b^fsmttmttmttf]cmtttslekduztUTS|utleklrid\\f]ccbVlddSKJlldUMRr]ZVTLOS`)+2|llkFD;[[TSKJFD;SKJVZTUMRJHFJHFtsllldredSKJ{||UTS\[bekd|z|tts{||mtt{||lri]cdvuztztl[TTztltts\[btsl{{{u{UTS|]bZ{{JHFddcult}|\[[d\\srelri{tt}|rfksrebVZdc\edksleddcu{{\[[ekdf]c\UZ|d\\|z[[T\[[\[bd\\{{td\\||lritts}{tt||||ttsUUY{{}Æ~uzttt{~{tt{||{tt}lks]cdlriddcult|uzt|Ìddcultult[TTtllekdiq]]bZekdkd\{{\[[ekdf]c{u{lksmtttt{||nek]|lksuztmtt{{lks{{~tll}|{{lksddc{u{{{tult|mtt|{{lksfkk\[b]cd\[b]cdfkkddcuzt]cdlri|z{||[TTb[Ukd\sleb[UyleyfdllkJHFaWMlriOS`*)(tts}{ttd\\sre{{tb[UVTL74,JHFFD;UTSVZTkd\redjV[{u{ekdmtt{{tult{{t|zu{{lkslri\UZuzt}[TTlri]cdddc{||UTStt{|tts{u{|uztultUTSlddztl|zek]{{:97f]c\[[{ttlld{u{|z{ttrfk{ttsref]cUMR[[TlriJHF||\[b{{ult]bZult}||mttekdtt{{||{||}{{t}u{{|{{ultmk}~ult|tll}|lks{ttVZ[{{]cdmttUUYultylf]cf]cwlddcJHF[[T|edkulttt{edkmtt}]cdMRK{{|OS`lri]bZLKR{{lksuztyl}edkttslekmttfkk{|||\[[f]c\[b]cd{{lks|}||lksVZTf]ckd\b[Uf]c[[Trg]red{{tekd]bZtslJHF,55mttlldbVUFD;b[Uzlekd[[TekdlriSKJlld}{u{{u{d\\UTSlks|zlrimttu{{mttllk\[[llk\[[ldd{tt{||lri{{ulttsl{{mtt|{||}}ult{{ttsdc\{{t{{t[[TlksJHFJHFd\\|z{{|utsl[TTrfkVTLrfkdc\FD;sleekd[TTkk]|lld}{u{JHF{{\[[UUY]bZ{u{SKJllkzlllek{||||}lldlri}ldd|z{{llklkslekmtt{{|{{ode-0.11.1/drawstuff/textures/checkered.ppm0000644000076400007640000002304010770757040015623 00000000000000P6 57 57 255 ode-0.11.1/drawstuff/textures/sky.ppm0000644000076400007640000014005307251560070014513 00000000000000P6 # Created by Paint Shop Pro 128 128 255 }}~~}}y{}}z~|zz~zz|~{y~~~~|{x|yz}~xvuwzzzzyw~{zz}wuttyzyxw{~~zy~||{xwvwvwz~|{~}}~|zwyxx|~~|{||zz~~~}y}~}z{~||}}~~||||yw|{{|wtz}||~~vsuz}xwvw}~~zxwz}}|{{}|}|z|~|wuux{{~zxvuw||}}}||yv||~z|||~~|{y~}}z{|~~|yz}~}||x{|}|}z}~ode-0.11.1/drawstuff/textures/wood.ppm0000644000076400007640000060005307251560070014656 00000000000000P6 # Created by Paint Shop Pro 256 256 255 ǿżŰ̻ÿǻʻǻŻÿ¸øŸۼƿ̼ÿÿʻõƼɿǾøشſ·ɻþǼƾŻǼʿƿÿǿٳſ̺ɿǼɿ»Ƽǿпƿпǵص̸Ǽǿ¾ſѾ׼ʾǸ¿ŵƻɿƿ̼¾׿Ƽ°»ºɺغǸۼſƿžؿ̼ƾ¿μſžÿúƸ¿¾žÿɻͿŸɿÿ»οüʿſ¿»ξǼſ¿μǸ¿¾ƾ׼δ¼ǻͻüп»ſŻžǼþÿþǿ¿ǿ¾þÿ¿¾úƿ¼̾źſº¼ƿѻŷ÷þþ׾ŷƵüſ¿¾ƸɵƼ¸ÿƺʵǼǻ¿ƾƼɺžžżƾƿſƾ÷ÿ̷ǻþ̿úƿÿԻżξþɸûпž̺Żí¾ǼʾʻŻñɼͿλпƻ¿ŻѼտúǾÿżԼԿʸѺǿÿſ̼;ͿռżԼƸǾſʼŵ¿ǺǺƾǿÿóοƾ»üѿǿƾÿƷҼƾü׻źþûѸܾҿûǿÿ·຺ƿÿ¾¸߾»żƻƸ߻þſҸмݺп̼Ƽ¼ſ¾;վÿٺԵλŵƾ¼¿ǷǸ¾»ܴѻǼúüʺ¼ưźžб׼Ƿ¼¾Ŵƾ¾ܵٿƼʼż´¾ƿº׾຺¾¾Ϳ;º̴¾ƺûɸžҸҿ;ƿǾ㸸Ե̸Żſ¸¼ÿ걱ƻ۾Ʊſ¼о»ǸµǷ߸ƿ¿Ǿؼ¿Ѻ¿¾ξûú侾ѵ¼¿ͺƿ¸Ƹ¾ƻǼվ¼üÿƴ۳һǼݾ¼ػƺɸ¿రưǸƸøſ·¼žõ¼ƿʿԾ÷·̼ƿ¿ƺ¿ƾ¸·̿Ʒ;ʼøſҾŵźҺǼͻþǿžտ±ŷɸžƿٳʼ̼ο¾¿÷þɸþſԷߴɼûþû÷żƸǺÿ¼ÿ¿»Я¾ſɼǻÿ¿üγɿƿɻǿÿɼż̼ſұǿ¿»ǺƵ¿ٸſɾſ¸ɾſǿºþغƾ̿¾¿λ¿¿Ǵƾſǵɼ»θƸ¿»ŵǾƿǿɻɺž¾żÿ¿úþµɺ¼¾ŵǻ¿ÿ¿Ǽɾ¼ÿƿ¿ſº¿ʺ¼źô俿ƺºŵžð¿Կúɻÿɿٻ»źƾξǾƻ⺺üξƻûǿƿÿǻÿ¾úµݵþǸ¿ǿ¼Ŵÿ¾ʨ¼¾ջƼƿÿɺþø¼¿ÿΰμ¾¿θѸ»º»¿´¿»ǿͼɼο¼ž¿üŷǸǼλ¿ÿŸ°Ƽ¾ø¿μ¿¿¾þɾžƿÿôŸ¼¿ż¼ÿ¿ƿſʼƿž¾ɸź¿ú¿ü¾û¿̿ʾ¾ø¾¿¾µǼſ¼µǼµƾƿÿ÷¿ƿƿ÷Żÿɺǿú÷¿¼ŷƿ¿ɼѾ¿¾üʿ¾üԱͿž¿Լ¼»¾ر¿÷Ÿüп¾ɿ̵þ¿Ǽҿ¿ʿ¸¿¿ɻɸþºҾ¿ż»Ǿпž¿¾¿ܿ̾·ÿƷǼɼ¿øƿþɻ¾㾾̼¼óɺú۷¼ñ뾾ɺǸ۷þɾ¾ų̺;¼̿謬ǾƼǿʺɿſżٺ¿ƿƼҾþżž̵¿ÿûʴݻǼ̼ü¿üƻƸݵÿǺ¾¸õƴٵɾ͸¾ͻƿپƻƾ»ƻƺ̼÷ѳǿ¾ſƸ¼һſƻ͸þѻʾξóοüƺͿ»۱̾Űеüʾíº¿ɾ㷷¾¾ƴ÷Ƽŭ¸ºŵ߷ɿƵ߼Ǹɼɵ¬ƿܷ̾´ݸºõ̻¿ŵ´üɷܺÿ;õžþƵƷƸαÿɻɷÿÿǸ¿»Ÿŭΰ¾Ŵʿþ໻ƿʸþǺſɾǷ͸ü̿Ƴ¿ⳳƿþþǴ俿ÿƺú´źźúǩÿźпʻ¾¾ſ¿ʼпʻ¿úÿкÿûþ¸ѻ;¸Żѱü۷ƿǿƿ´Իͺô¿ұÿþ¿̾ɸǿǺżͼºƴƸǿ߾ÿͻ³żûɾƳſ´ſհǺ״ſ̺¿¾ǿ¾̼ɿû³ÿץШǻƿøŻµ̻ɻôǿצɬúǾкþмѿŵ¾ըűþǾƻžźлƿѿǿêſõɱž̼¸ÿɻƿɾ׿ŭ¼μ¿̴¿¿οƻƼ¿ѺůǻоǬ̿¿ɻÿǿ̿ƻð¾ʼɵÿǻ¾Ϳþÿżűž¼ɾƯʿżôǰſüʿƯ躺Ǿ¯¸ÿüʼ绻žõ»Ŵͷɿ¼Ϳ̾ǿƺҿ¾λ¿»ЬɭʺǾ̿¾׾Ծ¿þ¸ҬƸƿ¿ƿׯŻɻž¼տ¾üҿٵ¸ÿ¿­翿DZ¼ʸܻÿŻÿ÷⼼ž¯¾ܼɷ¿ɸ¬»պǿ۷̿ǻǺñǺƸͿÿþ۱¼طÿǼǻۼѾ»Ǽ̯µ̷¿¿õʻ¿Ǽÿº̱¼ÿ¼ʿ¿Һ¿ʿͿǾʵŷǾƿ¼ú׻оſͰʼ¿ÿüظмʻͿ;еξ̾¼о¼Ǿ¿¿ǵƼʿοƿŻ¿;͵ۼŸտƺԸż̿ذƺſɾγŷݸ꿿ſɿ۵¼մоʼ󿿿ۼ¾ѿʿ¼¾үѻþվſǴǷоſƾ羾ʺʿ¾¿θƦοǾ྾ѾػǼŻ̼ûҨþͿûԾԴҺ¾߿СɾŻ»ÿº׻հһʻؼټШüǾɻƻǻݼ׺ŵü¿Һ¿ʨ¿ټźƿþغƵ̼ƺÿɾԻίɿǰǾžʼǺǺǿʿʸʼԩվƷ»ƻ྾ɿ̼ƾŷ̺似ŷ̿ſɳԸ̾»Ǿݵ¿ߵͿ»ø¾ҺƼŷǿŵǾ¾ܿǸɼǺſŴôξͿο¿̵ƸǾƿҾҿ뼼Һʴɿ¿þÿͷξóݻ۷̷ǿɻƺǸ¼Ǿƴ¾۸ε¿ÿþ̾ŻɷصʰǼиɻƺ̺ͬþûŸ±ƻƻͼ¢Ѵƿʸ㾾ƿ»̼üǸ¿̿ɰ»׻θ¸¼ŸкɼʰʿƯºƿԷǸշʱ·ͪ¿ǻƸþܸҴ¾¿лµͿ侾¾üſûҴл·»л俿ÿ¿þƻ׸ǷʿԿüþպ¾¾һͿԻ»»¿¿ɻƾžſżз̸Լ¼λ°¾÷տͿξŸ»оλúۿÿͿܸƾɰƳ¸Ƶ»ѾɼŸŵ⺺¿»ſվ¼ұƼ¼¿̷ƻ¿ݷþø㻻վ»ǵ¾ø¸ʸͿÿ׵ſٱѺƿǷžʰ¿̷ɻƺο¿̺üͼ·ǰ¾ԾƼDZÿƿƺ׵ÿԾſгԿ·þ׿õ¿źÿճɺſþű³»ü¾Ѻñп¿ɼ͵Ƽÿκ³Ƹû¿з·ſѺҺǾʿѷǴż»һ̼źԪžż¿¾һµõƾžþλ±þԯǼǻþѼҼ¼ÿǿμƾ¾Ԭÿ¿¿¿űʴ̾ƿſûܭɻѾ¿ѵǿúüƿ¿կпżƼƸ̻úƾ¾ñʻſ¼ðκºǺµҵ÷Ʒſÿʷ÷Ǹ̴ƾǾ¿¾ûþξ»Ϳܿ̿;ƿ¿ɾŸ״Ǿʵиſdzʼɼǵ׿»ÿξͼ̾Ѹʻż¿¿ѻƼ̾¿ſ¼¾̺øμεžſ̿ŻͻͼžżÿʻººþοøҼž»žͻɿű¾¿ž¾̿̿ۿŸżݼƺ͵¿ʿƴ¾ɳʹѸǸسǾǷ»¿ż¸ó̸¿ѿŻ绻ɿžǻʿ¸¿ʿú¸ŸžǾպ¼ƿǿ¿ɸ¿̼ƾѻƼþſүܾʾ̺ǿûԷƻԾ¼¼żƻÿɿø״ÿƷǭƿſ¿׼¿¿ƿ¿Ǿʺͼÿſżյþƿ¿ŵżһƿռξ»οžüбƾʿÿüκ¿Ƹ¼Żƿ¾ǿθŻûǵ¼ɳºǿ߾¼þüſ·μɻþѭѼɾʵþ·ǿž¿αͿɺ¼žŵžƿſ¼ÿƾǾ̷ʿοúɯ¾ÿҺؿǼǿſ⼼¼þôǷÿǾдźѾÿþüżſǾſɺſüа¿ſѿ;ÿǾÿƾ»¿иܴ̻»¿¾ʷƾſźºž¿ûºüǺóþſþŵºż¸ƿǼѴ³̾ÿþ»ôп¾žþǸüʵ¿¿̸þ̸¾üʼƻƵƸſƸ¿ôÿþžûмǻʿ;̻žɷƿƿ¿ʾøþɸƯ»ѸʻŻɵ»ſɼ±ǿλҼð̺Ƹžɻɼÿοÿ°¿žپ׼þɿ»۾žŻûƾƾ¿Ǽغ͸һǿ¿ۼú¾ʾ»ÿǿ·¸¾¾ԿżǷͻŷþ¿λ¸»ûÿÿξǿ̻ſ¾ô»Ƽɺɿ¾ƻƿ̿¾ɻ¾мɼǺؼ̼ɷɾÿɸŵÿ̾ſøźδ̷¸ûžƾױſ¾¾ɺʴɯɾǾ̴Ƽµ̷¼ƸÿƱ¼ƾÿɻƼ۴Ժ̼¿ɳƸͻ¿иźżû±ǵμ·¼¾¿¿ǾƼ¿ɻú¸͸ſô³Ʊǿûžûƻ¾¿»ɼʻԷŵ·ǼżüÿԿŻƿ±ƻɻǿŷξſ̿¾̸ͻҷøɼ»ʿ¿Ÿüٿſɼ¼Żͺ¿ż¸λƵƿʿŰƾ¾͸ƸɼžŴú׷żüʿҷ÷ŷǾͱɾ¿̷Ƹóż»ƺԸƿŵżƼηžʹоʿѼǴξøñǿ¿ѿɾ´¼żô¿ʺûƺƸп̺Ѱðűɿɴ¿͵õú»¸̺»ž¾Хƿǻ׾ʵ¾Ʊ̾¿ǼʿüǿDZ¼Żʷ¿þžûүǼɴ¿ƿο¾Ǫ¼µÿʾºƾǸ¼Կ¿ɺúɼͺɾѾǻþŪ´û¿ǾžøջóżǭƿʸǾͿþʿſ;ɿǾÿ¿ƺƼʿ¿̷ʻüؾ̱ƺɸ߿þ¬̿þ»Ǿíƻվ¾ʿÿ۾мͻɼ̺úſ÷°Ǽ¿þ»ŸͰµʺ¿пźº̾ʼ¿ǿ¿¬оʷʼ·ͼǿúεɿƾоÿż»þ̺ͿпøûƸžʾþʾտʸũտſðҸǼ¸žпƺÿüɺѿ;þƾλÿŸ·¾̿ƻþſξ»վ·¿ÿ⻻ſ¬ø¼̺̿ѿɼÿɻƾǾ»ⳳ¿ʻ¼κ¼þ̾з͸οſ´人ºðºƸ̸ûѴпºûżܿž㷷ǿ¼ʴ¾Ƽɺθ;ɾʷδξ̻Ǽʾ侾зƿɺγصѿаʸ̺¼̿໻͵žÿźſÿҷ̻ǿ¾þ似㿿̴̿¿ú̾ʾɷºɿƻøµ侾ʴɼüͿഴξǼ;ǿ°ɾƸ㾾ѿ̾ǻžѳ̺ɿ͸ǿƾƿǺǴſ÷Ǽ¼ߴοԺ¸ɿǿǿκ¾ʹÿûž糳Ǽü´ºŷ¾׿¾ź¾ɺؿ̱ode-0.11.1/missing0000755000076400007640000002557711206343422010706 00000000000000#! /bin/sh # Common stub for a few missing GNU programs while installing. scriptversion=2006-05-10.23 # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006 # Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 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, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, 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. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' sed_minuso='s/.* -o \([^ ]*\).*/\1/p' # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi msg="missing on your system" case $1 in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 # Exit code 63 means version mismatch. This often happens # when the user try to use an ancient version of a tool on # a file that requires a minimum version. In this case we # we should proceed has if the program had been absent, or # if --run hadn't been passed. if test $? = 63; then run=: msg="probably too old" fi ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' autom4te touch the output file, or create a stub one automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch] Send bug reports to ." 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 # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect # the program). case $1 in lex|yacc) # Not GNU programs, they don't have --version. ;; tar) if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then exit 1 fi ;; *) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then # Could not run --version or --help. This is probably someone # running `$TOOL --version' or `$TOOL --help' to check whether # $TOOL exists and not knowing $TOOL uses missing. exit 1 fi ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case $1 in aclocal*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case $f in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te) echo 1>&2 "\ WARNING: \`$1' is needed, but is $msg. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' $msg. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if test $# -ne 1; then eval LASTARG="\${$#}" case $LASTARG in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.h fi ;; esac fi if test ! -f y.tab.h; then echo >y.tab.h fi if test ! -f y.tab.c; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if test $# -ne 1; then eval LASTARG="\${$#}" case $LASTARG in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if test ! -f lex.yy.c; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." # The file to touch is that specified with -o ... file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -z "$file"; then # ... or it is the one specified with @setfilename ... infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n ' /^@setfilename/{ s/.* \([^ ]*\) *$/\1/ p q }' $infile` # ... or it is derived from the source name (dir/f.texi becomes f.info) test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info fi # If the file does not exist, the user really needs makeinfo; # let's fail without touching anything. test -f $file || exit 1 touch $file ;; tar) shift # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case $firstarg in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case $firstarg in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and is $msg. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: ode-0.11.1/ode.pc.in0000644000076400007640000000036111054335173010774 00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: ode Description: Open Dynamics Engine Version: @ODE_RELEASE@ Libs: -L${libdir} -lode Libs.private: -lstdc++ -lm Cflags: -I${includedir} @ODE_PRECISION@ ode-0.11.1/configure0000755000076400007640000256140311206343413011211 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.63 for ODE 0.11.1. # # Report bugs to . # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008 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 # PATH needs CR # 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_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 if (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 # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false 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. 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); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # Required to use basename. 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 # Name of the executable. 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'` # CDPATH. $as_unset CDPATH if test "x$CONFIG_SHELL" = x; then if (eval ":") 2>/dev/null; then as_have_required=yes else as_have_required=no fi if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=\$LINENO as_lineno_2=\$LINENO test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } ") 2> /dev/null; then : else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in /*) for as_base in sh bash ksh sh5; do as_candidate_shells="$as_candidate_shells $as_dir/$as_base" done;; esac done IFS=$as_save_IFS for as_shell in $as_candidate_shells $SHELL; do # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF 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 : _ASEOF }; then CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF 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_func_return () { (exit $1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = "$1" ); then : else exitcode=1 echo positional parameters were not saved. fi test $exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } _ASEOF }; then break fi fi done if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test $as_have_required = no; then echo This script requires a shell more modern than all the echo shells that I found on your system. Please install a echo modern shell, or manually run the script under such a echo shell if you do have one. { (exit 1); exit 1; } fi fi fi (eval "as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0") || { echo No shell found that supports shell functions. echo Please tell bug-autoconf@gnu.org about your system, echo including any error possibly output before this message. echo This can help us improve future autoconf versions. echo Configuration will now proceed without shell functions. } as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. 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 { (exit 1); exit 1; }; } # 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 } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi 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 -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' 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=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # 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'" # Check that we are running under the correct shell. SHELL=${CONFIG_SHELL-/bin/sh} case X$lt_ECHO in X*--fallback-echo) # Remove one level of quotation (which was required for Make). ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` ;; esac ECHO=${lt_ECHO-echo} if test "X$1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X$1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then # Yippee, $ECHO works! : else # Restart under the correct shell. exec $SHELL "$0" --no-reexec ${1+"$@"} fi if test "X$1" = X--fallback-echo; then # used as fallback echo shift cat <<_LT_EOF $* _LT_EOF exit 0 fi # 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 if test -z "$lt_ECHO"; then if test "X${echo_test_string+set}" != Xset; then # find a string as large as possible, as long as the shell can cope with it for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... if { echo_test_string=`eval $cmd`; } 2>/dev/null && { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null then break fi done fi if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then : else # The Solaris, AIX, and Digital Unix default echo programs unquote # backslashes. This makes it impossible to quote backslashes using # echo "$something" | sed 's/\\/\\\\/g' # # So, first we look for a working echo in the user's PATH. lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for dir in $PATH /usr/ucb; do IFS="$lt_save_ifs" if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then ECHO="$dir/echo" break fi done IFS="$lt_save_ifs" if test "X$ECHO" = Xecho; then # We didn't find a better echo, so look for alternatives. if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # This shell has a builtin print -r that does the trick. ECHO='print -r' elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && test "X$CONFIG_SHELL" != X/bin/ksh; then # If we have ksh, try running configure again with it. ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} export ORIGINAL_CONFIG_SHELL CONFIG_SHELL=/bin/ksh export CONFIG_SHELL exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} else # Try using printf. ECHO='printf %s\n' if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # Cool, printf works : elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL export CONFIG_SHELL SHELL="$CONFIG_SHELL" export SHELL ECHO="$CONFIG_SHELL $0 --fallback-echo" elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then ECHO="$CONFIG_SHELL $0 --fallback-echo" else # maybe with a smaller string... prev=: for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null then break fi prev="$cmd" done if test "$prev" != 'sed 50q "$0"'; then echo_test_string=`eval $prev` export echo_test_string exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} else # Oops. We lost completely, so just stick with echo. ECHO=echo fi fi fi fi fi fi # Copy echo and quote the copy suitably for passing to libtool from # the Makefile, instead of quoting the original, which is used later. lt_ECHO=$ECHO if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" fi exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, 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= SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='ODE' PACKAGE_TARNAME='ode' PACKAGE_VERSION='0.11.1' PACKAGE_STRING='ODE 0.11.1' PACKAGE_BUGREPORT='ode@ode.org' # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" enable_option_checking=no ac_subst_vars='LTLIBOBJS ENABLE_OU_FALSE ENABLE_OU_TRUE subdirs LIBOBJS ALLOCA ENABLE_DEMOS_FALSE ENABLE_DEMOS_TRUE LIBSTDCXX GL_LIBS X_EXTRA_LIBS X_LIBS X_PRE_LIBS X_CFLAGS XMKMF OSX_FALSE OSX_TRUE X11_FALSE X11_TRUE WIN32_FALSE WIN32_TRUE ENABLE_DRAWSTUFF_FALSE ENABLE_DRAWSTUFF_TRUE 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 ac_ct_WINDRES WINDRES CXXCPP OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL lt_ECHO RANLIB 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 AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CXX CPPFLAGS LDFLAGS CXXFLAGS CXX 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_RELEASE 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 localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix 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_dependency_tracking enable_shared enable_static with_pic enable_fast_install with_gnu_ld enable_libtool_lock enable_demos with_trimesh enable_double_precision with_drawstuff with_x enable_old_trimesh enable_gprof enable_malloc enable_ou enable_asserts ' ac_precious_vars='build_alias host_alias target_alias CXX CXXFLAGS LDFLAGS LIBS CPPFLAGS CCC CC CFLAGS CPP CXXCPP XMKMF' ac_subdirs_all='ou' # 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' 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=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_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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 ;; -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_echo "$as_me: error: invalid package name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: invalid package name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2 { (exit 1); exit 1; }; } ;; *) $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 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_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } 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 $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 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_echo "$as_me: error: working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || { $as_echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } # 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_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } 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.11.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] --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 X features: --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR 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.11.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 --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --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) --disable-demos don't build demos --enable-double-precision Configure ODE to work with double precision, if not specified, single precision is used --enable-old-trimesh enable use of the old trimesh collider --enable-gprof enable profiling with gprof --enable-malloc use malloc to emulate alloca (more portable but slower) --enable-ou EXPERIMENTAL: use TLS for global variables to allow for running ODE in multiple threads simultaneously --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 try to use only PIC/non-PIC objects [default=use both] --with-gnu-ld assume the C compiler uses GNU ld [default=no] --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. --with-x use the X Window System Some influential environment variables: CXX C++ compiler command CXXFLAGS C++ compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if you have headers in a nonstandard directory CC C compiler command CFLAGS C compiler flags CPP C preprocessor CXXCPP C++ preprocessor XMKMF Path to xmkmf, Makefile generator for X Window System 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 . _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.11.1 generated by GNU Autoconf 2.63 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 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 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.11.1, which was generated by GNU Autoconf 2.63. 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) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$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 ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export 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 cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX 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:$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= ;; #( *) $as_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 cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX 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 cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX 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 cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX 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'; { (exit 1); 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 # 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 # 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 ac_site_file1=$CONFIG_SITE 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 -r "$ac_site_file"; then { $as_echo "$as_me:$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" 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. if test -f "$cache_file"; then { $as_echo "$as_me:$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:$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:$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:$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:$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:$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:$LINENO: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:$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. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:$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_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 $as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } 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_CONFIG_SRCDIR([ode/src/ode.cpp]) ODE_RELEASE=0.11.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=2 REVISION=1 AGE=1 # 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_echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 $as_echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 $as_echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} { (exit 1); exit 1; }; } { $as_echo "$as_me:$LINENO: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if test "${ac_cv_build+set}" = set; 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_echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 $as_echo "$as_me: error: cannot guess build type; you must specify one" >&2;} { (exit 1); exit 1; }; } ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 $as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} { (exit 1); exit 1; }; } fi { $as_echo "$as_me:$LINENO: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 $as_echo "$as_me: error: invalid value of canonical build" >&2;} { (exit 1); exit 1; }; };; 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:$LINENO: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if test "${ac_cv_host+set}" = set; 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_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 $as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} { (exit 1); exit 1; }; } fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 $as_echo "$as_me: error: invalid value of canonical host" >&2;} { (exit 1); exit 1; }; };; 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.10' # 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:$LINENO: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; 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 { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$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:$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:$LINENO: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Just in case sleep 1 echo timestamp > conftest.file # 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 ( 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 rm -f conftest.file 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_echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&5 $as_echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&2;} { (exit 1); exit 1; }; } fi test "$2" = conftest.file ) then # Ok. : else { { $as_echo "$as_me:$LINENO: error: newly created file is older than distributed files! Check your system clock" >&5 $as_echo "$as_me: error: newly created file is older than distributed files! Check your system clock" >&2;} { (exit 1); exit 1; }; } fi { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } 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` test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { $as_echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi { $as_echo "$as_me:$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 test "${ac_cv_path_mkdir+set}" = set; 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 { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$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 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. test -d ./--version && rmdir ./--version MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:$LINENO: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } mkdir_p="$MKDIR_P" case $mkdir_p in [\\/$]* | ?:[\\/]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_AWK+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:$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 { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; 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:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:$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 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_echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 $as_echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} { (exit 1); exit 1; }; } 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.11.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"} install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} # 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_STRIP+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:$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:$LINENO: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:$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:$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" # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. AMTAR=${AMTAR-"${am_missing_run}tar"} am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' ac_config_headers="$ac_config_headers ode/src/config.h" { $as_echo "$as_me:$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 { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; 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:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CXX+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CXX+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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:$LINENO: checking for C++ compiler default output file name" >&5 $as_echo_n "checking for C++ compiler default output file name... " >&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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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 { $as_echo "$as_me:$LINENO: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } if test -z "$ac_file"; then $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: C++ compiler cannot create executables See \`config.log' for more details." >&5 $as_echo "$as_me: error: C++ compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; }; } fi ac_exeext=$ac_cv_exeext # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:$LINENO: checking whether the C++ compiler works" >&5 $as_echo_n "checking whether the C++ compiler works... " >&6; } # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi fi fi { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } { $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } { $as_echo "$as_me:$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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi rm -f conftest$ac_cv_exeext { $as_echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT { $as_echo "$as_me:$LINENO: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if test "${ac_cv_objext+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:$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 test "${ac_cv_cxx_compiler_gnu+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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:$LINENO: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if test "${ac_cv_prog_cxx_g+set}" = set; 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CXXFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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 done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:$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 # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi { $as_echo "$as_me:$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='\' 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:$LINENO: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; 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'. 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 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 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in 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 ;; none) break ;; esac # 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. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} 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 sub/conftest.${OBJEXT-o} 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:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 $as_echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } # Provide some information about the compiler. $as_echo "$as_me:$LINENO: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { $as_echo "$as_me:$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 test "${ac_cv_c_compiler_gnu+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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:$LINENO: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if test "${ac_cv_prog_cc_g+set}" = set; 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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:$LINENO: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* 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" 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$LINENO: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:$LINENO: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; 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 depcc="$CC" am_compiler_list= { $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if test "${am_cv_CC_dependencies_compiler_type+set}" = set; 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'. 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 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 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in 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 ;; none) break ;; esac # 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. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} 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 sub/conftest.${OBJEXT-o} 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:$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 if test "x$CC" != xcc; then { $as_echo "$as_me:$LINENO: checking whether $CC and cc understand -c and -o together" >&5 $as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } else { $as_echo "$as_me:$LINENO: checking whether cc understands -c and -o together" >&5 $as_echo_n "checking whether cc understands -c and -o together... " >&6; } fi set dummy $CC; ac_cc=`$as_echo "$2" | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` if { as_var=ac_cv_prog_cc_${ac_cc}_c_o; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # We do the test twice because some compilers refuse to overwrite an # existing .o file with -o, though they will create one. ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' rm -f conftest2.* if { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -f conftest2.$ac_objext && { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then eval ac_cv_prog_cc_${ac_cc}_c_o=yes if test "x$CC" != xcc; then # Test first that cc exists at all. if { ac_try='cc -c conftest.$ac_ext >&5' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' rm -f conftest2.* if { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -f conftest2.$ac_objext && { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # cc works too. : else # cc exists but doesn't like -o. eval ac_cv_prog_cc_${ac_cc}_c_o=no fi fi fi else eval ac_cv_prog_cc_${ac_cc}_c_o=no fi rm -f core conftest* fi if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } cat >>confdefs.h <<\_ACEOF #define NO_MINUS_C_MINUS_O 1 _ACEOF fi # FIXME: we rely on the cache variable name because # there is no other way. set dummy $CC am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o if test "$am_t" != 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 { $as_echo "$as_me:$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 test "${ac_cv_prog_CPP+set}" = set; 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 to if __STDC__ is defined, since # 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f 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:$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 to if __STDC__ is defined, since # 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 $as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_AWK+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done # 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:$LINENO: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; 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 { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$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:$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:$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:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:$LINENO: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi { $as_echo "$as_me:$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 test "${ac_cv_path_mkdir+set}" = set; 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 { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$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 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. test -d ./--version && rmdir ./--version MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:$LINENO: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } # 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_AS+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AS="${ac_tool_prefix}as" $as_echo "$as_me:$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:$LINENO: result: $AS" >&5 $as_echo "$AS" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_AS+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_AS="as" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_AS" >&5 $as_echo "$ac_ct_AS" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_DLLTOOL+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:$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:$LINENO: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_DLLTOOL+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_OBJDUMP+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:$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:$LINENO: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:$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:$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:$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.2.6' macro_revision='1.3012' ltmain="$ac_aux_dir/ltmain.sh" { $as_echo "$as_me:$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 test "${ac_cv_path_SED+set}" = set; 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 $as_unset ac_script || 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" { test -f "$ac_path_SED" && $as_test_x "$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 ac_count=`expr $ac_count + 1` 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_echo "$as_me:$LINENO: error: no acceptable sed could be found in \$PATH" >&5 $as_echo "$as_me: error: no acceptable sed could be found in \$PATH" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:$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:$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 test "${ac_cv_path_GREP+set}" = set; 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" { test -f "$ac_path_GREP" && $as_test_x "$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 ac_count=`expr $ac_count + 1` 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_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 $as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:$LINENO: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if test "${ac_cv_path_EGREP+set}" = set; 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" { test -f "$ac_path_EGREP" && $as_test_x "$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 ac_count=`expr $ac_count + 1` 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_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 $as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:$LINENO: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if test "${ac_cv_path_FGREP+set}" = set; 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" { test -f "$ac_path_FGREP" && $as_test_x "$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 ac_count=`expr $ac_count + 1` 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_echo "$as_me:$LINENO: error: no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 $as_echo "$as_me: error: no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:$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 "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:$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 "$with_gnu_ld" = yes; then { $as_echo "$as_me:$LINENO: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:$LINENO: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if test "${lt_cv_path_LD+set}" = set; 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 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && { { $as_echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 $as_echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} { (exit 1); exit 1; }; } { $as_echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if test "${lt_cv_prog_gnu_ld+set}" = set; 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 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:$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 test "${lt_cv_path_NM+set}" = set; 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 case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) 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:$LINENO: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$ac_tool_prefix"; then for ac_prog in "dumpbin -symbols" "link -dump -symbols" 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_DUMPBIN+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:$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 -symbols" "link -dump -symbols" 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:$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:$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 if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:$LINENO: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if test "${lt_cv_nm_interface+set}" = set; 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:5850: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:5853: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:5856: 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:$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:$LINENO: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if test "${lt_cv_sys_max_cmd_len+set}" = set; 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; ;; 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; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # 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 ;; 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"; 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"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ = "XX$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 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:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:$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"} { $as_echo "$as_me:$LINENO: checking whether the shell understands some XSI constructs" >&5 $as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes { $as_echo "$as_me:$LINENO: result: $xsi_shell" >&5 $as_echo "$xsi_shell" >&6; } { $as_echo "$as_me:$LINENO: checking whether the shell understands \"+=\"" >&5 $as_echo_n "checking whether the shell understands \"+=\"... " >&6; } lt_shell_append=no ( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes { $as_echo "$as_me:$LINENO: result: $lt_shell_append" >&5 $as_echo "$lt_shell_append" >&6; } 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:$LINENO: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if test "${lt_cv_ld_reload_flag+set}" = set; then $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:$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 darwin*) if test "$GCC" = yes; 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_OBJDUMP+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:$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:$LINENO: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if test "${lt_cv_deplibs_check_method+set}" = set; 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 # which 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 lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' 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 ;; gnu*) 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]) 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 Linux ELF. linux* | k*bsd*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd*) 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*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; 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 ;; esac fi { $as_echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } 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}ar", so it can be a program name with args. set dummy ${ac_tool_prefix}ar; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_AR+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AR="${ac_tool_prefix}ar" $as_echo "$as_me:$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:$LINENO: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_AR"; then ac_ct_AR=$AR # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_AR+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_AR="ar" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:$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 else AR="$ac_cv_prog_AR" fi test -z "$AR" && AR=ar test -z "$AR_FLAGS" && AR_FLAGS=cru 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_STRIP+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:$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:$LINENO: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_RANLIB+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:$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:$LINENO: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:$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:$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 openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" fi # 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:$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 test "${lt_cv_sys_global_symbol_pipe+set}" = set; 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 "$host_cpu" = ia64; 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 # 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 -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$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 -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/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 # and D for any global 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};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print 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 # 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:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Now try to grab the symbols. nlist=conftest.nm if { (eval echo "$as_me:$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:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && 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 #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. */ const struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$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_save_LIBS="$LIBS" lt_save_CFLAGS="$CFLAGS" LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS="$lt_save_LIBS" CFLAGS="$lt_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 "$pipe_works" = yes; 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:$LINENO: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:$LINENO: result: ok" >&5 $as_echo "ok" >&6; } fi # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then enableval=$enable_libtool_lock; fi test "x$enable_libtool_lock" != xno && 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 which ABI we are using. echo 'int i;' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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 which ABI we are using. echo '#line 7048 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then if test "$lt_cv_prog_gnu_ld" = yes; 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* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|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" ;; ppc*-*linux*|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:$LINENO: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if test "${lt_cv_cc_needs_belf+set}" = set; 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then lt_cv_cc_needs_belf=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 lt_cv_cc_needs_belf=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ 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:$LINENO: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; sparc*-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) LD="${LD-ld} -m elf64_sparc" ;; *) 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" 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_DSYMUTIL+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:$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:$LINENO: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_NMEDIT+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:$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:$LINENO: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_LIPO+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:$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:$LINENO: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_OTOOL+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:$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:$LINENO: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_OTOOL64+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:$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:$LINENO: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if test "${lt_cv_apple_cc_single_mod+set}" = set; 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 test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; 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:$LINENO: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:$LINENO: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if test "${lt_cv_ld_exported_symbols_list+set}" = set; 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then lt_cv_ld_exported_symbols_list=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 lt_cv_ld_exported_symbols_list=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:$LINENO: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&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 "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; 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" != ":"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac { $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if test "${ac_cv_header_stdc+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #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 rm -f 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : 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 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF 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` { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = 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 as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CXX+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CXX+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { $as_echo "$as_me:$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 test "${ac_cv_cxx_compiler_gnu+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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:$LINENO: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if test "${ac_cv_prog_cxx_g+set}" = set; 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CXXFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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 depcc="$CXX" am_compiler_list= { $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; 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'. 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 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 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in 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 ;; none) break ;; esac # 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. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} 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 sub/conftest.${OBJEXT-o} 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:$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 if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; 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:$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 test "${ac_cv_prog_CXXCPP+set}" = set; 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 to if __STDC__ is defined, since # 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f 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:$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 to if __STDC__ is defined, since # 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} _lt_caught_CXX_error=yes; } 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 # Set options 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; pic_mode="$withval" else pic_mode=default fi test -z "$pic_mode" && pic_mode=default # 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 # 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:$LINENO: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if test "${lt_cv_objdir+set}" = set; 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:$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 "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # 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. 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' # 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 for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` # 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:$LINENO: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if test "${lt_cv_path_MAGIC_CMD+set}" = set; 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:$LINENO: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if test "${lt_cv_path_MAGIC_CMD+set}" = set; 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:$LINENO: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:$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 "$GCC" = yes; then lt_prog_compiler_no_builtin_flag=' -fno-builtin' { $as_echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; 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" # 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:9352: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:9356: \$? = $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 "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/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:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; 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= { $as_echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if test "$GCC" = yes; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi ;; 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' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; 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 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 "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; 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' ;; 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) 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' ;; pgcc* | pgf77* | pgf90* | pgf95*) # 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*) # IBM XL C 8.0/Fortran 10.1 on PPC lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Sun\ F*) # 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='' ;; 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*) 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 which 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:$LINENO: result: $lt_prog_compiler_pic" >&5 $as_echo "$lt_prog_compiler_pic" >&6; } # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:$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 test "${lt_cv_prog_compiler_pic_works+set}" = set; 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" # 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:9691: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:9695: \$? = $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 "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/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:$LINENO: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test x"$lt_cv_prog_compiler_pic_works" = xyes; 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:$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 test "${lt_cv_prog_compiler_static_works+set}" = set; 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 "X$_lt_linker_boilerplate" | $Xsed -e '/^$/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:$LINENO: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test x"$lt_cv_prog_compiler_static_works" = xyes; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:$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 test "${lt_cv_prog_compiler_c_o+set}" = set; 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:9796: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:9800: \$? = $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 "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/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:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:$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 test "${lt_cv_prog_compiler_c_o+set}" = set; 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:9851: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:9855: \$? = $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 "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/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:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:$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:$LINENO: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:$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:$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_flag_spec_ld= 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 "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac ld_shlibs=yes if test "$with_gnu_ld" = yes; 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 2>&1` in *\ [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 "$host_cpu" != ia64; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.9.1, 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 modify your PATH *** so that a non-GNU linker is found, and then restart. _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 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' 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/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' 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 (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; 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 ;; 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) tmp_diet=no if test "$host_os" = linux-dietlibc; 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 "$tmp_diet" = no then tmp_addflag= 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; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95*) # 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; $ECHO \"$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' ;; xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; 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; $ECHO \"$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 "x$supports_anon_versioning" = xyes; 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 xlf*) # 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= hardcode_libdir_flag_spec_ld='-rpath $libdir' archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; 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 $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd*) 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 $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' 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 $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 ;; 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 can not *** 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 $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 if test "$ld_shlibs" = no; 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 "$GCC" = yes && 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 "$host_cpu" = ia64; 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 AIX nm, but means don't demangle with GNU 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")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | 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 # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; 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,' if test "$GCC" = yes; 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 "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi link_all_deplibs=no else # not using gcc if test "$host_cpu" = ia64; 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 "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi 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_use_runtimelinking" = yes; 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. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/ p } }' 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 "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; 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 "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; 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. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/ p } }' 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 "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; 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' # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' archive_cmds_need_lc=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' 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. 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 `$ECHO "X$deplibs" | $Xsed -e '\''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' fix_srcfile_path='`cygpath -w "$srcfile"`' enable_shared_with_static_runtimes=yes ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported whole_archive_flag_spec='' link_all_deplibs=yes allow_undefined_flag="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=echo 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 ;; freebsd1*) ld_shlibs=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 -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $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 $output_objdir/$soname = $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 "$GCC" = yes -a "$with_gnu_ld" = no; then archive_cmds='$CC -shared -fPIC ${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 "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_flag_spec_ld='+b $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 "$GCC" = yes -a "$with_gnu_ld" = no; 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 -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared -fPIC ${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' ;; *) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; 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 "$GCC" = yes; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${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. save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" cat >conftest.$ac_ext <<_ACEOF int foo(void) {} _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -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 ;; netbsd*) 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*) 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__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; 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 case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-R$libdir' ;; *) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; 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" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${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" && $ECHO "X-set_version $verstring" | $Xsed` -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 "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${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" && $ECHO "X-set_version $verstring" | $Xsed` -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 "X-set_version $verstring" | $Xsed` -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 "$GCC" = yes; then wlarc='${wl}' archive_cmds='$CC -shared ${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 ${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 "$GCC" = yes; 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 "x$host_vendor" = xsequent; 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 "$GCC" = yes; 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 can NOT 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 "$GCC" = yes; 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 x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='${wl}-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:$LINENO: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test "$ld_shlibs" = no && 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 "$enable_shared" = yes && test "$GCC" = yes; 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:$LINENO: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } 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:$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:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } then archive_cmds_need_lc=no else archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* { $as_echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5 $as_echo "$archive_cmds_need_lc" >&6; } ;; esac fi ;; esac { $as_echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then # 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 -e 's/;/ /g'` else lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # 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` 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" else 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; } }'` sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` 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 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 need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; 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 # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.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}' else # 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' fi 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=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $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 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,$host_os in yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) 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="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. 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 ;; 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 ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # 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 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 ;; freebsd1*) dynamic_linker=no ;; 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[123]*) 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} $libname${shared_ext}' 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 ;; 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 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 "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; 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' ;; interix[3-9]*) 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' 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 "$lt_cv_prog_gnu_ld" = yes; then version_type=linux 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 ;; # This must be Linux ELF. linux* | k*bsd*-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' 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 save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then shlibpath_overrides_runpath=yes fi else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir # 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 # find out which ABI we are using libsuff= case "$host_cpu" in x86_64*|s390x*|powerpc64*) echo '#line 11708 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then case `/usr/bin/file conftest.$ac_objext` in *64-bit*) libsuff=64 ;; esac fi rm -rf conftest* ;; esac sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff}" # Append ld.so.conf contents 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;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $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' ;; 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 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*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac 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 if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; 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 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 "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux 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 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=freebsd-elf 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 "$with_gnu_ld" = yes; 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 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 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:$LINENO: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:$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 "X$hardcode_automatic" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct" != no && # 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 "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && test "$hardcode_minus_L" != no; 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:$LINENO: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test "$hardcode_action" = relink || test "$inherit_rpath" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi if test "x$enable_dlopen" != xyes; 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:$LINENO: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if test "${ac_cv_lib_dl_dlopen+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_dl_dlopen=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlopen=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = x""yes; 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 ;; *) { $as_echo "$as_me:$LINENO: checking for shl_load" >&5 $as_echo_n "checking for shl_load... " >&6; } if test "${ac_cv_func_shl_load+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define shl_load to an innocuous variant, in case declares shl_load. For example, HP-UX 11i declares gettimeofday. */ #define shl_load innocuous_shl_load /* System header to define __stub macros and hopefully few prototypes, which can conflict with char shl_load (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef shl_load /* 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 (); /* 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_shl_load || defined __stub___shl_load choke me #endif int main () { return shl_load (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_shl_load=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_shl_load=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 $as_echo "$ac_cv_func_shl_load" >&6; } if test "x$ac_cv_func_shl_load" = x""yes; then lt_cv_dlopen="shl_load" else { $as_echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if test "${ac_cv_lib_dld_shl_load+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_dld_shl_load=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_shl_load=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$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" = x""yes; then lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else { $as_echo "$as_me:$LINENO: checking for dlopen" >&5 $as_echo_n "checking for dlopen... " >&6; } if test "${ac_cv_func_dlopen+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define dlopen to an innocuous variant, in case declares dlopen. For example, HP-UX 11i declares gettimeofday. */ #define dlopen innocuous_dlopen /* System header to define __stub macros and hopefully few prototypes, which can conflict with char dlopen (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef dlopen /* 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 (); /* 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_dlopen || defined __stub___dlopen choke me #endif int main () { return dlopen (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_dlopen=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_dlopen=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 $as_echo "$ac_cv_func_dlopen" >&6; } if test "x$ac_cv_func_dlopen" = x""yes; then lt_cv_dlopen="dlopen" else { $as_echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if test "${ac_cv_lib_dl_dlopen+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_dl_dlopen=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlopen=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = x""yes; then lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else { $as_echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if test "${ac_cv_lib_svld_dlopen+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_svld_dlopen=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_svld_dlopen=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = x""yes; then lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else { $as_echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if test "${ac_cv_lib_dld_dld_link+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_dld_dld_link=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_dld_link=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$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" = x""yes; then lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" fi fi fi fi fi fi ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && 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:$LINENO: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if test "${lt_cv_dlopen_self+set}" = set; then $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; 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 12674 "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #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 void fnord() { int i=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; /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && 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:$LINENO: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:$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 test "${lt_cv_dlopen_self_static+set}" = set; then $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; 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 12770 "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #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 void fnord() { int i=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; /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && 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:$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:$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:$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:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report which library types will actually be built { $as_echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:$LINENO: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test "$can_build_shared" = "no" && 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 "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac { $as_echo "$as_me:$LINENO: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:$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 "$enable_shared" = yes || enable_static=yes { $as_echo "$as_me:$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" 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_flag_spec_ld_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 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 "$_lt_caught_CXX_error" != yes; 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_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++"} compiler=$CC compiler_CXX=$CC for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' else lt_prog_compiler_no_builtin_flag_CXX= fi if test "$GXX" = yes; 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 "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:$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 "$with_gnu_ld" = yes; then { $as_echo "$as_me:$LINENO: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:$LINENO: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if test "${lt_cv_path_LD+set}" = set; 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 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && { { $as_echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 $as_echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} { (exit 1); exit 1; }; } { $as_echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if test "${lt_cv_prog_gnu_ld+set}" = set; 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 &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 "$with_gnu_ld" = yes; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -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 "\-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:$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 "$host_cpu" = ia64; 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 # need to do runtime linking. 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 ;; 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,' if test "$GXX" = yes; 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 "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; 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 "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi 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_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag_CXX='-berok' # Determine the default libpath from the value encoded in an empty # executable. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/ p } }' 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 "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; 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 "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; 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. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/ p } }' 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 "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; 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' # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec_CXX='$convenience' archive_cmds_need_lc_CXX=yes # This is similar to how AIX traditionally builds its shared # libraries. archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag_CXX=unsupported # Joseph Beckenbach 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*) # _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' 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 (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; 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 ;; darwin* | rhapsody*) archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes hardcode_shlibpath_var_CXX=unsupported whole_archive_flag_spec_CXX='' link_all_deplibs_CXX=yes allow_undefined_flag_CXX="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=echo 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 "$lt_cv_apple_cc_single_mod" != "yes"; 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 ;; 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 ;; freebsd[12]*) # 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 ;; gnu*) ;; 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 $output_objdir/$soname = $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; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes; then archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; 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; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; 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 -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${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" && $ECHO "X-set_version $verstring" | $Xsed` -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 "$GXX" = yes; then if test "$with_gnu_ld" = no; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -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) 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; $ECHO "X$list" | $Xsed' 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 | $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 | $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 | $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 | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 will 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; $ECHO \"$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=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; xl*) # 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 "x$supports_anon_versioning" = xyes; 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; $ECHO \"$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='echo' # 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 ;; openbsd2*) # C++ shared libraries are fairly broken ld_shlibs_CXX=no ;; openbsd*) 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__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; 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=echo 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" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -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" && $ECHO "X-set_version $verstring" | $Xsed` -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 "X-set_version $verstring" | $Xsed` -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=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; 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" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${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 "\-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*) # 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='echo' # 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 "$GXX" = yes && test "$with_gnu_ld" = no; then no_undefined_flag_CXX=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $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 -nostdlib ${wl}-M $wl$lib.exp -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 "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $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 -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 "\-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 can NOT 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' ;; *) 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:$LINENO: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } test "$ld_shlibs_CXX" = no && 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 if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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 $p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue else prev= fi if test "$pre_test_object_deps_done" = no; then case $p 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 ;; *.$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 "$pre_test_object_deps_done" = no; 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 # 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= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then postdeps_CXX='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then postdeps_CXX='-library=Cstd -library=Crun' fi ;; esac ;; 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= { $as_echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; 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 "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' fi ;; 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' ;; 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= ;; 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 "$host_cpu" = ia64; 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 ;; 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 "$host_cpu" != ia64; 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) 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*) # IBM XL 8.0 on PPC 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*) ;; *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*) # 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 which 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:$LINENO: result: $lt_prog_compiler_pic_CXX" >&5 $as_echo "$lt_prog_compiler_pic_CXX" >&6; } # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic_CXX"; then { $as_echo "$as_me:$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 test "${lt_cv_prog_compiler_pic_works_CXX+set}" = set; 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" # 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:14790: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:14794: \$? = $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 "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/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:$LINENO: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 $as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; 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:$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 test "${lt_cv_prog_compiler_static_works_CXX+set}" = set; 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 "X$_lt_linker_boilerplate" | $Xsed -e '/^$/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:$LINENO: result: $lt_cv_prog_compiler_static_works_CXX" >&5 $as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then : else lt_prog_compiler_static_CXX= fi { $as_echo "$as_me:$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 test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; 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:14889: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:14893: \$? = $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 "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/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:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5 $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } { $as_echo "$as_me:$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 test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; 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:14941: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:14945: \$? = $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 "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/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:$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 "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:$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:$LINENO: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:$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:$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' 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 AIX nm, but means don't demangle with GNU 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")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) export_symbols_cmds_CXX="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;/^.*[ ]__nm__/s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' ;; linux* | k*bsd*-gnu) link_all_deplibs_CXX=no ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' { $as_echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } test "$ld_shlibs_CXX" = no && 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 "$enable_shared" = yes && test "$GCC" = yes; 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:$LINENO: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } 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:$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:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } then archive_cmds_need_lc_CXX=no else 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* { $as_echo "$as_me:$LINENO: result: $archive_cmds_need_lc_CXX" >&5 $as_echo "$archive_cmds_need_lc_CXX" >&6; } ;; esac fi ;; esac { $as_echo "$as_me:$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 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 need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; 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 # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.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}' else # 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' fi 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=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $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 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,$host_os in yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) 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="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. 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 ;; 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 ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # 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 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 ;; freebsd1*) dynamic_linker=no ;; 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[123]*) 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} $libname${shared_ext}' 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 ;; 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 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 "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; 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' ;; interix[3-9]*) 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' 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 "$lt_cv_prog_gnu_ld" = yes; then version_type=linux 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 ;; # This must be Linux ELF. linux* | k*bsd*-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' 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 save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then shlibpath_overrides_runpath=yes fi else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir # 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 # find out which ABI we are using libsuff= case "$host_cpu" in x86_64*|s390x*|powerpc64*) echo '#line 15595 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then case `/usr/bin/file conftest.$ac_objext` in *64-bit*) libsuff=64 ;; esac fi rm -rf conftest* ;; esac sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff}" # Append ld.so.conf contents 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;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $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' ;; 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 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*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac 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 if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; 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 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 "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux 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 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=freebsd-elf 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 "$with_gnu_ld" = yes; 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 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 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:$LINENO: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:$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 "X$hardcode_automatic_CXX" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct_CXX" != no && # 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 "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && test "$hardcode_minus_L_CXX" != no; 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:$LINENO: result: $hardcode_action_CXX" >&5 $as_echo "$hardcode_action_CXX" >&6; } if test "$hardcode_action_CXX" = relink || test "$inherit_rpath_CXX" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi fi # test -n "$compiler" CC=$lt_save_CC 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 "$_lt_caught_CXX_error" != yes 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_WINDRES+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_WINDRES="$ac_tool_prefix$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $WINDRES" >&5 $as_echo "$WINDRES" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_WINDRES+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_WINDRES="$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_WINDRES" >&5 $as_echo "$ac_ct_WINDRES" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking whether byte ordering is bigendian" >&5 $as_echo_n "checking whether byte ordering is bigendian... " >&6; } if test "${ac_cv_c_bigendian+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_c_bigendian=unknown # See if we're dealing with a universal compiler. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifndef __APPLE_CC__ not a universal capable compiler #endif typedef int dummy; _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then # Check for potential -arch flags. It is not universal unless # there are some -arch flags. Note that *ppc* also matches # ppc64. This check is also rather less than ideal. case "${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}" in #( *-arch*ppc*|*-arch*i386*|*-arch*x86_64*) ac_cv_c_bigendian=universal;; esac else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then # It does; now see whether it defined to BIG_ENDIAN or not. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_bigendian=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then # It does; now see whether it defined to _BIG_ENDIAN or not. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { #ifndef _BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_bigendian=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; 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 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 rm -f 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_bigendian=no 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 ( exit $ac_status ) ac_cv_c_bigendian=yes fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 $as_echo "$ac_cv_c_bigendian" >&6; } case $ac_cv_c_bigendian in #( yes) cat >>confdefs.h <<\_ACEOF #define WORDS_BIGENDIAN 1 _ACEOF ;; #( no) ;; #( universal) cat >>confdefs.h <<\_ACEOF #define AC_APPLE_UNIVERSAL_BUILD 1 _ACEOF ;; #( *) { { $as_echo "$as_me:$LINENO: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&5 $as_echo "$as_me: error: unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} { (exit 1); exit 1; }; } ;; esac { $as_echo "$as_me:$LINENO: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if test "${ac_cv_c_inline+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_inline=$ac_kw else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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:$LINENO: checking for working volatile" >&5 $as_echo_n "checking for working volatile... " >&6; } if test "${ac_cv_c_volatile+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { volatile int x; int * volatile y = (int *) 0; return !x && !y; ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_volatile=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_volatile=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_c_volatile" >&5 $as_echo "$ac_cv_c_volatile" >&6; } if test $ac_cv_c_volatile = no; then cat >>confdefs.h <<\_ACEOF #define volatile /**/ _ACEOF fi { $as_echo "$as_me:$LINENO: checking for stdbool.h that conforms to C99" >&5 $as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } if test "${ac_cv_header_stdbool_h+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #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]; bool e = &s; 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]; # if defined __xlc__ || defined __GNUC__ /* Catch a bug in IBM AIX xlc compiler version 6.0.0.0 reported by James Lemley on 2005-10-05; see http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html This test is not quite right, since xlc is allowed to reject this program, as the initializer for xlcbug is not one of the forms that C requires support for. However, doing the test right would require a runtime test, and that would make cross-compilation harder. Let us hope that IBM fixes the xlc bug, and also adds support for this kind of constant expression. In the meantime, this test will reject xlc, which is OK, since our stdbool.h substitute should suffice. We also test this with GCC, where it should work, to detect more quickly whether someone messes up the test in the future. */ char digs[] = "0123456789"; int xlcbug = 1 / (&(digs + 5)[-2 + (bool) 1] == &digs[4] ? 1 : -1); # endif /* 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 () { *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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdbool_h=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdbool_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdbool_h" >&5 $as_echo "$ac_cv_header_stdbool_h" >&6; } { $as_echo "$as_me:$LINENO: checking for _Bool" >&5 $as_echo_n "checking for _Bool... " >&6; } if test "${ac_cv_type__Bool+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_type__Bool=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if (sizeof (_Bool)) return 0; ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if (sizeof ((_Bool))) return 0; ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type__Bool=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_type__Bool" >&5 $as_echo "$ac_cv_type__Bool" >&6; } if test "x$ac_cv_type__Bool" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE__BOOL 1 _ACEOF fi if test $ac_cv_header_stdbool_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_STDBOOL_H 1 _ACEOF fi { $as_echo "$as_me:$LINENO: checking for size_t" >&5 $as_echo_n "checking for size_t... " >&6; } if test "${ac_cv_type_size_t+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_type_size_t=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if (sizeof (size_t)) return 0; ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if (sizeof ((size_t))) return 0; ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_size_t=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 $as_echo "$ac_cv_type_size_t" >&6; } if test "x$ac_cv_type_size_t" = x""yes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi { $as_echo "$as_me:$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 { $as_echo "$as_me:$LINENO: result: $enable_demos" >&5 $as_echo "$enable_demos" >&6; } pentium=no cpu64=no case "$host_cpu" in i586 | i686 | i786 ) pentium=yes cat >>confdefs.h <<\_ACEOF #define PENTIUM 1 _ACEOF ;; x86_64* ) pentium=yes cpu64=yes cat >>confdefs.h <<\_ACEOF #define X86_64_SYSTEM 1 _ACEOF ;; 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 stdint.h stdlib.h math.h string.h stdarg.h malloc.h float.h time.h sys/time.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## -------------------------- ## ## Report this to ode@ode.org ## ## -------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = 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:$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; precision=$enableval else precision=no fi { $as_echo "$as_me:$LINENO: result: $precision" >&5 $as_echo "$precision" >&6; } if test "$precision" = yes; then ODE_PRECISION=-DdDOUBLE else ODE_PRECISION=-DdSINGLE fi CPPFLAGS+=" $ODE_PRECISION" # 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 if test x$drawstuff != xnone; then ENABLE_DRAWSTUFF_TRUE= ENABLE_DRAWSTUFF_FALSE='#' else ENABLE_DRAWSTUFF_TRUE='#' ENABLE_DRAWSTUFF_FALSE= 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 { $as_echo "$as_me:$LINENO: checking which drawstuff lib to build" >&5 $as_echo_n "checking which drawstuff lib to build... " >&6; } { $as_echo "$as_me:$LINENO: result: $drawstuff" >&5 $as_echo "$drawstuff" >&6; } if test "x$drawstuff" = "xX11" then { $as_echo "$as_me:$LINENO: checking for X" >&5 $as_echo_n "checking for X... " >&6; } # Check whether --with-x was given. if test "${with_x+set}" = set; then withval=$with_x; fi # $have_x is `yes', `no', `disabled', or empty when we do not yet know. if test "x$with_x" = xno; then # The user explicitly disabled X. have_x=disabled else case $x_includes,$x_libraries in #( *\'*) { { $as_echo "$as_me:$LINENO: error: cannot use X directory names containing '" >&5 $as_echo "$as_me: error: cannot use X directory names containing '" >&2;} { (exit 1); exit 1; }; };; #( *,NONE | NONE,*) if test "${ac_cv_have_x+set}" = set; then $as_echo_n "(cached) " >&6 else # One or both of the vars are not set, and there is no cached value. ac_x_includes=no ac_x_libraries=no rm -f -r conftest.dir if mkdir conftest.dir; then cd conftest.dir cat >Imakefile <<'_ACEOF' incroot: @echo incroot='${INCROOT}' usrlibdir: @echo usrlibdir='${USRLIBDIR}' libdir: @echo libdir='${LIBDIR}' _ACEOF if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then # GNU make sometimes prints "make[1]: Entering...", which would confuse us. for ac_var in incroot usrlibdir libdir; do eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`" done # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. for ac_extension in a so sl dylib la dll; do if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" && test -f "$ac_im_libdir/libX11.$ac_extension"; then ac_im_usrlibdir=$ac_im_libdir; break fi done # Screen out bogus values from the imake configuration. They are # bogus both because they are the default anyway, and because # using them would break gcc on systems where it needs fixed includes. case $ac_im_incroot in /usr/include) ac_x_includes= ;; *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; esac case $ac_im_usrlibdir in /usr/lib | /usr/lib64 | /lib | /lib64) ;; *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; esac fi cd .. rm -f -r conftest.dir fi # Standard set of common directories for X headers. # Check X11 before X11Rn because it is often a symlink to the current release. ac_x_header_dirs=' /usr/X11/include /usr/X11R6/include /usr/X11R5/include /usr/X11R4/include /usr/include/X11 /usr/include/X11R6 /usr/include/X11R5 /usr/include/X11R4 /usr/local/X11/include /usr/local/X11R6/include /usr/local/X11R5/include /usr/local/X11R4/include /usr/local/include/X11 /usr/local/include/X11R6 /usr/local/include/X11R5 /usr/local/include/X11R4 /usr/X386/include /usr/x386/include /usr/XFree86/include/X11 /usr/include /usr/local/include /usr/unsupported/include /usr/athena/include /usr/local/x11r5/include /usr/lpp/Xamples/include /usr/openwin/include /usr/openwin/share/include' if test "$ac_x_includes" = no; then # Guess where to find include files, by looking for Xlib.h. # First, try using that file with no special directory specified. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # We can compile using X headers with no special include directory. ac_x_includes= else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 for ac_dir in $ac_x_header_dirs; do if test -r "$ac_dir/X11/Xlib.h"; then ac_x_includes=$ac_dir break fi done fi rm -f conftest.err conftest.$ac_ext fi # $ac_x_includes = no if test "$ac_x_libraries" = no; then # Check for the libraries. # See if we find them without any special options. # Don't add to $LIBS permanently. ac_save_LIBS=$LIBS LIBS="-lX11 $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { XrmInitialize () ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then LIBS=$ac_save_LIBS # We can link X programs with no special library path. ac_x_libraries= else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 LIBS=$ac_save_LIBS for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` do # Don't even attempt the hair of trying to link an X program! for ac_extension in a so sl dylib la dll; do if test -r "$ac_dir/libX11.$ac_extension"; then ac_x_libraries=$ac_dir break 2 fi done done fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi # $ac_x_libraries = no case $ac_x_includes,$ac_x_libraries in #( no,* | *,no | *\'*) # Didn't find X, or a directory has "'" in its name. ac_cv_have_x="have_x=no";; #( *) # Record where we found X for the cache. ac_cv_have_x="have_x=yes\ ac_x_includes='$ac_x_includes'\ ac_x_libraries='$ac_x_libraries'" esac fi ;; #( *) have_x=yes;; esac eval "$ac_cv_have_x" fi # $with_x != no if test "$have_x" != yes; then { $as_echo "$as_me:$LINENO: result: $have_x" >&5 $as_echo "$have_x" >&6; } no_x=yes else # If each of the values was on the command line, it overrides each guess. test "x$x_includes" = xNONE && x_includes=$ac_x_includes test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries # Update the cache value to reflect the command line values. ac_cv_have_x="have_x=yes\ ac_x_includes='$x_includes'\ ac_x_libraries='$x_libraries'" { $as_echo "$as_me:$LINENO: result: libraries $x_libraries, headers $x_includes" >&5 $as_echo "libraries $x_libraries, headers $x_includes" >&6; } fi if test "$no_x" = yes; then # Not all programs may use this symbol, but it does not hurt to define it. cat >>confdefs.h <<\_ACEOF #define X_DISPLAY_MISSING 1 _ACEOF X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS= else if test -n "$x_includes"; then X_CFLAGS="$X_CFLAGS -I$x_includes" fi # It would also be nice to do this for all -L options, not just this one. if test -n "$x_libraries"; then X_LIBS="$X_LIBS -L$x_libraries" # For Solaris; some versions of Sun CC require a space after -R and # others require no space. Words are not sufficient . . . . { $as_echo "$as_me:$LINENO: checking whether -R must be followed by a space" >&5 $as_echo_n "checking whether -R must be followed by a space... " >&6; } ac_xsave_LIBS=$LIBS; LIBS="$LIBS -R$x_libraries" ac_xsave_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } X_LIBS="$X_LIBS -R$x_libraries" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 LIBS="$ac_xsave_LIBS -R $x_libraries" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } X_LIBS="$X_LIBS -R $x_libraries" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { $as_echo "$as_me:$LINENO: result: neither works" >&5 $as_echo "neither works" >&6; } fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext ac_c_werror_flag=$ac_xsave_c_werror_flag LIBS=$ac_xsave_LIBS fi # Check for system-dependent libraries X programs must link with. # Do this before checking for the system-independent R6 libraries # (-lICE), since we may need -lsocket or whatever for X linking. if test "$ISC" = yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl_s -linet" else # Martyn Johnson says this is needed for Ultrix, if the X # libraries were built with DECnet support. And Karl Berry says # the Alpha needs dnet_stub (dnet does not exist). ac_xsave_LIBS="$LIBS"; LIBS="$LIBS $X_LIBS -lX11" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 XOpenDisplay (); int main () { return XOpenDisplay (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { $as_echo "$as_me:$LINENO: checking for dnet_ntoa in -ldnet" >&5 $as_echo_n "checking for dnet_ntoa in -ldnet... " >&6; } if test "${ac_cv_lib_dnet_dnet_ntoa+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldnet $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 dnet_ntoa (); int main () { return dnet_ntoa (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_dnet_dnet_ntoa=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dnet_dnet_ntoa=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_dnet_dnet_ntoa" >&5 $as_echo "$ac_cv_lib_dnet_dnet_ntoa" >&6; } if test "x$ac_cv_lib_dnet_dnet_ntoa" = x""yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" fi if test $ac_cv_lib_dnet_dnet_ntoa = no; then { $as_echo "$as_me:$LINENO: checking for dnet_ntoa in -ldnet_stub" >&5 $as_echo_n "checking for dnet_ntoa in -ldnet_stub... " >&6; } if test "${ac_cv_lib_dnet_stub_dnet_ntoa+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldnet_stub $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 dnet_ntoa (); int main () { return dnet_ntoa (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_dnet_stub_dnet_ntoa=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dnet_stub_dnet_ntoa=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5 $as_echo "$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; } if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = x""yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" fi fi fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS="$ac_xsave_LIBS" # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT, # to get the SysV transport functions. # Chad R. Larson says the Pyramis MIS-ES running DC/OSx (SVR4) # needs -lnsl. # The nsl library prevents programs from opening the X display # on Irix 5.2, according to T.E. Dickey. # The functions gethostbyname, getservbyname, and inet_addr are # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking. { $as_echo "$as_me:$LINENO: checking for gethostbyname" >&5 $as_echo_n "checking for gethostbyname... " >&6; } if test "${ac_cv_func_gethostbyname+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define gethostbyname to an innocuous variant, in case declares gethostbyname. For example, HP-UX 11i declares gettimeofday. */ #define gethostbyname innocuous_gethostbyname /* System header to define __stub macros and hopefully few prototypes, which can conflict with char gethostbyname (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef gethostbyname /* 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 gethostbyname (); /* 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_gethostbyname || defined __stub___gethostbyname choke me #endif int main () { return gethostbyname (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_gethostbyname=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_gethostbyname=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5 $as_echo "$ac_cv_func_gethostbyname" >&6; } if test $ac_cv_func_gethostbyname = no; then { $as_echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5 $as_echo_n "checking for gethostbyname in -lnsl... " >&6; } if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_nsl_gethostbyname=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_nsl_gethostbyname=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5 $as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } if test "x$ac_cv_lib_nsl_gethostbyname" = x""yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" fi if test $ac_cv_lib_nsl_gethostbyname = no; then { $as_echo "$as_me:$LINENO: checking for gethostbyname in -lbsd" >&5 $as_echo_n "checking for gethostbyname in -lbsd... " >&6; } if test "${ac_cv_lib_bsd_gethostbyname+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbsd $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 gethostbyname (); int main () { return gethostbyname (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_bsd_gethostbyname=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_bsd_gethostbyname=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_bsd_gethostbyname" >&5 $as_echo "$ac_cv_lib_bsd_gethostbyname" >&6; } if test "x$ac_cv_lib_bsd_gethostbyname" = x""yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd" fi fi fi # lieder@skyler.mavd.honeywell.com says without -lsocket, # socket/setsockopt and other routines are undefined under SCO ODT # 2.0. But -lsocket is broken on IRIX 5.2 (and is not necessary # on later versions), says Simon Leinen: it contains gethostby* # variants that don't use the name server (or something). -lsocket # must be given before -lnsl if both are needed. We assume that # if connect needs -lnsl, so does gethostbyname. { $as_echo "$as_me:$LINENO: checking for connect" >&5 $as_echo_n "checking for connect... " >&6; } if test "${ac_cv_func_connect+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define connect to an innocuous variant, in case declares connect. For example, HP-UX 11i declares gettimeofday. */ #define connect innocuous_connect /* System header to define __stub macros and hopefully few prototypes, which can conflict with char connect (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef connect /* 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 connect (); /* 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_connect || defined __stub___connect choke me #endif int main () { return connect (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_connect=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_connect=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5 $as_echo "$ac_cv_func_connect" >&6; } if test $ac_cv_func_connect = no; then { $as_echo "$as_me:$LINENO: checking for connect in -lsocket" >&5 $as_echo_n "checking for connect in -lsocket... " >&6; } if test "${ac_cv_lib_socket_connect+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $X_EXTRA_LIBS $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 connect (); int main () { return connect (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_socket_connect=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_socket_connect=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_socket_connect" >&5 $as_echo "$ac_cv_lib_socket_connect" >&6; } if test "x$ac_cv_lib_socket_connect" = x""yes; then X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" fi fi # Guillermo Gomez says -lposix is necessary on A/UX. { $as_echo "$as_me:$LINENO: checking for remove" >&5 $as_echo_n "checking for remove... " >&6; } if test "${ac_cv_func_remove+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define remove to an innocuous variant, in case declares remove. For example, HP-UX 11i declares gettimeofday. */ #define remove innocuous_remove /* System header to define __stub macros and hopefully few prototypes, which can conflict with char remove (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef remove /* 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 remove (); /* 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_remove || defined __stub___remove choke me #endif int main () { return remove (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_remove=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_remove=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_remove" >&5 $as_echo "$ac_cv_func_remove" >&6; } if test $ac_cv_func_remove = no; then { $as_echo "$as_me:$LINENO: checking for remove in -lposix" >&5 $as_echo_n "checking for remove in -lposix... " >&6; } if test "${ac_cv_lib_posix_remove+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lposix $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 remove (); int main () { return remove (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_posix_remove=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_posix_remove=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_posix_remove" >&5 $as_echo "$ac_cv_lib_posix_remove" >&6; } if test "x$ac_cv_lib_posix_remove" = x""yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" fi fi # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. { $as_echo "$as_me:$LINENO: checking for shmat" >&5 $as_echo_n "checking for shmat... " >&6; } if test "${ac_cv_func_shmat+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define shmat to an innocuous variant, in case declares shmat. For example, HP-UX 11i declares gettimeofday. */ #define shmat innocuous_shmat /* System header to define __stub macros and hopefully few prototypes, which can conflict with char shmat (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef shmat /* 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 shmat (); /* 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_shmat || defined __stub___shmat choke me #endif int main () { return shmat (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_shmat=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_shmat=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_shmat" >&5 $as_echo "$ac_cv_func_shmat" >&6; } if test $ac_cv_func_shmat = no; then { $as_echo "$as_me:$LINENO: checking for shmat in -lipc" >&5 $as_echo_n "checking for shmat in -lipc... " >&6; } if test "${ac_cv_lib_ipc_shmat+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lipc $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 shmat (); int main () { return shmat (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_ipc_shmat=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ipc_shmat=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_ipc_shmat" >&5 $as_echo "$ac_cv_lib_ipc_shmat" >&6; } if test "x$ac_cv_lib_ipc_shmat" = x""yes; then X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" fi fi fi # Check for libraries that X11R6 Xt/Xaw programs need. ac_save_LDFLAGS=$LDFLAGS test -n "$x_libraries" && LDFLAGS="$LDFLAGS -L$x_libraries" # SM needs ICE to (dynamically) link under SunOS 4.x (so we have to # check for ICE first), but we must link in the order -lSM -lICE or # we get undefined symbols. So assume we have SM if we have ICE. # These have to be linked with before -lX11, unlike the other # libraries we check for below, so use a different variable. # John Interrante, Karl Berry { $as_echo "$as_me:$LINENO: checking for IceConnectionNumber in -lICE" >&5 $as_echo_n "checking for IceConnectionNumber in -lICE... " >&6; } if test "${ac_cv_lib_ICE_IceConnectionNumber+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lICE $X_EXTRA_LIBS $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 IceConnectionNumber (); int main () { return IceConnectionNumber (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_ICE_IceConnectionNumber=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ICE_IceConnectionNumber=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5 $as_echo "$ac_cv_lib_ICE_IceConnectionNumber" >&6; } if test "x$ac_cv_lib_ICE_IceConnectionNumber" = x""yes; then X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" fi LDFLAGS=$ac_save_LDFLAGS fi fi if test "x$drawstuff" = "xOSX"; then cat >>confdefs.h <<\_ACEOF #define HAVE_APPLE_OPENGL_FRAMEWORK 1 _ACEOF GL_LIBS="-framework OpenGL -framework Carbon -framework AGL" else 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` { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef WIN32 #include #endif #if HAVE_GL_GL_H #include #endif #if HAVE_GL_GLU_H #include #endif #include <$ac_header> _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = 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:$LINENO: checking for main in -lGL" >&5 $as_echo_n "checking for main in -lGL... " >&6; } if test "${ac_cv_lib_GL_main+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lGL $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_GL_main=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_GL_main=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_GL_main" >&5 $as_echo "$ac_cv_lib_GL_main" >&6; } if test "x$ac_cv_lib_GL_main" = x""yes; then GL_LIBS="-lGL"; have_gl=yes fi { $as_echo "$as_me:$LINENO: checking for main in -lGLU" >&5 $as_echo_n "checking for main in -lGLU... " >&6; } if test "${ac_cv_lib_GLU_main+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lGLU -lGL $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_GLU_main=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_GLU_main=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_GLU_main" >&5 $as_echo "$ac_cv_lib_GLU_main" >&6; } if test "x$ac_cv_lib_GLU_main" = x""yes; then GL_LIBS="-lGLU $GL_LIBS"; have_glu=yes fi { $as_echo "$as_me:$LINENO: checking for main in -lopengl32" >&5 $as_echo_n "checking for main in -lopengl32... " >&6; } if test "${ac_cv_lib_opengl32_main+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lopengl32 $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_opengl32_main=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_opengl32_main=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_opengl32_main" >&5 $as_echo "$ac_cv_lib_opengl32_main" >&6; } if test "x$ac_cv_lib_opengl32_main" = x""yes; then GL_LIBS="-lopengl32"; have_gl=yes fi { $as_echo "$as_me:$LINENO: checking for main in -lglu32" >&5 $as_echo_n "checking for main in -lglu32... " >&6; } if test "${ac_cv_lib_glu32_main+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lglu32 -lopengl32 $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_glu32_main=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_glu32_main=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_glu32_main" >&5 $as_echo "$ac_cv_lib_glu32_main" >&6; } if test "x$ac_cv_lib_glu32_main" = x""yes; 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 if test x$enable_demos = xyes; then { $as_echo "$as_me:$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;} fi enable_demos=no fi fi { $as_echo "$as_me:$LINENO: checking for main in -lstdc++" >&5 $as_echo_n "checking for main in -lstdc++... " >&6; } if test "${ac_cv_lib_stdcpp_main+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lstdc++ $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_stdcpp_main=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_stdcpp_main=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_stdcpp_main" >&5 $as_echo "$ac_cv_lib_stdcpp_main" >&6; } if test "x$ac_cv_lib_stdcpp_main" = x""yes; then LIBSTDCXX="-lstdc++" else LIBSTDCXX= fi { $as_echo "$as_me:$LINENO: checking for main in -lpthread" >&5 $as_echo_n "checking for main in -lpthread... " >&6; } if test "${ac_cv_lib_pthread_main+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_pthread_main=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthread_main=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_main" >&5 $as_echo "$ac_cv_lib_pthread_main" >&6; } if test "x$ac_cv_lib_pthread_main" = x""yes; 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 cat >>confdefs.h <<\_ACEOF #define dTRIMESH_OPCODE_USE_OLD_TRIMESH_TRIMESH_COLLIDER 1 _ACEOF else old_trimesh=no fi { $as_echo "$as_me:$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:$LINENO: result: enabled" >&5 $as_echo "enabled" >&6; } { $as_echo "$as_me:$LINENO: checking for main in -lgmon" >&5 $as_echo_n "checking for main in -lgmon... " >&6; } if test "${ac_cv_lib_gmon_main+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgmon $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_gmon_main=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gmon_main=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_gmon_main" >&5 $as_echo "$ac_cv_lib_gmon_main" >&6; } if test "x$ac_cv_lib_gmon_main" = x""yes; then LIBS="$LIBS -lgmon" fi else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:$LINENO: checking for main in -lm" >&5 $as_echo_n "checking for main in -lm... " >&6; } if test "${ac_cv_lib_m_main+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_m_main=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_m_main=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_m_main" >&5 $as_echo "$ac_cv_lib_m_main" >&6; } if test "x$ac_cv_lib_m_main" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:$LINENO: checking for main in -lsunmath" >&5 $as_echo_n "checking for main in -lsunmath... " >&6; } if test "${ac_cv_lib_sunmath_main+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsunmath $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_sunmath_main=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_sunmath_main=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_sunmath_main" >&5 $as_echo "$ac_cv_lib_sunmath_main" >&6; } if test "x$ac_cv_lib_sunmath_main" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBSUNMATH 1 _ACEOF LIBS="-lsunmath $LIBS" fi for ac_func in floor memmove memset select sqrt sqrtf sinf cosf fabsf atan2f fmodf copysignf copysign snprintf vsnprintf gettimeofday isnan isnanf _isnan _isnanf __isnan __isnanf do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* 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 $ac_func (); /* 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_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` if test "x$as_val" = 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:$LINENO: checking for working alloca.h" >&5 $as_echo_n "checking for working alloca.h... " >&6; } if test "${ac_cv_working_alloca_h+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { char *p = (char *) alloca (2 * sizeof (int)); if (p) return 0; ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_working_alloca_h=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_working_alloca_h=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$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 cat >>confdefs.h <<\_ACEOF #define HAVE_ALLOCA_H 1 _ACEOF fi { $as_echo "$as_me:$LINENO: checking for alloca" >&5 $as_echo_n "checking for alloca... " >&6; } if test "${ac_cv_func_alloca_works+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __GNUC__ # define alloca __builtin_alloca #else # ifdef _MSC_VER # include # define alloca _alloca # else # ifdef HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ char *alloca (); # endif # endif # endif # endif #endif int main () { char *p = (char *) alloca (1); if (p) return 0; ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_alloca_works=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_alloca_works=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$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 cat >>confdefs.h <<\_ACEOF #define HAVE_ALLOCA 1 _ACEOF 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 cat >>confdefs.h <<\_ACEOF #define C_ALLOCA 1 _ACEOF { $as_echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5 $as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } if test "${ac_cv_os_cray+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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:$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` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* 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 $ac_func (); /* 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_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define CRAY_STACKSEG_END $ac_func _ACEOF break fi done fi { $as_echo "$as_me:$LINENO: checking stack direction for C alloca" >&5 $as_echo_n "checking stack direction for C alloca... " >&6; } if test "${ac_cv_c_stack_direction+set}" = set; then $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then ac_cv_c_stack_direction=0 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int find_stack_direction () { static char *addr = 0; auto char dummy; if (addr == 0) { addr = &dummy; return find_stack_direction (); } else return (&dummy > addr) ? 1 : -1; } int main () { return find_stack_direction () < 0; } _ACEOF rm -f 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_c_stack_direction=1 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 ( exit $ac_status ) ac_cv_c_stack_direction=-1 fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi { $as_echo "$as_me:$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 for ac_header in stdlib.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## -------------------------- ## ## Report this to ode@ode.org ## ## -------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:$LINENO: checking for GNU libc compatible malloc" >&5 $as_echo_n "checking for GNU libc compatible malloc... " >&6; } if test "${ac_cv_func_malloc_0_nonnull+set}" = set; then $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then ac_cv_func_malloc_0_nonnull=no else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #if defined STDC_HEADERS || defined HAVE_STDLIB_H # include #else char *malloc (); #endif int main () { return ! malloc (0); ; return 0; } _ACEOF rm -f 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_malloc_0_nonnull=yes 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 ( exit $ac_status ) ac_cv_func_malloc_0_nonnull=no fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_malloc_0_nonnull" >&5 $as_echo "$ac_cv_func_malloc_0_nonnull" >&6; } if test $ac_cv_func_malloc_0_nonnull = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_MALLOC 1 _ACEOF else cat >>confdefs.h <<\_ACEOF #define HAVE_MALLOC 0 _ACEOF case " $LIBOBJS " in *" malloc.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS malloc.$ac_objext" ;; esac cat >>confdefs.h <<\_ACEOF #define malloc rpl_malloc _ACEOF fi { $as_echo "$as_me:$LINENO: checking for obstacks" >&5 $as_echo_n "checking for obstacks... " >&6; } if test "${ac_cv_func_obstack+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_obstack=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_obstack=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_obstack" >&5 $as_echo "$ac_cv_func_obstack" >&6; } if test $ac_cv_func_obstack = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_OBSTACK 1 _ACEOF else case " $LIBOBJS " in *" obstack.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS obstack.$ac_objext" ;; esac fi for ac_header in stdlib.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## -------------------------- ## ## Report this to ode@ode.org ## ## -------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:$LINENO: checking for GNU libc compatible realloc" >&5 $as_echo_n "checking for GNU libc compatible realloc... " >&6; } if test "${ac_cv_func_realloc_0_nonnull+set}" = set; then $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then ac_cv_func_realloc_0_nonnull=no else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #if defined STDC_HEADERS || defined HAVE_STDLIB_H # include #else char *realloc (); #endif int main () { return ! realloc (0, 0); ; return 0; } _ACEOF rm -f 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_realloc_0_nonnull=yes 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 ( exit $ac_status ) ac_cv_func_realloc_0_nonnull=no fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_realloc_0_nonnull" >&5 $as_echo "$ac_cv_func_realloc_0_nonnull" >&6; } if test $ac_cv_func_realloc_0_nonnull = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_REALLOC 1 _ACEOF else cat >>confdefs.h <<\_ACEOF #define HAVE_REALLOC 0 _ACEOF case " $LIBOBJS " in *" realloc.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS realloc.$ac_objext" ;; esac cat >>confdefs.h <<\_ACEOF #define realloc rpl_realloc _ACEOF fi for ac_header in sys/select.h sys/socket.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## -------------------------- ## ## Report this to ode@ode.org ## ## -------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:$LINENO: checking types of arguments for select" >&5 $as_echo_n "checking types of arguments for select... " >&6; } if test "${ac_cv_func_select_args+set}" = set; then $as_echo_n "(cached) " >&6 else for ac_arg234 in 'fd_set *' 'int *' 'void *'; do for ac_arg1 in 'int' 'size_t' 'unsigned long int' 'unsigned int'; do for ac_arg5 in 'struct timeval *' 'const struct timeval *'; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #ifdef HAVE_SYS_SELECT_H # include #endif #ifdef HAVE_SYS_SOCKET_H # include #endif int main () { extern int select ($ac_arg1, $ac_arg234, $ac_arg234, $ac_arg234, $ac_arg5); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_func_select_args="$ac_arg1,$ac_arg234,$ac_arg5"; break 3 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done done done # Provide a safe default value. : ${ac_cv_func_select_args='int,int *,struct timeval *'} fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_select_args" >&5 $as_echo "$ac_cv_func_select_args" >&6; } ac_save_IFS=$IFS; IFS=',' set dummy `echo "$ac_cv_func_select_args" | sed 's/\*/\*/g'` IFS=$ac_save_IFS shift cat >>confdefs.h <<_ACEOF #define SELECT_TYPE_ARG1 $1 _ACEOF cat >>confdefs.h <<_ACEOF #define SELECT_TYPE_ARG234 ($2) _ACEOF cat >>confdefs.h <<_ACEOF #define SELECT_TYPE_ARG5 ($3) _ACEOF rm -f conftest* for ac_func in vprintf do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* 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 $ac_func (); /* 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_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF { $as_echo "$as_me:$LINENO: checking for _doprnt" >&5 $as_echo_n "checking for _doprnt... " >&6; } if test "${ac_cv_func__doprnt+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define _doprnt to an innocuous variant, in case declares _doprnt. For example, HP-UX 11i declares gettimeofday. */ #define _doprnt innocuous__doprnt /* System header to define __stub macros and hopefully few prototypes, which can conflict with char _doprnt (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef _doprnt /* 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 _doprnt (); /* 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__doprnt || defined __stub____doprnt choke me #endif int main () { return _doprnt (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func__doprnt=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func__doprnt=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5 $as_echo "$ac_cv_func__doprnt" >&6; } if test "x$ac_cv_func__doprnt" = x""yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_DOPRNT 1 _ACEOF fi fi done { $as_echo "$as_me:$LINENO: checking if alloca should be emulated by malloc" >&5 $as_echo_n "checking if alloca should be emulated by malloc... " >&6; } # Check whether --enable-malloc was given. if test "${enable_malloc+set}" = set; then enableval=$enable_malloc; usemalloc=$enableval else usemalloc=no fi if test "$usemalloc" != no then cat >>confdefs.h <<\_ACEOF #define dUSE_MALLOC_FOR_ALLOCA 1 _ACEOF { $as_echo "$as_me:$LINENO: result: $usemalloc" >&5 $as_echo "$usemalloc" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi # Check whether --enable-ou was given. if test "${enable_ou+set}" = set; then enableval=$enable_ou; use_ou=$enableval else use_ou=no fi if test x$use_ou = xyes then OU_NAMESPACE=odeou cat >>confdefs.h <<\_ACEOF #define _OU_NAMESPACE odeou _ACEOF cat >>confdefs.h <<\_ACEOF #define dOU_ENABLED 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define dATOMICS_ENABLED 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define dTLS_ENABLED 1 _ACEOF 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 { $as_echo "$as_me:$LINENO: checking for OSAtomicAdd32Barrier" >&5 $as_echo_n "checking for OSAtomicAdd32Barrier... " >&6; } if test "${ac_cv_func_OSAtomicAdd32Barrier+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define OSAtomicAdd32Barrier to an innocuous variant, in case declares OSAtomicAdd32Barrier. For example, HP-UX 11i declares gettimeofday. */ #define OSAtomicAdd32Barrier innocuous_OSAtomicAdd32Barrier /* System header to define __stub macros and hopefully few prototypes, which can conflict with char OSAtomicAdd32Barrier (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef OSAtomicAdd32Barrier /* 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 OSAtomicAdd32Barrier (); /* 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_OSAtomicAdd32Barrier || defined __stub___OSAtomicAdd32Barrier choke me #endif int main () { return OSAtomicAdd32Barrier (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_OSAtomicAdd32Barrier=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_OSAtomicAdd32Barrier=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_OSAtomicAdd32Barrier" >&5 $as_echo "$ac_cv_func_OSAtomicAdd32Barrier" >&6; } if test "x$ac_cv_func_OSAtomicAdd32Barrier" = x""yes; then MAC_OS_X_VERSION=1040 fi { $as_echo "$as_me:$LINENO: checking for OSAtomicAnd32OrigBarrier" >&5 $as_echo_n "checking for OSAtomicAnd32OrigBarrier... " >&6; } if test "${ac_cv_func_OSAtomicAnd32OrigBarrier+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define OSAtomicAnd32OrigBarrier to an innocuous variant, in case declares OSAtomicAnd32OrigBarrier. For example, HP-UX 11i declares gettimeofday. */ #define OSAtomicAnd32OrigBarrier innocuous_OSAtomicAnd32OrigBarrier /* System header to define __stub macros and hopefully few prototypes, which can conflict with char OSAtomicAnd32OrigBarrier (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef OSAtomicAnd32OrigBarrier /* 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 OSAtomicAnd32OrigBarrier (); /* 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_OSAtomicAnd32OrigBarrier || defined __stub___OSAtomicAnd32OrigBarrier choke me #endif int main () { return OSAtomicAnd32OrigBarrier (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_OSAtomicAnd32OrigBarrier=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_OSAtomicAnd32OrigBarrier=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_OSAtomicAnd32OrigBarrier" >&5 $as_echo "$ac_cv_func_OSAtomicAnd32OrigBarrier" >&6; } if test "x$ac_cv_func_OSAtomicAnd32OrigBarrier" = x""yes; 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 { $as_echo "$as_me:$LINENO: checking for atomic_inc_32_nv" >&5 $as_echo_n "checking for atomic_inc_32_nv... " >&6; } if test "${ac_cv_func_atomic_inc_32_nv+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define atomic_inc_32_nv to an innocuous variant, in case declares atomic_inc_32_nv. For example, HP-UX 11i declares gettimeofday. */ #define atomic_inc_32_nv innocuous_atomic_inc_32_nv /* System header to define __stub macros and hopefully few prototypes, which can conflict with char atomic_inc_32_nv (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef atomic_inc_32_nv /* 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 atomic_inc_32_nv (); /* 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_atomic_inc_32_nv || defined __stub___atomic_inc_32_nv choke me #endif int main () { return atomic_inc_32_nv (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_atomic_inc_32_nv=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_atomic_inc_32_nv=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_atomic_inc_32_nv" >&5 $as_echo "$ac_cv_func_atomic_inc_32_nv" >&6; } if test "x$ac_cv_func_atomic_inc_32_nv" = x""yes; then : else targetos=_OU_TARGET_OS_GENUNIX fi fi cat >>confdefs.h <<_ACEOF #define _OU_TARGET_OS $targetos _ACEOF fi subdirs="$subdirs ou" if test x$use_ou = xyes; then ENABLE_OU_TRUE= ENABLE_OU_FALSE='#' else ENABLE_OU_TRUE='#' ENABLE_OU_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" if test x$use_ou = xyes then CPPFLAGS="$CPPFLAGS -DNDEBUG" fi fi ac_config_files="$ac_config_files Makefile include/Makefile include/ode/Makefile include/drawstuff/Makefile ode/Makefile ode/src/Makefile ode/src/joints/Makefile drawstuff/Makefile drawstuff/src/Makefile drawstuff/dstest/Makefile ode/demo/Makefile OPCODE/Makefile OPCODE/Ice/Makefile GIMPACT/Makefile GIMPACT/include/Makefile GIMPACT/include/GIMPACT/Makefile GIMPACT/src/Makefile tests/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:$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= ;; #( *) $as_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 test "x$cache_file" != "x/dev/null" && { $as_echo "$as_me:$LINENO: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { $as_echo "$as_me:$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= 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. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${X86_64_SYSTEM_TRUE}" && test -z "${X86_64_SYSTEM_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"X86_64_SYSTEM\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"X86_64_SYSTEM\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${OPCODE_TRUE}" && test -z "${OPCODE_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"OPCODE\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"OPCODE\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${GIMPACT_TRUE}" && test -z "${GIMPACT_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"GIMPACT\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"GIMPACT\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${TRIMESH_TRUE}" && test -z "${TRIMESH_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"TRIMESH\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"TRIMESH\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${ENABLE_DRAWSTUFF_TRUE}" && test -z "${ENABLE_DRAWSTUFF_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"ENABLE_DRAWSTUFF\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"ENABLE_DRAWSTUFF\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${WIN32_TRUE}" && test -z "${WIN32_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"WIN32\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"WIN32\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${X11_TRUE}" && test -z "${X11_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"X11\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"X11\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${OSX_TRUE}" && test -z "${OSX_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"OSX\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"OSX\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${ENABLE_DEMOS_TRUE}" && test -z "${ENABLE_DEMOS_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"ENABLE_DEMOS\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"ENABLE_DEMOS\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${ENABLE_OU_TRUE}" && test -z "${ENABLE_OU_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"ENABLE_OU\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"ENABLE_OU\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } 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:$LINENO: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF || ac_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} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_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 # PATH needs CR # 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_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 if (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 # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false 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. 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); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # Required to use basename. 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 # Name of the executable. 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'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. 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 { (exit 1); exit 1; }; } # 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 } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi 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 -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' 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=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # 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 # 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.11.1, which was generated by GNU Autoconf 2.63. 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="`echo $ac_config_files`" config_headers="`echo $ac_config_headers`" config_commands="`echo $ac_config_commands`" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTION]... [FILE]... -h, --help print this help, then exit -V, --version print version number and configuration settings, 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 ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ ODE config.status 0.11.1 configured by $0, generated by GNU Autoconf 2.63, with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2008 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=$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 ;; --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"` ;; esac CONFIG_FILES="$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 CONFIG_HEADERS="$CONFIG_HEADERS '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header { $as_echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; };; --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_echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$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 "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`' AS='`$ECHO "X$AS" | $Xsed -e "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "X$DLLTOOL" | $Xsed -e "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`' macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`' macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`' enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`' pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`' host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`' host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`' host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`' build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`' build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`' build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`' SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`' Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`' GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`' EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`' FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`' LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`' NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`' LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`' ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`' exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`' lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`' reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`' reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`' AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`' STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`' RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`' CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`' compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`' GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`' SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`' ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`' need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`' NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`' LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`' OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`' OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`' libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`' fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`' include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`' file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`' version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`' runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`' libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`' library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`' soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`' finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`' sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`' hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`' old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`' striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`' compiler_lib_search_dirs='`$ECHO "X$compiler_lib_search_dirs" | $Xsed -e "$delay_single_quote_subst"`' predep_objects='`$ECHO "X$predep_objects" | $Xsed -e "$delay_single_quote_subst"`' postdep_objects='`$ECHO "X$postdep_objects" | $Xsed -e "$delay_single_quote_subst"`' predeps='`$ECHO "X$predeps" | $Xsed -e "$delay_single_quote_subst"`' postdeps='`$ECHO "X$postdeps" | $Xsed -e "$delay_single_quote_subst"`' compiler_lib_search_path='`$ECHO "X$compiler_lib_search_path" | $Xsed -e "$delay_single_quote_subst"`' LD_CXX='`$ECHO "X$LD_CXX" | $Xsed -e "$delay_single_quote_subst"`' old_archive_cmds_CXX='`$ECHO "X$old_archive_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' compiler_CXX='`$ECHO "X$compiler_CXX" | $Xsed -e "$delay_single_quote_subst"`' GCC_CXX='`$ECHO "X$GCC_CXX" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "X$lt_prog_compiler_no_builtin_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_wl_CXX='`$ECHO "X$lt_prog_compiler_wl_CXX" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_pic_CXX='`$ECHO "X$lt_prog_compiler_pic_CXX" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_static_CXX='`$ECHO "X$lt_prog_compiler_static_CXX" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o_CXX='`$ECHO "X$lt_cv_prog_compiler_c_o_CXX" | $Xsed -e "$delay_single_quote_subst"`' archive_cmds_need_lc_CXX='`$ECHO "X$archive_cmds_need_lc_CXX" | $Xsed -e "$delay_single_quote_subst"`' enable_shared_with_static_runtimes_CXX='`$ECHO "X$enable_shared_with_static_runtimes_CXX" | $Xsed -e "$delay_single_quote_subst"`' export_dynamic_flag_spec_CXX='`$ECHO "X$export_dynamic_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' whole_archive_flag_spec_CXX='`$ECHO "X$whole_archive_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' compiler_needs_object_CXX='`$ECHO "X$compiler_needs_object_CXX" | $Xsed -e "$delay_single_quote_subst"`' old_archive_from_new_cmds_CXX='`$ECHO "X$old_archive_from_new_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds_CXX='`$ECHO "X$old_archive_from_expsyms_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' archive_cmds_CXX='`$ECHO "X$archive_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' archive_expsym_cmds_CXX='`$ECHO "X$archive_expsym_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' module_cmds_CXX='`$ECHO "X$module_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' module_expsym_cmds_CXX='`$ECHO "X$module_expsym_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' with_gnu_ld_CXX='`$ECHO "X$with_gnu_ld_CXX" | $Xsed -e "$delay_single_quote_subst"`' allow_undefined_flag_CXX='`$ECHO "X$allow_undefined_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`' no_undefined_flag_CXX='`$ECHO "X$no_undefined_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_CXX='`$ECHO "X$hardcode_libdir_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_ld_CXX='`$ECHO "X$hardcode_libdir_flag_spec_ld_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_libdir_separator_CXX='`$ECHO "X$hardcode_libdir_separator_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_direct_CXX='`$ECHO "X$hardcode_direct_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_direct_absolute_CXX='`$ECHO "X$hardcode_direct_absolute_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_minus_L_CXX='`$ECHO "X$hardcode_minus_L_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_shlibpath_var_CXX='`$ECHO "X$hardcode_shlibpath_var_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_automatic_CXX='`$ECHO "X$hardcode_automatic_CXX" | $Xsed -e "$delay_single_quote_subst"`' inherit_rpath_CXX='`$ECHO "X$inherit_rpath_CXX" | $Xsed -e "$delay_single_quote_subst"`' link_all_deplibs_CXX='`$ECHO "X$link_all_deplibs_CXX" | $Xsed -e "$delay_single_quote_subst"`' fix_srcfile_path_CXX='`$ECHO "X$fix_srcfile_path_CXX" | $Xsed -e "$delay_single_quote_subst"`' always_export_symbols_CXX='`$ECHO "X$always_export_symbols_CXX" | $Xsed -e "$delay_single_quote_subst"`' export_symbols_cmds_CXX='`$ECHO "X$export_symbols_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' exclude_expsyms_CXX='`$ECHO "X$exclude_expsyms_CXX" | $Xsed -e "$delay_single_quote_subst"`' include_expsyms_CXX='`$ECHO "X$include_expsyms_CXX" | $Xsed -e "$delay_single_quote_subst"`' prelink_cmds_CXX='`$ECHO "X$prelink_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' file_list_spec_CXX='`$ECHO "X$file_list_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_action_CXX='`$ECHO "X$hardcode_action_CXX" | $Xsed -e "$delay_single_quote_subst"`' compiler_lib_search_dirs_CXX='`$ECHO "X$compiler_lib_search_dirs_CXX" | $Xsed -e "$delay_single_quote_subst"`' predep_objects_CXX='`$ECHO "X$predep_objects_CXX" | $Xsed -e "$delay_single_quote_subst"`' postdep_objects_CXX='`$ECHO "X$postdep_objects_CXX" | $Xsed -e "$delay_single_quote_subst"`' predeps_CXX='`$ECHO "X$predeps_CXX" | $Xsed -e "$delay_single_quote_subst"`' postdeps_CXX='`$ECHO "X$postdeps_CXX" | $Xsed -e "$delay_single_quote_subst"`' compiler_lib_search_path_CXX='`$ECHO "X$compiler_lib_search_path_CXX" | $Xsed -e "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # Quote evaled strings. for var in SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ deplibs_check_method \ file_magic_cmd \ AR \ AR_FLAGS \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ SHELL \ ECHO \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_wl \ lt_prog_compiler_pic \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ 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_flag_spec_ld \ hardcode_libdir_separator \ fix_srcfile_path \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ finish_eval \ old_striplib \ striplib \ compiler_lib_search_dirs \ predep_objects \ postdep_objects \ predeps \ postdeps \ compiler_lib_search_path \ LD_CXX \ compiler_CXX \ lt_prog_compiler_no_builtin_flag_CXX \ lt_prog_compiler_wl_CXX \ lt_prog_compiler_pic_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_flag_spec_ld_CXX \ hardcode_libdir_separator_CXX \ fix_srcfile_path_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 "X\\\\\$\$var"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) 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 \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ sys_lib_dlsearch_path_spec \ 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; do case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Fix-up fallback echo if it was mangled by the above quoting rules. case \$lt_ECHO in *'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\` ;; esac ac_aux_dir='$ac_aux_dir' xsi_shell='$xsi_shell' lt_shell_append='$lt_shell_append' # See if we are running on zsh, and set the options which 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' TIMESTAMP='$TIMESTAMP' 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" ;; "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;; "include/ode/Makefile") CONFIG_FILES="$CONFIG_FILES include/ode/Makefile" ;; "include/drawstuff/Makefile") CONFIG_FILES="$CONFIG_FILES include/drawstuff/Makefile" ;; "ode/Makefile") CONFIG_FILES="$CONFIG_FILES ode/Makefile" ;; "ode/src/Makefile") CONFIG_FILES="$CONFIG_FILES ode/src/Makefile" ;; "ode/src/joints/Makefile") CONFIG_FILES="$CONFIG_FILES ode/src/joints/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" ;; "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/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_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 $as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; 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= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || { $as_echo "$as_me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } # 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=' ' ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /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 {' >"$tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } 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 >>"\$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 ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$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 < "$tmp/subs1.awk" > "$tmp/subs.awk" \ || { { $as_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5 $as_echo "$as_me: error: could not setup config files machinery" >&2;} { (exit 1); exit 1; }; } _ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ 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[ ]*=/{ s/:*\$(srcdir):*/:/ s/:*\${srcdir}:*/:/ s/:*@srcdir@:*/:/ s/^\([^=]*=[ ]*\):*/\1/ s/:*$// 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 >"$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_t=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_t"; then break elif $ac_last_try; then { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_HEADERS" >&5 $as_echo "$as_me: error: could not make $CONFIG_HEADERS" >&2;} { (exit 1); exit 1; }; } 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 ' >$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_echo "$as_me:$LINENO: error: could not setup config headers machinery" >&5 $as_echo "$as_me: error: could not setup config headers machinery" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: invalid tag $ac_tag" >&5 $as_echo "$as_me: error: invalid tag $ac_tag" >&2;} { (exit 1); exit 1; }; };; :[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="$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_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 $as_echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac ac_file_inputs="$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:$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 >"$tmp/stdin" \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } ;; 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" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { 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_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 $as_echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } 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:$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 "$tmp/subs.awk" >$tmp/out \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:$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 "$tmp/stdin" case $ac_file in -) cat "$tmp/out" && rm -f "$tmp/out";; *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" } >"$tmp/config.h" \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:$LINENO: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$tmp/config.h" "$ac_file" \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ || { { $as_echo "$as_me:$LINENO: error: could not create -" >&5 $as_echo "$as_me: error: could not create -" >&2;} { (exit 1); exit 1; }; } 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:$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"" || # Autoconf 2.62 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"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //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' -e 's/\$U/'"$U"'/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 case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { 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_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 $as_echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ;; "libtool":C) # See if we are running on zsh, and set the options which 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 # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $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. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # The names of the tagged configurations supported by this script. available_tags="CXX " # ### BEGIN LIBTOOL CONFIG # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Assembler program. AS=$AS # DLL creation program. DLLTOOL=$DLLTOOL # Object dumper program. OBJDUMP=$OBJDUMP # 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 # 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 # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # 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 # The archiver. AR=$lt_AR AR_FLAGS=$lt_AR_FLAGS # 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 # 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 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 of the directory that contains temporary libtool files. objdir=$objdir # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that does not interpret backslashes. ECHO=$lt_ECHO # 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 # 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 # 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 # Run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # 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 # 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 # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # 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 # If ld is used when linking, flag to hardcode \$libdir into a binary # during linking. This must work even if \$libdir does not exist. hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld # 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 # Fix the shell variable \$srcfile for the compiler. fix_srcfile_path=$lt_fix_srcfile_path # 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 # 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 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 "X${COLLECT_NAMES+set}" != Xset; 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 '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) case $xsi_shell in yes) cat << \_LT_EOF >> "$cfgfile" # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac } # func_basename file func_basename () { func_basename_result="${1##*/}" } # 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" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}" } # func_stripname 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). func_stripname () { # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"} } # func_opt_split func_opt_split () { func_opt_split_opt=${1%%=*} func_opt_split_arg=${1#*=} } # func_lo2o object func_lo2o () { case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac } # func_xform libobj-or-source func_xform () { func_xform_result=${1%.*}.lo } # func_arith arithmetic-term... func_arith () { func_arith_result=$(( $* )) } # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=${#1} } _LT_EOF ;; *) # Bourne compatible functions. cat << \_LT_EOF >> "$cfgfile" # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_basename file func_basename () { func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` } # func_stripname 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). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "X${3}" \ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "X${3}" \ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; esac } # sed scripts: my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q' my_sed_long_arg='1s/^-[^=]*=//' # func_opt_split func_opt_split () { func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` } # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` } # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'` } # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "$@"` } # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` } _LT_EOF esac case $lt_shell_append in yes) cat << \_LT_EOF >> "$cfgfile" # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "$1+=\$2" } _LT_EOF ;; *) cat << \_LT_EOF >> "$cfgfile" # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "$1=\$$1\$2" } _LT_EOF ;; esac sed -n '/^# Generated shell functions inserted here/,$p' "$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 # 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 # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_CXX # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_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 # If ld is used when linking, flag to hardcode \$libdir into a binary # during linking. This must work even if \$libdir does not exist. hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_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 # Fix the shell variable \$srcfile for the compiler. fix_srcfile_path=$lt_fix_srcfile_path_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 # 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 { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5 $as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } export OU_NAMESPACE=odeou # 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 || { (exit 1); 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 ac_sub_configure_args="$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:$LINENO: $ac_msg" >&5 $as_echo "$ac_msg" >&6 { as_dir="$ac_dir" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { 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_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 $as_echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } 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:$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:$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_echo "$as_me:$LINENO: error: $ac_sub_configure failed for $ac_dir" >&5 $as_echo "$as_me: error: $ac_sub_configure failed for $ac_dir" >&2;} { (exit 1); exit 1; }; } fi cd "$ac_popdir" done fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:$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: $precision" echo " Use drawstuff: $drawstuff" echo " Demos enabled: $enable_demos" echo " Use OPCODE: $opcode" echo " Use GIMPACT: $gimpact" echo " Is target a Pentium: $pentium" echo " Is target x86-64: $cpu64" echo " Use old opcode trimesh collider: $old_trimesh" echo " TLS for global data: $use_ou" 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" ode-0.11.1/README.txt0000644000076400007640000000361510670126704011000 00000000000000The Open Dynamics Engine (ODE), 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: (1) The GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (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. * Installation instructions are in the INSTALL file * The ODE web pages are at http://ode.org/ * An online manual is at http://opende.sf.net/wiki/index.php/Manual * API documentation is in the file ode/docs/index.html, or you can view it on the web at http://opende.sf.net/docs/index.html All contributions are copyright by their owners, but the owners automatically transfer unrestricted rights in those changes to the ODE project, which is released under the dual 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 dual ODE licenses as part of an ODE release. ode-0.11.1/LICENSE.TXT0000644000076400007640000006347407265104631010777 00000000000000 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. Copyright (C) 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. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! ode-0.11.1/ode-config.in0000644000076400007640000000162511053655105011641 00000000000000#!/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_RELEASE@ ;; --cflags) echo -I@includedir@ @ODE_PRECISION@ ;; --libs) echo -L@libdir@ -lode ;; *) echo "${usage}" 1>&2 exit 1 ;; esac shift done ode-0.11.1/include/0000777000076400007640000000000011206343456011005 500000000000000ode-0.11.1/include/ode/0000777000076400007640000000000011206343456011554 500000000000000ode-0.11.1/include/ode/error.h0000644000076400007640000000526310765152110012772 00000000000000/************************************************************************* * * * 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 #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 dError (int num, const char *msg, ...); ODE_API void dDebug (int num, const char *msg, ...); ODE_API void dMessage (int num, const char *msg, ...); #ifdef __cplusplus } #endif #endif ode-0.11.1/include/ode/odeconfig.h0000644000076400007640000000400711075740455013603 00000000000000#ifndef ODECONFIG_H #define ODECONFIG_H #ifndef dDOUBLE #ifndef dSINGLE #define dSINGLE #endif #endif /* Pull in the standard headers */ #include #include #include #include #include #include #if defined(ODE_DLL) || defined(ODE_LIB) || !defined(_MSC_VER) #define __ODE__ #endif /* Define a DLL export symbol for those platforms that need it */ #if defined(_MSC_VER) #if defined(ODE_DLL) #define ODE_API __declspec(dllexport) #elif !defined(ODE_LIB) #define ODE_DLL_API __declspec(dllimport) #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 /* Well-defined common data types...need to define for 64 bit systems */ #if defined(_M_IA64) || defined(__ia64__) || defined(_M_AMD64) || defined(__x86_64__) #define X86_64_SYSTEM 1 typedef int int32; typedef unsigned int uint32; typedef short int16; typedef unsigned short uint16; typedef char int8; typedef unsigned char uint8; #else typedef int int32; typedef unsigned int uint32; typedef short int16; typedef unsigned short uint16; typedef char int8; typedef unsigned char uint8; #endif /* Visual C does not define these functions */ #if defined(_MSC_VER) #define copysignf _copysign #define copysign _copysign #endif /* Define the dInfinity macro */ #ifdef INFINITY #define dInfinity INFINITY #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 #endif ode-0.11.1/include/ode/odecpp.h0000644000076400007640000010701311123307602013104 00000000000000/************************************************************************* * * * 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 dWorld { dWorldID _id; // intentionally undefined, don't use these dWorld (const dWorld &); void operator= (const dWorld &); public: dWorld() { _id = dWorldCreate(); } ~dWorld() { dWorldDestroy (_id); } dWorldID id() const { return _id; } operator dWorldID() const { return _id; } void setGravity (dReal x, dReal y, dReal z) { dWorldSetGravity (_id,x,y,z); } void setGravity (const dVector3 g) { setGravity (g[0], g[1], g[2]); } void getGravity (dVector3 g) const { dWorldGetGravity (_id,g); } void setERP (dReal erp) { dWorldSetERP(_id, erp); } dReal getERP() const { return dWorldGetERP(_id); } void setCFM (dReal cfm) { dWorldSetCFM(_id, cfm); } dReal getCFM() const { return dWorldGetCFM(_id); } void step (dReal stepsize) { dWorldStep (_id,stepsize); } void stepFast1 (dReal stepsize, int maxiterations) { dWorldStepFast1 (_id,stepsize,maxiterations); } void setAutoEnableDepthSF1(int depth) { dWorldSetAutoEnableDepthSF1 (_id, depth); } int getAutoEnableDepthSF1() const { return dWorldGetAutoEnableDepthSF1 (_id); } void quickStep(dReal stepsize) { dWorldQuickStep (_id, stepsize); } void setQuickStepNumIterations(int num) { dWorldSetQuickStepNumIterations (_id, num); } int getQuickStepNumIterations() const { return dWorldGetQuickStepNumIterations (_id); } void setQuickStepW(dReal over_relaxation) { dWorldSetQuickStepW (_id, over_relaxation); } dReal getQuickStepW() const { return dWorldGetQuickStepW (_id); } void setAutoDisableLinearThreshold (dReal threshold) { dWorldSetAutoDisableLinearThreshold (_id,threshold); } dReal getAutoDisableLinearThreshold() const { return dWorldGetAutoDisableLinearThreshold (_id); } void setAutoDisableAngularThreshold (dReal threshold) { dWorldSetAutoDisableAngularThreshold (_id,threshold); } dReal getAutoDisableAngularThreshold() const { return dWorldGetAutoDisableAngularThreshold (_id); } void setAutoDisableSteps (int steps) { dWorldSetAutoDisableSteps (_id,steps); } int getAutoDisableSteps() const { return dWorldGetAutoDisableSteps (_id); } void setAutoDisableTime (dReal time) { dWorldSetAutoDisableTime (_id,time); } dReal getAutoDisableTime() const { return dWorldGetAutoDisableTime (_id); } void setAutoDisableFlag (int do_auto_disable) { dWorldSetAutoDisableFlag (_id,do_auto_disable); } int getAutoDisableFlag() const { return dWorldGetAutoDisableFlag (_id); } dReal getLinearDampingThreshold() const { return dWorldGetLinearDampingThreshold(_id); } void setLinearDampingThreshold(dReal threshold) { dWorldSetLinearDampingThreshold(_id, threshold); } dReal getAngularDampingThreshold() const { return dWorldGetAngularDampingThreshold(_id); } void setAngularDampingThreshold(dReal threshold) { dWorldSetAngularDampingThreshold(_id, threshold); } dReal getLinearDamping() const { return dWorldGetLinearDamping(_id); } void setLinearDamping(dReal scale) { dWorldSetLinearDamping(_id, scale); } dReal getAngularDamping() const { return dWorldGetAngularDamping(_id); } void setAngularDamping(dReal scale) { dWorldSetAngularDamping(_id, scale); } void setDamping(dReal linear_scale, dReal angular_scale) { dWorldSetDamping(_id, linear_scale, angular_scale); } dReal getMaxAngularSpeed() const { return dWorldGetMaxAngularSpeed(_id); } void setMaxAngularSpeed(dReal max_speed) { dWorldSetMaxAngularSpeed(_id, max_speed); } void setContactSurfaceLayer(dReal depth) { dWorldSetContactSurfaceLayer (_id, depth); } dReal getContactSurfaceLayer() const { return dWorldGetContactSurfaceLayer (_id); } void impulseToForce (dReal stepsize, dReal ix, dReal iy, dReal iz, dVector3 force) { dWorldImpulseToForce (_id,stepsize,ix,iy,iz,force); } }; class dBody { dBodyID _id; // intentionally undefined, don't use these dBody (const dBody &); void operator= (const dBody &); public: dBody() { _id = 0; } dBody (dWorldID world) { _id = dBodyCreate (world); } dBody (dWorld& world) { _id = dBodyCreate (world.id()); } ~dBody() { if (_id) dBodyDestroy (_id); } void create (dWorldID world) { if (_id) dBodyDestroy (_id); _id = dBodyCreate (world); } void create (dWorld& world) { create(world.id()); } dBodyID id() const { return _id; } operator dBodyID() const { return _id; } void setData (void *data) { dBodySetData (_id,data); } void *getData() const { return dBodyGetData (_id); } void setPosition (dReal x, dReal y, dReal z) { dBodySetPosition (_id,x,y,z); } void setPosition (const dVector3 p) { setPosition(p[0], p[1], p[2]); } void setRotation (const dMatrix3 R) { dBodySetRotation (_id,R); } void setQuaternion (const dQuaternion q) { dBodySetQuaternion (_id,q); } void setLinearVel (dReal x, dReal y, dReal z) { dBodySetLinearVel (_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 (_id,x,y,z); } void setAngularVel (const dVector3 v) { setAngularVel (v[0], v[1], v[2]); } const dReal * getPosition() const { return dBodyGetPosition (_id); } const dReal * getRotation() const { return dBodyGetRotation (_id); } const dReal * getQuaternion() const { return dBodyGetQuaternion (_id); } const dReal * getLinearVel() const { return dBodyGetLinearVel (_id); } const dReal * getAngularVel() const { return dBodyGetAngularVel (_id); } void setMass (const dMass *mass) { dBodySetMass (_id,mass); } void setMass (const dMass &mass) { setMass (&mass); } dMass getMass () const { dMass mass; dBodyGetMass (_id,&mass); return mass; } void addForce (dReal fx, dReal fy, dReal fz) { dBodyAddForce (_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 (_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 (_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 (_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 (_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 (_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 (_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 (_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(_id); } const dReal * getTorque() const { return dBodyGetTorque(_id); } void setForce (dReal x, dReal y, dReal z) { dBodySetForce (_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 (_id,x,y,z); } void setTorque (const dVector3 t) { setTorque (t[0], t[1], t[2]); } void setDynamic() { dBodySetDynamic (_id); } void setKinematic() { dBodySetKinematic (_id); } bool isKinematic() const { return dBodyIsKinematic (_id) != 0; } void enable() { dBodyEnable (_id); } void disable() { dBodyDisable (_id); } bool isEnabled() const { return dBodyIsEnabled (_id) != 0; } void getRelPointPos (dReal px, dReal py, dReal pz, dVector3 result) const { dBodyGetRelPointPos (_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 (_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 (_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 (_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 (_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 (_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 (_id, mode); } void setFiniteRotationAxis (dReal x, dReal y, dReal z) { dBodySetFiniteRotationAxis (_id, x, y, z); } void setFiniteRotationAxis (const dVector3 a) { setFiniteRotationAxis (a[0], a[1], a[2]); } bool getFiniteRotationMode() const { return dBodyGetFiniteRotationMode (_id) != 0; } void getFiniteRotationAxis (dVector3 result) const { dBodyGetFiniteRotationAxis (_id, result); } int getNumJoints() const { return dBodyGetNumJoints (_id); } dJointID getJoint (int index) const { return dBodyGetJoint (_id, index); } void setGravityMode (bool mode) { dBodySetGravityMode (_id,mode); } bool getGravityMode() const { return dBodyGetGravityMode (_id) != 0; } bool isConnectedTo (dBodyID body) const { return dAreConnected (_id, body) != 0; } void setAutoDisableLinearThreshold (dReal threshold) { dBodySetAutoDisableLinearThreshold (_id,threshold); } dReal getAutoDisableLinearThreshold() const { return dBodyGetAutoDisableLinearThreshold (_id); } void setAutoDisableAngularThreshold (dReal threshold) { dBodySetAutoDisableAngularThreshold (_id,threshold); } dReal getAutoDisableAngularThreshold() const { return dBodyGetAutoDisableAngularThreshold (_id); } void setAutoDisableSteps (int steps) { dBodySetAutoDisableSteps (_id,steps); } int getAutoDisableSteps() const { return dBodyGetAutoDisableSteps (_id); } void setAutoDisableTime (dReal time) { dBodySetAutoDisableTime (_id,time); } dReal getAutoDisableTime() const { return dBodyGetAutoDisableTime (_id); } void setAutoDisableFlag (bool do_auto_disable) { dBodySetAutoDisableFlag (_id,do_auto_disable); } bool getAutoDisableFlag() const { return dBodyGetAutoDisableFlag (_id) != 0; } dReal getLinearDamping() const { return dBodyGetLinearDamping(_id); } void setLinearDamping(dReal scale) { dBodySetLinearDamping(_id, scale); } dReal getAngularDamping() const { return dBodyGetAngularDamping(_id); } void setAngularDamping(dReal scale) { dBodySetAngularDamping(_id, scale); } void setDamping(dReal linear_scale, dReal angular_scale) { dBodySetDamping(_id, linear_scale, angular_scale); } dReal getLinearDampingThreshold() const { return dBodyGetLinearDampingThreshold(_id); } void setLinearDampingThreshold(dReal threshold) const { dBodySetLinearDampingThreshold(_id, threshold); } dReal getAngularDampingThreshold() const { return dBodyGetAngularDampingThreshold(_id); } void setAngularDampingThreshold(dReal threshold) { dBodySetAngularDampingThreshold(_id, threshold); } void setDampingDefaults() { dBodySetDampingDefaults(_id); } dReal getMaxAngularSpeed() const { return dBodyGetMaxAngularSpeed(_id); } void setMaxAngularSpeed(dReal max_speed) { dBodySetMaxAngularSpeed(_id, max_speed); } bool getGyroscopicMode() const { return dBodyGetGyroscopicMode(_id) != 0; } void setGyroscopicMode(bool mode) { dBodySetGyroscopicMode(_id, mode); } }; class dJointGroup { dJointGroupID _id; // intentionally undefined, don't use these dJointGroup (const dJointGroup &); void operator= (const dJointGroup &); public: dJointGroup () { _id = dJointGroupCreate (0); } ~dJointGroup() { dJointGroupDestroy (_id); } void create () { if (_id) dJointGroupDestroy (_id); _id = dJointGroupCreate (0); } dJointGroupID id() const { return _id; } operator dJointGroupID() const { return _id; } void empty() { dJointGroupEmpty (_id); } void clear() { empty(); } }; class dJoint { private: // intentionally undefined, don't use these dJoint (const dJoint &) ; void operator= (const dJoint &); protected: dJointID _id; dJoint() // don't let user construct pure dJoint objects { _id = 0; } public: virtual ~dJoint() // :( Destructor must be virtual to suppress compiler warning "class XXX has virtual functions but non-virtual destructor" { if (_id) dJointDestroy (_id); } dJointID id() const { return _id; } operator dJointID() const { return _id; } int getNumBodies() const { return dJointGetNumBodies(_id); } void attach (dBodyID body1, dBodyID body2) { dJointAttach (_id, body1, body2); } void attach (dBody& body1, dBody& body2) { attach(body1.id(), body2.id()); } void enable() { dJointEnable (_id); } void disable() { dJointDisable (_id); } bool isEnabled() const { return dJointIsEnabled (_id) != 0; } void setData (void *data) { dJointSetData (_id, data); } void *getData() const { return dJointGetData (_id); } dJointType getType() const { return dJointGetType (_id); } dBodyID getBody (int index) const { return dJointGetBody (_id, index); } void setFeedback(dJointFeedback *fb) { dJointSetFeedback(_id, fb); } dJointFeedback *getFeedback() const { return dJointGetFeedback(_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; } }; class dBallJoint : public dJoint { private: // intentionally undefined, don't use these dBallJoint (const dBallJoint &); void operator= (const dBallJoint &); public: dBallJoint() { } dBallJoint (dWorldID world, dJointGroupID group=0) { _id = dJointCreateBall (world, group); } dBallJoint (dWorld& world, dJointGroupID group=0) { _id = dJointCreateBall (world.id(), group); } void create (dWorldID world, dJointGroupID group=0) { if (_id) dJointDestroy (_id); _id = dJointCreateBall (world, group); } void create (dWorld& world, dJointGroupID group=0) { create(world.id(), group); } void setAnchor (dReal x, dReal y, dReal z) { dJointSetBallAnchor (_id, x, y, z); } void setAnchor (const dVector3 a) { setAnchor (a[0], a[1], a[2]); } void getAnchor (dVector3 result) const { dJointGetBallAnchor (_id, result); } void getAnchor2 (dVector3 result) const { dJointGetBallAnchor2 (_id, result); } virtual void setParam (int parameter, dReal value) { dJointSetBallParam (_id, parameter, value); } virtual dReal getParam (int parameter) const { return dJointGetBallParam (_id, parameter); } // TODO: expose params through methods } ; class dHingeJoint : public dJoint { // intentionally undefined, don't use these dHingeJoint (const dHingeJoint &); void operator = (const dHingeJoint &); public: dHingeJoint() { } dHingeJoint (dWorldID world, dJointGroupID group=0) { _id = dJointCreateHinge (world, group); } dHingeJoint (dWorld& world, dJointGroupID group=0) { _id = dJointCreateHinge (world.id(), group); } void create (dWorldID world, dJointGroupID group=0) { if (_id) dJointDestroy (_id); _id = dJointCreateHinge (world, group); } void create (dWorld& world, dJointGroupID group=0) { create(world.id(), group); } void setAnchor (dReal x, dReal y, dReal z) { dJointSetHingeAnchor (_id, x, y, z); } void setAnchor (const dVector3 a) { setAnchor (a[0], a[1], a[2]); } void getAnchor (dVector3 result) const { dJointGetHingeAnchor (_id, result); } void getAnchor2 (dVector3 result) const { dJointGetHingeAnchor2 (_id, result); } void setAxis (dReal x, dReal y, dReal z) { dJointSetHingeAxis (_id, x, y, z); } void setAxis (const dVector3 a) { setAxis(a[0], a[1], a[2]); } void getAxis (dVector3 result) const { dJointGetHingeAxis (_id, result); } dReal getAngle() const { return dJointGetHingeAngle (_id); } dReal getAngleRate() const { return dJointGetHingeAngleRate (_id); } virtual void setParam (int parameter, dReal value) { dJointSetHingeParam (_id, parameter, value); } virtual dReal getParam (int parameter) const { return dJointGetHingeParam (_id, parameter); } // TODO: expose params through methods void addTorque (dReal torque) { dJointAddHingeTorque(_id, torque); } }; class dSliderJoint : public dJoint { // intentionally undefined, don't use these dSliderJoint (const dSliderJoint &); void operator = (const dSliderJoint &); public: dSliderJoint() { } dSliderJoint (dWorldID world, dJointGroupID group=0) { _id = dJointCreateSlider (world, group); } dSliderJoint (dWorld& world, dJointGroupID group=0) { _id = dJointCreateSlider (world.id(), group); } void create (dWorldID world, dJointGroupID group=0) { if (_id) dJointDestroy (_id); _id = dJointCreateSlider (world, group); } void create (dWorld& world, dJointGroupID group=0) { create(world.id(), group); } void setAxis (dReal x, dReal y, dReal z) { dJointSetSliderAxis (_id, x, y, z); } void setAxis (const dVector3 a) { setAxis (a[0], a[1], a[2]); } void getAxis (dVector3 result) const { dJointGetSliderAxis (_id, result); } dReal getPosition() const { return dJointGetSliderPosition (_id); } dReal getPositionRate() const { return dJointGetSliderPositionRate (_id); } virtual void setParam (int parameter, dReal value) { dJointSetSliderParam (_id, parameter, value); } virtual dReal getParam (int parameter) const { return dJointGetSliderParam (_id, parameter); } // TODO: expose params through methods void addForce (dReal force) { dJointAddSliderForce(_id, force); } }; class dUniversalJoint : public dJoint { // intentionally undefined, don't use these dUniversalJoint (const dUniversalJoint &); void operator = (const dUniversalJoint &); public: dUniversalJoint() { } dUniversalJoint (dWorldID world, dJointGroupID group=0) { _id = dJointCreateUniversal (world, group); } dUniversalJoint (dWorld& world, dJointGroupID group=0) { _id = dJointCreateUniversal (world.id(), group); } void create (dWorldID world, dJointGroupID group=0) { if (_id) dJointDestroy (_id); _id = dJointCreateUniversal (world, group); } void create (dWorld& world, dJointGroupID group=0) { create(world.id(), group); } void setAnchor (dReal x, dReal y, dReal z) { dJointSetUniversalAnchor (_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 (_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 (_id, x, y, z); } void setAxis2 (const dVector3 a) { setAxis2 (a[0], a[1], a[2]); } void getAnchor (dVector3 result) const { dJointGetUniversalAnchor (_id, result); } void getAnchor2 (dVector3 result) const { dJointGetUniversalAnchor2 (_id, result); } void getAxis1 (dVector3 result) const { dJointGetUniversalAxis1 (_id, result); } void getAxis2 (dVector3 result) const { dJointGetUniversalAxis2 (_id, result); } virtual void setParam (int parameter, dReal value) { dJointSetUniversalParam (_id, parameter, value); } virtual dReal getParam (int parameter) const { return dJointGetUniversalParam (_id, parameter); } // TODO: expose params through methods void getAngles(dReal *angle1, dReal *angle2) const { dJointGetUniversalAngles (_id, angle1, angle2); } dReal getAngle1() const { return dJointGetUniversalAngle1 (_id); } dReal getAngle1Rate() const { return dJointGetUniversalAngle1Rate (_id); } dReal getAngle2() const { return dJointGetUniversalAngle2 (_id); } dReal getAngle2Rate() const { return dJointGetUniversalAngle2Rate (_id); } void addTorques (dReal torque1, dReal torque2) { dJointAddUniversalTorques(_id, torque1, torque2); } }; class dHinge2Joint : public dJoint { // intentionally undefined, don't use these dHinge2Joint (const dHinge2Joint &); void operator = (const dHinge2Joint &); public: dHinge2Joint() { } dHinge2Joint (dWorldID world, dJointGroupID group=0) { _id = dJointCreateHinge2 (world, group); } dHinge2Joint (dWorld& world, dJointGroupID group=0) { _id = dJointCreateHinge2 (world.id(), group); } void create (dWorldID world, dJointGroupID group=0) { if (_id) dJointDestroy (_id); _id = dJointCreateHinge2 (world, group); } void create (dWorld& world, dJointGroupID group=0) { create(world.id(), group); } void setAnchor (dReal x, dReal y, dReal z) { dJointSetHinge2Anchor (_id, x, y, z); } void setAnchor (const dVector3 a) { setAnchor(a[0], a[1], a[2]); } void setAxis1 (dReal x, dReal y, dReal z) { dJointSetHinge2Axis1 (_id, x, y, z); } void setAxis1 (const dVector3 a) { setAxis1 (a[0], a[1], a[2]); } void setAxis2 (dReal x, dReal y, dReal z) { dJointSetHinge2Axis2 (_id, x, y, z); } void setAxis2 (const dVector3 a) { setAxis2 (a[0], a[1], a[2]); } void getAnchor (dVector3 result) const { dJointGetHinge2Anchor (_id, result); } void getAnchor2 (dVector3 result) const { dJointGetHinge2Anchor2 (_id, result); } void getAxis1 (dVector3 result) const { dJointGetHinge2Axis1 (_id, result); } void getAxis2 (dVector3 result) const { dJointGetHinge2Axis2 (_id, result); } dReal getAngle1() const { return dJointGetHinge2Angle1 (_id); } dReal getAngle1Rate() const { return dJointGetHinge2Angle1Rate (_id); } dReal getAngle2Rate() const { return dJointGetHinge2Angle2Rate (_id); } virtual void setParam (int parameter, dReal value) { dJointSetHinge2Param (_id, parameter, value); } virtual dReal getParam (int parameter) const { return dJointGetHinge2Param (_id, parameter); } // TODO: expose params through methods void addTorques(dReal torque1, dReal torque2) { dJointAddHinge2Torques(_id, torque1, torque2); } }; class dPRJoint : public dJoint { dPRJoint (const dPRJoint &); void operator = (const dPRJoint &); public: dPRJoint() { } dPRJoint (dWorldID world, dJointGroupID group=0) { _id = dJointCreatePR (world, group); } dPRJoint (dWorld& world, dJointGroupID group=0) { _id = dJointCreatePR (world.id(), group); } void create (dWorldID world, dJointGroupID group=0) { if (_id) dJointDestroy (_id); _id = dJointCreatePR (world, group); } void create (dWorld& world, dJointGroupID group=0) { create(world.id(), group); } void setAnchor (dReal x, dReal y, dReal z) { dJointSetPRAnchor (_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 (_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 (_id, x, y, z); } void setAxis2 (const dVector3 a) { setAxis2(a[0], a[1], a[2]); } void getAnchor (dVector3 result) const { dJointGetPRAnchor (_id, result); } void getAxis1 (dVector3 result) const { dJointGetPRAxis1 (_id, result); } void getAxis2 (dVector3 result) const { dJointGetPRAxis2 (_id, result); } dReal getPosition() const { return dJointGetPRPosition (_id); } dReal getPositionRate() const { return dJointGetPRPositionRate (_id); } dReal getAngle() const { return dJointGetPRAngle (_id); } dReal getAngleRate() const { return dJointGetPRAngleRate (_id); } virtual void setParam (int parameter, dReal value) { dJointSetPRParam (_id, parameter, value); } virtual dReal getParam (int parameter) const { return dJointGetPRParam (_id, parameter); } }; class dPUJoint : public dJoint { dPUJoint (const dPUJoint &); void operator = (const dPUJoint &); public: dPUJoint() { } dPUJoint (dWorldID world, dJointGroupID group=0) { _id = dJointCreatePU (world, group); } dPUJoint (dWorld& world, dJointGroupID group=0) { _id = dJointCreatePU (world.id(), group); } void create (dWorldID world, dJointGroupID group=0) { if (_id) dJointDestroy (_id); _id = dJointCreatePU (world, group); } void create (dWorld& world, dJointGroupID group=0) { create(world.id(), group); } void setAnchor (dReal x, dReal y, dReal z) { dJointSetPUAnchor (_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 (_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 (_id, x, y, z); } void setAxis3 (dReal x, dReal y, dReal z) { dJointSetPUAxis3 (_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 (_id, x, y, z); } void setAxisP (const dVector3 a) { setAxisP(a[0], a[1], a[2]); } virtual void getAnchor (dVector3 result) const { dJointGetPUAnchor (_id, result); } void getAxis1 (dVector3 result) const { dJointGetPUAxis1 (_id, result); } void getAxis2 (dVector3 result) const { dJointGetPUAxis2 (_id, result); } void getAxis3 (dVector3 result) const { dJointGetPUAxis3 (_id, result); } void getAxisP (dVector3 result) const { dJointGetPUAxis3 (_id, result); } dReal getAngle1() const { return dJointGetPUAngle1 (_id); } dReal getAngle1Rate() const { return dJointGetPUAngle1Rate (_id); } dReal getAngle2() const { return dJointGetPUAngle2 (_id); } dReal getAngle2Rate() const { return dJointGetPUAngle2Rate (_id); } dReal getPosition() const { return dJointGetPUPosition (_id); } dReal getPositionRate() const { return dJointGetPUPositionRate (_id); } virtual void setParam (int parameter, dReal value) { dJointSetPUParam (_id, parameter, value); } virtual dReal getParam (int parameter) const { return dJointGetPUParam (_id, parameter); } // TODO: expose params through methods }; class dPistonJoint : public dJoint { // intentionally undefined, don't use these dPistonJoint (const dPistonJoint &); void operator = (const dPistonJoint &); public: dPistonJoint() { } dPistonJoint (dWorldID world, dJointGroupID group=0) { _id = dJointCreatePiston (world, group); } dPistonJoint (dWorld& world, dJointGroupID group=0) { _id = dJointCreatePiston (world, group); } void create (dWorldID world, dJointGroupID group=0) { if (_id) dJointDestroy (_id); _id = dJointCreatePiston (world, group); } void create (dWorld& world, dJointGroupID group=0) { create(world.id(), group); } void setAnchor (dReal x, dReal y, dReal z) { dJointSetPistonAnchor (_id, x, y, z); } void setAnchor (const dVector3 a) { setAnchor (a[0], a[1], a[2]); } void getAnchor (dVector3 result) const { dJointGetPistonAnchor (_id, result); } void getAnchor2 (dVector3 result) const { dJointGetPistonAnchor2 (_id, result); } void setAxis (dReal x, dReal y, dReal z) { dJointSetPistonAxis (_id, x, y, z); } void setAxis (const dVector3 a) { setAxis(a[0], a[1], a[2]); } void getAxis (dVector3 result) const { dJointGetPistonAxis (_id, result); } dReal getPosition() const { return dJointGetPistonPosition (_id); } dReal getPositionRate() const { return dJointGetPistonPositionRate (_id); } virtual void setParam (int parameter, dReal value) { dJointSetPistonParam (_id, parameter, value); } virtual dReal getParam (int parameter) const { return dJointGetPistonParam (_id, parameter); } // TODO: expose params through methods void addForce (dReal force) { dJointAddPistonForce (_id, force); } }; class dFixedJoint : public dJoint { // intentionally undefined, don't use these dFixedJoint (const dFixedJoint &); void operator = (const dFixedJoint &); public: dFixedJoint() { } dFixedJoint (dWorldID world, dJointGroupID group=0) { _id = dJointCreateFixed (world, group); } dFixedJoint (dWorld& world, dJointGroupID group=0) { _id = dJointCreateFixed (world, group); } void create (dWorldID world, dJointGroupID group=0) { if (_id) dJointDestroy (_id); _id = dJointCreateFixed (world, group); } void create (dWorld& world, dJointGroupID group=0) { create(world.id(), group); } void set() { dJointSetFixed (_id); } virtual void setParam (int parameter, dReal value) { dJointSetFixedParam (_id, parameter, value); } virtual dReal getParam (int parameter) const { return dJointGetFixedParam (_id, parameter); } // TODO: expose params through methods }; class dContactJoint : public dJoint { // intentionally undefined, don't use these dContactJoint (const dContactJoint &); void operator = (const dContactJoint &); public: dContactJoint() { } dContactJoint (dWorldID world, dJointGroupID group, dContact *contact) { _id = dJointCreateContact (world, group, contact); } dContactJoint (dWorld& world, dJointGroupID group, dContact *contact) { _id = dJointCreateContact (world.id(), group, contact); } void create (dWorldID world, dJointGroupID group, dContact *contact) { if (_id) dJointDestroy (_id); _id = dJointCreateContact (world, group, contact); } void create (dWorld& world, dJointGroupID group, dContact *contact) { create(world.id(), group, contact); } }; class dNullJoint : public dJoint { // intentionally undefined, don't use these dNullJoint (const dNullJoint &); void operator = (const dNullJoint &); public: dNullJoint() { } dNullJoint (dWorldID world, dJointGroupID group=0) { _id = dJointCreateNull (world, group); } dNullJoint (dWorld& world, dJointGroupID group=0) { _id = dJointCreateNull (world.id(), group); } void create (dWorldID world, dJointGroupID group=0) { if (_id) dJointDestroy (_id); _id = dJointCreateNull (world, group); } void create (dWorld& world, dJointGroupID group=0) { create(world.id(), group); } }; class dAMotorJoint : public dJoint { // intentionally undefined, don't use these dAMotorJoint (const dAMotorJoint &); void operator = (const dAMotorJoint &); public: dAMotorJoint() { } dAMotorJoint (dWorldID world, dJointGroupID group=0) { _id = dJointCreateAMotor (world, group); } dAMotorJoint (dWorld& world, dJointGroupID group=0) { _id = dJointCreateAMotor (world.id(), group); } void create (dWorldID world, dJointGroupID group=0) { if (_id) dJointDestroy (_id); _id = dJointCreateAMotor (world, group); } void create (dWorld& world, dJointGroupID group=0) { create(world.id(), group); } void setMode (int mode) { dJointSetAMotorMode (_id, mode); } int getMode() const { return dJointGetAMotorMode (_id); } void setNumAxes (int num) { dJointSetAMotorNumAxes (_id, num); } int getNumAxes() const { return dJointGetAMotorNumAxes (_id); } void setAxis (int anum, int rel, dReal x, dReal y, dReal z) { dJointSetAMotorAxis (_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 (_id, anum, result); } int getAxisRel (int anum) const { return dJointGetAMotorAxisRel (_id, anum); } void setAngle (int anum, dReal angle) { dJointSetAMotorAngle (_id, anum, angle); } dReal getAngle (int anum) const { return dJointGetAMotorAngle (_id, anum); } dReal getAngleRate (int anum) { return dJointGetAMotorAngleRate (_id,anum); } void setParam (int parameter, dReal value) { dJointSetAMotorParam (_id, parameter, value); } dReal getParam (int parameter) const { return dJointGetAMotorParam (_id, parameter); } // TODO: expose params through methods void addTorques(dReal torque1, dReal torque2, dReal torque3) { dJointAddAMotorTorques(_id, torque1, torque2, torque3); } }; class dLMotorJoint : public dJoint { // intentionally undefined, don't use these dLMotorJoint (const dLMotorJoint &); void operator = (const dLMotorJoint &); public: dLMotorJoint() { } dLMotorJoint (dWorldID world, dJointGroupID group=0) { _id = dJointCreateLMotor (world, group); } dLMotorJoint (dWorld& world, dJointGroupID group=0) { _id = dJointCreateLMotor (world.id(), group); } void create (dWorldID world, dJointGroupID group=0) { if (_id) dJointDestroy (_id); _id = dJointCreateLMotor (world, group); } void create (dWorld& world, dJointGroupID group=0) { create(world.id(), group); } void setNumAxes (int num) { dJointSetLMotorNumAxes (_id, num); } int getNumAxes() const { return dJointGetLMotorNumAxes (_id); } void setAxis (int anum, int rel, dReal x, dReal y, dReal z) { dJointSetLMotorAxis (_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 (_id, anum, result); } void setParam (int parameter, dReal value) { dJointSetLMotorParam (_id, parameter, value); } dReal getParam (int parameter) const { return dJointGetLMotorParam (_id, parameter); } // TODO: expose params through methods }; //} #endif #endif // Local variables: // mode:c++ // c-basic-offset:2 // End: ode-0.11.1/include/ode/odeinit.h0000644000076400007640000002266411156775756013326 00000000000000/************************************************************************* * * * 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 #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 = ~0U, //@< 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_ ode-0.11.1/include/ode/timer.h0000644000076400007640000000556310765152110012764 00000000000000/************************************************************************* * * * 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 #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 ode-0.11.1/include/ode/contact.h0000644000076400007640000000654611011020770013270 00000000000000/************************************************************************* * * * 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 #ifdef __cplusplus extern "C" { #endif enum { dContactMu2 = 0x001, dContactFDir1 = 0x002, dContactBounce = 0x004, dContactSoftERP = 0x008, dContactSoftCFM = 0x010, dContactMotion1 = 0x020, dContactMotion2 = 0x040, dContactMotionN = 0x080, dContactSlip1 = 0x100, dContactSlip2 = 0x200, dContactApprox0 = 0x0000, dContactApprox1_1 = 0x1000, dContactApprox1_2 = 0x2000, dContactApprox1 = 0x3000 }; typedef struct dSurfaceParameters { /* must always be defined */ int mode; dReal mu; /* only defined if the corresponding flag is set in mode */ dReal mu2; dReal bounce; dReal bounce_vel; 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 ode-0.11.1/include/ode/collision_trimesh.h0000644000076400007640000002100711116517541015365 00000000000000/************************************************************************* * * * 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; /* * These dont make much sense now, but they will later when we add more * features. */ ODE_API dTriMeshDataID dGeomTriMeshDataCreate(void); ODE_API void dGeomTriMeshDataDestroy(dTriMeshDataID g); enum { TRIMESH_FACE_NORMALS }; ODE_API void dGeomTriMeshDataSet(dTriMeshDataID g, int data_id, void* in_data); ODE_API void* dGeomTriMeshDataGet(dTriMeshDataID g, int data_id); /** * 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, dMatrix4 last_trans ); ODE_API 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); /* Preprocess the trimesh data to remove mark unnecessary edges and vertices */ ODE_API void dGeomTriMeshDataPreprocess(dTriMeshDataID g); /* Get and set the internal preprocessed trimesh data buffer, for loading and saving */ ODE_API void dGeomTriMeshDataGetBuffer(dTriMeshDataID g, unsigned char** buf, int* bufLen); 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_ */ ode-0.11.1/include/ode/compatibility.h0000644000076400007640000000366110041552512014507 00000000000000/************************************************************************* * * * 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 ode-0.11.1/include/ode/odecpp_collision.h0000644000076400007640000002672511122133067015172 00000000000000/************************************************************************* * * * 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 //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 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); } void setParams (int firstContact, int backfaceCull) { dGeomRaySetParams (_id, firstContact, backfaceCull); } void getParams (int *firstContact, int *backfaceCull) { dGeomRayGetParams (_id, firstContact, backfaceCull); } void setClosestHit (int closestHit) { dGeomRaySetClosestHit (_id, closestHit); } int getClosestHit() { return dGeomRayGetClosestHit (_id); } }; class 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); } }; //} #endif #endif ode-0.11.1/include/ode/Makefile.in0000644000076400007640000003101311206343412013523 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 DIST_COMMON = README $(libode_la_include_HEADERS) \ $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ode/src/config.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = 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 = `echo $$p | sed -e 's|^.*/||'`; am__installdirs = "$(DESTDIR)$(libode_la_includedir)" libode_la_includeHEADERS_INSTALL = $(INSTALL_HEADER) HEADERS = $(libode_la_include_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ 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@ 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@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODE_PRECISION = @ODE_PRECISION@ ODE_RELEASE = @ODE_RELEASE@ 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_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ 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@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ 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_trimesh.h \ mass.h \ odecpp.h \ common.h \ matrix.h \ odecpp_collision.h \ compatibility.h \ memory.h \ contact.h \ misc.h \ odemath.h \ odeinit.h \ collision.h \ error.h \ objects.h \ rotation.h \ collision_space.h \ export-dif.h \ ode.h \ timer.h \ odeconfig.h EXTRA_DIST = README 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'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign include/ode/Makefile .PRECIOUS: 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 mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-libode_la_includeHEADERS: $(libode_la_include_HEADERS) @$(NORMAL_INSTALL) test -z "$(libode_la_includedir)" || $(MKDIR_P) "$(DESTDIR)$(libode_la_includedir)" @list='$(libode_la_include_HEADERS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ f=$(am__strip_dir) \ echo " $(libode_la_includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(libode_la_includedir)/$$f'"; \ $(libode_la_includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(libode_la_includedir)/$$f"; \ done uninstall-libode_la_includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(libode_la_include_HEADERS)'; for p in $$list; do \ f=$(am__strip_dir) \ echo " rm -f '$(DESTDIR)$(libode_la_includedir)/$$f'"; \ rm -f "$(DESTDIR)$(libode_la_includedir)/$$f"; \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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)"; 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-am info-am: install-data-am: install-libode_la_includeHEADERS install-dvi: install-dvi-am 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 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-libode_la_includeHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libtool ctags 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-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 uninstall uninstall-am uninstall-libode_la_includeHEADERS # 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: ode-0.11.1/include/ode/objects.h0000644000076400007640000025315111136406244013276 00000000000000 /************************************************************************* * * * 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 #include #include #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 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); /** * @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. * @ingroup world * @param stepsize The number of seconds that the simulation has to advance. */ ODE_API void dWorldStep (dWorldID, 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 Step the world. * @ingroup world * @remarks * 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. * @remarks * 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. * @remarks * 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. */ ODE_API void dWorldQuickStep (dWorldID w, dReal stepsize); /** * @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); /* StepFast1 functions */ /** * @brief Step the world using the StepFast1 algorithm. * @param stepsize the nr of seconds to advance the simulation. * @param maxiterations The number of iterations to perform. * @ingroup world */ ODE_API void dWorldStepFast1(dWorldID, dReal stepsize, int maxiterations); /** * @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 Set the AutoEnableDepth parameter used by the StepFast1 algorithm. * @ingroup disable */ ODE_API void dWorldSetAutoEnableDepthSF1(dWorldID, int autoEnableDepth); /** * @brief Get the AutoEnableDepth parameter used by the StepFast1 algorithm. * @ingroup disable */ ODE_API int dWorldGetAutoEnableDepthSF1(dWorldID); /** * @brief Get auto disable linear threshold for newly created bodies. * @ingroup disable * @return the threshold */ ODE_API dReal dWorldGetAutoDisableLinearThreshold (dWorldID); /** * @brief Set auto disable linear threshold for newly created bodies. * @param linear_threshold default is 0.01 * @ingroup disable */ ODE_API void dWorldSetAutoDisableLinearThreshold (dWorldID, dReal linear_threshold); /** * @brief Get auto disable angular threshold for newly created bodies. * @ingroup disable * @return the threshold */ ODE_API dReal dWorldGetAutoDisableAngularThreshold (dWorldID); /** * @brief Set auto disable angular threshold for newly created bodies. * @param linear_threshold default is 0.01 * @ingroup disable */ ODE_API void dWorldSetAutoDisableAngularThreshold (dWorldID, dReal angular_threshold); /** * @brief Get auto disable linear average threshold for newly created bodies. * @ingroup disable * @return the threshold */ ODE_API dReal dWorldGetAutoDisableLinearAverageThreshold (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 dWorldSetAutoDisableLinearAverageThreshold (dWorldID, dReal linear_average_threshold); /** * @brief Get auto disable angular average threshold for newly created bodies. * @ingroup disable * @return the threshold */ ODE_API dReal dWorldGetAutoDisableAngularAverageThreshold (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 dWorldSetAutoDisableAngularAverageThreshold (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 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: *
 * 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
 * 
* @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 axis * @ingroup joints */ ODE_API void dJointSetHinge2Axis1 (dJointID, dReal x, dReal y, dReal z); /** * @brief set axis * @ingroup joints */ ODE_API void dJointSetHinge2Axis2 (dJointID, 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: *
 * 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
 * 
* * @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: *
 * 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
 * 
* @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: *
   * 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
   * 
* @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: *
   * 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
   * 
* @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 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); /** * @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 ode-0.11.1/include/ode/odemath.h0000644000076400007640000003033411141606005013253 00000000000000/************************************************************************* * * * 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 #ifdef __GNUC__ #define PURE_INLINE extern inline #else #define PURE_INLINE inline #endif /* * 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]) )) /* * 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 operatos /// For example this function can be used to replace ///
/// for (int i=0; i<3; ++i)
///   a[i] += b[i] + c[i];
/// 
#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) /* * Length, and squared length helpers. dLENGTH returns the length of a dVector3. * dLENGTHSQUARED return the squared length of a dVector3. */ #define dLENGTHSQUARED(a) (((a)[0])*((a)[0]) + ((a)[1])*((a)[1]) + ((a)[2])*((a)[2])) #ifdef __cplusplus PURE_INLINE dReal dLENGTH (const dReal *a) { return dSqrt(dLENGTHSQUARED(a)); } #else #define dLENGTH(a) ( dSqrt( ((a)[0])*((a)[0]) + ((a)[1])*((a)[1]) + ((a)[2])*((a)[2]) ) ) #endif /* __cplusplus */ /* * 3-way dot product. dDOTpq means that elements of `a' and `b' are spaced * p and q indexes apart respectively. dDOT() means dDOT11. * in C++ we could use function templates to get all the versions of these * functions - but on some compilers this will result in sub-optimal code. */ #define dDOTpq(a,b,p,q) ((a)[0]*(b)[0] + (a)[p]*(b)[q] + (a)[2*(p)]*(b)[2*(q)]) #ifdef __cplusplus PURE_INLINE dReal dDOT (const dReal *a, const dReal *b) { return dDOTpq(a,b,1,1); } PURE_INLINE dReal dDOT13 (const dReal *a, const dReal *b) { return dDOTpq(a,b,1,3); } PURE_INLINE dReal dDOT31 (const dReal *a, const dReal *b) { return dDOTpq(a,b,3,1); } PURE_INLINE dReal dDOT33 (const dReal *a, const dReal *b) { return dDOTpq(a,b,3,3); } PURE_INLINE dReal dDOT14 (const dReal *a, const dReal *b) { return dDOTpq(a,b,1,4); } PURE_INLINE dReal dDOT41 (const dReal *a, const dReal *b) { return dDOTpq(a,b,4,1); } PURE_INLINE dReal dDOT44 (const dReal *a, const dReal *b) { return dDOTpq(a,b,4,4); } #else #define dDOT(a,b) dDOTpq(a,b,1,1) #define dDOT13(a,b) dDOTpq(a,b,1,3) #define dDOT31(a,b) dDOTpq(a,b,3,1) #define dDOT33(a,b) dDOTpq(a,b,3,3) #define dDOT14(a,b) dDOTpq(a,b,1,4) #define dDOT41(a,b) dDOTpq(a,b,4,1) #define dDOT44(a,b) dDOTpq(a,b,4,4) #endif /* __cplusplus */ /* * 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) /* * compute the distance between two 3D-vectors */ #ifdef __cplusplus PURE_INLINE dReal dDISTANCE (const dVector3 a, const dVector3 b) { return dSqrt( (a[0]-b[0])*(a[0]-b[0]) + (a[1]-b[1])*(a[1]-b[1]) + (a[2]-b[2])*(a[2]-b[2]) ); } #else #define dDISTANCE(a,b) \ (dSqrt( ((a)[0]-(b)[0])*((a)[0]-(b)[0]) + ((a)[1]-(b)[1])*((a)[1]-(b)[1]) + ((a)[2]-(b)[2])*((a)[2]-(b)[2]) )) #endif /* * special case matrix multipication, with operator selection */ #define dMULTIPLYOP0_331(A,op,B,C) \ do { \ (A)[0] op dDOT((B),(C)); \ (A)[1] op dDOT((B+4),(C)); \ (A)[2] op dDOT((B+8),(C)); \ } while(0) #define dMULTIPLYOP1_331(A,op,B,C) \ do { \ (A)[0] op dDOT41((B),(C)); \ (A)[1] op dDOT41((B+1),(C)); \ (A)[2] op dDOT41((B+2),(C)); \ } while(0) #define dMULTIPLYOP0_133(A,op,B,C) \ do { \ (A)[0] op dDOT14((B),(C)); \ (A)[1] op dDOT14((B),(C+1)); \ (A)[2] op dDOT14((B),(C+2)); \ } while(0) #define dMULTIPLYOP0_333(A,op,B,C) \ do { \ (A)[0] op dDOT14((B),(C)); \ (A)[1] op dDOT14((B),(C+1)); \ (A)[2] op dDOT14((B),(C+2)); \ (A)[4] op dDOT14((B+4),(C)); \ (A)[5] op dDOT14((B+4),(C+1)); \ (A)[6] op dDOT14((B+4),(C+2)); \ (A)[8] op dDOT14((B+8),(C)); \ (A)[9] op dDOT14((B+8),(C+1)); \ (A)[10] op dDOT14((B+8),(C+2)); \ } while(0) #define dMULTIPLYOP1_333(A,op,B,C) \ do { \ (A)[0] op dDOT44((B),(C)); \ (A)[1] op dDOT44((B),(C+1)); \ (A)[2] op dDOT44((B),(C+2)); \ (A)[4] op dDOT44((B+1),(C)); \ (A)[5] op dDOT44((B+1),(C+1)); \ (A)[6] op dDOT44((B+1),(C+2)); \ (A)[8] op dDOT44((B+2),(C)); \ (A)[9] op dDOT44((B+2),(C+1)); \ (A)[10] op dDOT44((B+2),(C+2)); \ } while(0) #define dMULTIPLYOP2_333(A,op,B,C) \ do { \ (A)[0] op dDOT((B),(C)); \ (A)[1] op dDOT((B),(C+4)); \ (A)[2] op dDOT((B),(C+8)); \ (A)[4] op dDOT((B+4),(C)); \ (A)[5] op dDOT((B+4),(C+4)); \ (A)[6] op dDOT((B+4),(C+8)); \ (A)[8] op dDOT((B+8),(C)); \ (A)[9] op dDOT((B+8),(C+4)); \ (A)[10] op dDOT((B+8),(C+8)); \ } while(0) #ifdef __cplusplus #define DECL template PURE_INLINE void /* Note: NEVER call any of these functions/macros with the same variable for A and C, it is not equivalent to A*=B. */ DECL dMULTIPLY0_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_331(A,=,B,C); } DECL dMULTIPLY1_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_331(A,=,B,C); } DECL dMULTIPLY0_133(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_133(A,=,B,C); } DECL dMULTIPLY0_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_333(A,=,B,C); } DECL dMULTIPLY1_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_333(A,=,B,C); } DECL dMULTIPLY2_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP2_333(A,=,B,C); } DECL dMULTIPLYADD0_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_331(A,+=,B,C); } DECL dMULTIPLYADD1_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_331(A,+=,B,C); } DECL dMULTIPLYADD0_133(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_133(A,+=,B,C); } DECL dMULTIPLYADD0_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_333(A,+=,B,C); } DECL dMULTIPLYADD1_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_333(A,+=,B,C); } DECL dMULTIPLYADD2_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP2_333(A,+=,B,C); } #undef DECL #else #define dMULTIPLY0_331(A,B,C) dMULTIPLYOP0_331(A,=,B,C) #define dMULTIPLY1_331(A,B,C) dMULTIPLYOP1_331(A,=,B,C) #define dMULTIPLY0_133(A,B,C) dMULTIPLYOP0_133(A,=,B,C) #define dMULTIPLY0_333(A,B,C) dMULTIPLYOP0_333(A,=,B,C) #define dMULTIPLY1_333(A,B,C) dMULTIPLYOP1_333(A,=,B,C) #define dMULTIPLY2_333(A,B,C) dMULTIPLYOP2_333(A,=,B,C) #define dMULTIPLYADD0_331(A,B,C) dMULTIPLYOP0_331(A,+=,B,C) #define dMULTIPLYADD1_331(A,B,C) dMULTIPLYOP1_331(A,+=,B,C) #define dMULTIPLYADD0_133(A,B,C) dMULTIPLYOP0_133(A,+=,B,C) #define dMULTIPLYADD0_333(A,B,C) dMULTIPLYOP0_333(A,+=,B,C) #define dMULTIPLYADD1_333(A,B,C) dMULTIPLYOP1_333(A,+=,B,C) #define dMULTIPLYADD2_333(A,B,C) dMULTIPLYOP2_333(A,+=,B,C) #endif #ifdef __cplusplus extern "C" { #endif /* * normalize 3x1 and 4x1 vectors (i.e. scale them to unit length) */ #if defined(__ODE__) int _dSafeNormalize3 (dVector3 a); int _dSafeNormalize4 (dVector4 a); static __inline void _dNormalize3(dVector3 a) { int bNormalizationResult = _dSafeNormalize3(a); dIASSERT(bNormalizationResult); dVARIABLEUSED(bNormalizationResult); } static __inline void _dNormalize4(dVector4 a) { int bNormalizationResult = _dSafeNormalize4(a); dIASSERT(bNormalizationResult); dVARIABLEUSED(bNormalizationResult); } #endif // defined(__ODE__) // 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 #if defined(__ODE__) // For internal use #define dSafeNormalize3(a) _dSafeNormalize3(a) #define dSafeNormalize4(a) _dSafeNormalize4(a) #define dNormalize3(a) _dNormalize3(a) #define dNormalize4(a) _dNormalize4(a) #endif // defined(__ODE__) /* * 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 */ ODE_API void dOrthogonalizeR(dMatrix3 m); #ifdef __cplusplus } #endif #endif ode-0.11.1/include/ode/matrix.h0000644000076400007640000001721510411045046013142 00000000000000/************************************************************************* * * * 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 #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 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 ode-0.11.1/include/ode/rotation.h0000644000076400007640000000603410411045046013472 00000000000000/************************************************************************* * * * 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 #include #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 ode-0.11.1/include/ode/mass.h0000644000076400007640000001247211123376105012605 00000000000000/************************************************************************* * * * 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 #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 ODE_API_DEPRECATED void dMassSetCappedCylinder(dMass *a, dReal b, int c, dReal d, dReal e); ODE_API ODE_API_DEPRECATED 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 ode-0.11.1/include/ode/common.h0000644000076400007640000002714511174214530013134 00000000000000/************************************************************************* * * * 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 #include #include #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 on some platforms (like MS-Windows) */ #ifndef M_PI #define M_PI REAL(3.1415926535897932384626433832795029) #endif #ifndef M_SQRT1_2 #define M_SQRT1_2 REAL(0.7071067811865475244008443621048490) #endif /* 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 */ #ifndef dNODEBUG # if defined(__STDC__) && __STDC_VERSION__ >= 199901L # define __FUNCTION__ __func__ # endif # ifdef __GNUC__ # define dIASSERT(a) if (!(a)) dDebug (d_ERR_IASSERT, \ "assertion \"" #a "\" failed in %s() [%s]",__FUNCTION__,__FILE__); # define dUASSERT(a,msg) if (!(a)) dDebug (d_ERR_UASSERT, \ msg " in %s()", __FUNCTION__); # define dDEBUGMSG(msg) dMessage (d_ERR_UASSERT, \ msg " in %s() File %s Line %d", __FUNCTION__, __FILE__,__LINE__); # else // not __GNUC__ # define dIASSERT(a) if (!(a)) dDebug (d_ERR_IASSERT, \ "assertion \"" #a "\" failed in %s:%d",__FILE__,__LINE__); # define dUASSERT(a,msg) if (!(a)) dDebug (d_ERR_UASSERT, \ msg " (%s:%d)", __FILE__,__LINE__); # define dDEBUGMSG(msg) dMessage (d_ERR_UASSERT, \ msg " (%s:%d)", __FILE__,__LINE__); # endif #else # define dIASSERT(a) ; # define dUASSERT(a,msg) ; # define dDEBUGMSG(msg) ; #endif #define dAASSERT(a) dUASSERT(a,"Bad argument(s)") // Macro used to suppress unused variable warning #define dVARIABLEUSED(a) ((void)a) /* 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 uint32 dTriIndex; #else // dTRIMESH_GIMPACT typedef uint16 dTriIndex; #endif // dTRIMESH_GIMPACT #else // dTRIMESH_16BIT_INDICES typedef uint32 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)-1)|3)+1) : (a)) /* these types are mainly just used in headers */ typedef dReal dVector3[4]; typedef dReal dVector4[4]; typedef dReal dMatrix3[4*3]; typedef dReal dMatrix4[4*4]; typedef dReal dMatrix6[8*6]; typedef dReal dQuaternion[4]; /* 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 dFMod(a,b) (fmodf(a,b)) /* modulo */ #define dFloor(x) floorf(x) /* floor */ #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 #define dCopySign(a,b) ((dReal)copysignf(a,b)) #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 dFMod(a,b) (fmod((a),(b))) #define dFloor(x) floor(x) #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 #define dCopySign(a,b) (copysign((a),(b))) #else #error You must #define dSINGLE or dDOUBLE #endif /* 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; struct dxJointNode; struct dxJointGroup; 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 } 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, \ 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, \ 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 }; /* 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_EXT_malloc_not_alloca * ODE_EXT_gyroscopic * ODE_OPC_16bit_indices * ODE_OPC_new_collider */ 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 ode-0.11.1/include/ode/collision.h0000644000076400007640000014005711137744225013645 00000000000000/************************************************************************* * * * 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 #include #include // Include odeinit.h for backward compatibility as some of initialization APIs // were initally declared in current header. #include #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); /* ************************************************************************ */ /* 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, dReal *_planes, unsigned int _planecount, dReal *_points, unsigned int _pointcount,unsigned int *_polygons); ODE_API void dGeomSetConvex (dGeomID g, dReal *_planes, unsigned int _count, dReal *_points, unsigned int _pointcount,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 void dGeomRaySetParams (dGeomID g, int FirstContact, int BackfaceCull); ODE_API void dGeomRayGetParams (dGeomID g, int *FirstContact, int *BackfaceCull); ODE_API void dGeomRaySetClosestHit (dGeomID g, int closestHit); ODE_API int dGeomRayGetClosestHit (dGeomID g); #include "collision_trimesh.h" ODE_API dGeomID dCreateGeomTransform (dSpaceID space); ODE_API void dGeomTransformSetGeom (dGeomID g, dGeomID obj); ODE_API dGeomID dGeomTransformGetGeom (dGeomID g); ODE_API void dGeomTransformSetCleanup (dGeomID g, int mode); ODE_API int dGeomTransformGetCleanup (dGeomID g); ODE_API void dGeomTransformSetInfo (dGeomID g, int mode); 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 ode-0.11.1/include/ode/ode.h0000644000076400007640000000414711005317717012414 00000000000000/************************************************************************* * * * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif ode-0.11.1/include/ode/Makefile.am0000644000076400007640000000067511010400636013517 00000000000000libode_la_includedir = $(includedir)/ode libode_la_include_HEADERS = collision_trimesh.h \ mass.h \ odecpp.h \ common.h \ matrix.h \ odecpp_collision.h \ compatibility.h \ memory.h \ contact.h \ misc.h \ odemath.h \ odeinit.h \ collision.h \ error.h \ objects.h \ rotation.h \ collision_space.h \ export-dif.h \ ode.h \ timer.h \ odeconfig.h EXTRA_DIST = README ode-0.11.1/include/ode/collision_space.h0000644000076400007640000001471211156775756015034 00000000000000/************************************************************************* * * * 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 #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 ode-0.11.1/include/ode/README0000644000076400007640000000062507675642007012364 00000000000000 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! ode-0.11.1/include/ode/misc.h0000644000076400007640000000640310737023615012577 00000000000000/************************************************************************* * * * 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 #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 */ #ifdef __cplusplus ODE_API void dPrintMatrix (const dReal *A, int n, int m, char *fmt = "%10.4f ", FILE *f=stdout); #else ODE_API void dPrintMatrix (const dReal *A, int n, int m, char *fmt, FILE *f); #endif /* 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 #endif ode-0.11.1/include/ode/memory.h0000644000076400007640000000514510765152110013150 00000000000000/************************************************************************* * * * 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 #ifdef __cplusplus extern "C" { #endif /* function types to allocate and free memory */ typedef void * dAllocFunction (size_t size); typedef void * dReallocFunction (void *ptr, size_t oldsize, size_t newsize); typedef void dFreeFunction (void *ptr, size_t 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 (size_t size); ODE_API void * dRealloc (void *ptr, size_t oldsize, size_t newsize); ODE_API void dFree (void *ptr, size_t size); #ifdef __cplusplus } #endif #endif ode-0.11.1/include/ode/export-dif.h0000644000076400007640000000331610411045046013714 00000000000000/************************************************************************* * * * 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_API void dWorldExportDIF (dWorldID w, FILE *file, const char *world_name); #endif ode-0.11.1/include/Makefile.in0000644000076400007640000003510511206343412012762 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ode/src/config.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-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 uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ 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@ 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@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODE_PRECISION = @ODE_PRECISION@ ODE_RELEASE = @ODE_RELEASE@ 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_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ 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@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ 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'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign include/Makefile .PRECIOUS: 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 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. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; 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; \ (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" $(RECURSIVE_CLEAN_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ 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 || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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 \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-exec-am: install-html: install-html-recursive install-info: install-info-recursive install-man: install-pdf: install-pdf-recursive install-ps: install-ps-recursive 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: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ ctags ctags-recursive 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-recursive \ uninstall uninstall-am # 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: ode-0.11.1/include/drawstuff/0000777000076400007640000000000011206343456013012 500000000000000ode-0.11.1/include/drawstuff/drawstuff.h0000644000076400007640000002334010770741517015113 00000000000000/************************************************************************* * * * 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 /* 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 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], float *_planes, unsigned int _planecount, float *_points, unsigned int _pointcount, 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 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], double *_planes, unsigned int _planecount, double *_points, unsigned int _pointcount, 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 ode-0.11.1/include/drawstuff/Makefile.in0000644000076400007640000002544311206343412014773 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ode/src/config.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = HEADERS = $(noinst_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ 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@ 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@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODE_PRECISION = @ODE_PRECISION@ ODE_RELEASE = @ODE_RELEASE@ 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_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ 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@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ 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'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign include/drawstuff/Makefile .PRECIOUS: 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 mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-am info-am: install-data-am: install-dvi: install-dvi-am 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 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 all all-am check check-am clean clean-generic \ clean-libtool ctags 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 uninstall \ uninstall-am # 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: ode-0.11.1/include/drawstuff/Makefile.am0000644000076400007640000000005110726351261014755 00000000000000 noinst_HEADERS = drawstuff.h version.h ode-0.11.1/include/drawstuff/version.h0000644000076400007640000000326007506200314014556 00000000000000/************************************************************************* * * * 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 ode-0.11.1/include/Makefile.am0000644000076400007640000000003010726322630012743 00000000000000SUBDIRS = ode drawstuff ode-0.11.1/ltmain.sh0000755000076400007640000073434611206343410011130 00000000000000# Generated from ltmain.m4sh. # ltmain.sh (GNU libtool) 2.2.6 # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, # or obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Usage: $progname [OPTION]... [MODE-ARG]... # # Provide generalized library-building support services. # # --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 # --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 informational messages (default) # --version print version information # -h, --help print short or 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. # 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) # $progname: (GNU libtool) 2.2.6 # automake: $automake_version # autoconf: $autoconf_version # # Report bugs to . PROGRAM=ltmain.sh PACKAGE=libtool VERSION=2.2.6 TIMESTAMP="" package_revision=1.3012 # define SED for historic ltconfig's generated by Libtool 1.3 test -z "$SED" && SED=sed # 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 # NLS nuisances: We save the old values to restore during execute mode. # Only set LANG and LC_ALL to C if already set. # These must not be set unconditionally because not all systems understand # e.g. LANG=C (notably SCO). lt_user_locale= lt_safe_locale= for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${$lt_var+set}\" = set; then save_$lt_var=\$$lt_var $lt_var=C export $lt_var lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" fi" done $lt_unset CDPATH : ${CP="cp -f"} : ${ECHO="echo"} : ${EGREP="/bin/grep -E"} : ${FGREP="/bin/grep -F"} : ${GREP="/bin/grep"} : ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SED="/bin/sed"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} # Global variables: 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. exit_status=$EXIT_SUCCESS # Make sure IFS has a sensible default lt_nl=' ' IFS=" $lt_nl" dirname="s,/[^/]*$,," basename="s,^.*/,," # 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" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` } # Generated shell functions inserted here. # 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: # In the unlikely event $progname began with a '-', it would play havoc with # func_echo (imagine progname=-n), so we prepend ./ in that case: func_dirname_and_basename "$progpath" progname=$func_basename_result case $progname in -*) progname=./$progname ;; esac # Make sure we have an absolute path for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=$func_dirname_result progdir=`cd "$progdir" && pwd` progpath="$progdir/$progname" ;; *) save_IFS="$IFS" IFS=: for progdir in $PATH; do IFS="$save_IFS" test -x "$progdir/$progname" && break done IFS="$save_IFS" test -n "$progdir" || progdir=`pwd` progpath="$progdir/$progname" ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed="${SED}"' -e 1s/^X//' sed_quote_subst='s/\([`"$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Re-`\' parameter expansions in output of double_quote_subst that were # `\'-ed in input to the same. If an odd number of `\' preceded a '$' # in input to 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 '$'. bs='\\' bs2='\\\\' bs4='\\\\\\\\' dollar='\$' sed_double_backslash="\ s/$bs4/&\\ /g s/^$bs2$dollar/$bs&/ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g s/\n//g" # Standard options: opt_dry_run=false opt_help=false opt_quiet=false opt_verbose=false opt_warning=: # func_echo arg... # Echo program name prefixed message, along with the current mode # name if it has been set yet. func_echo () { $ECHO "$progname${mode+: }$mode: $*" } # func_verbose arg... # Echo program name prefixed message in verbose mode only. func_verbose () { $opt_verbose && 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_error arg... # Echo program name prefixed message to standard error. func_error () { $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2 } # func_warning arg... # Echo program name prefixed warning message to standard error. func_warning () { $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2 # bash bug again: : } # func_fatal_error arg... # Echo program name prefixed message to standard error, and exit. func_fatal_error () { func_error ${1+"$@"} exit $EXIT_FAILURE } # func_fatal_help arg... # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { func_error ${1+"$@"} func_fatal_error "$help" } help="Try \`$progname --help' for more information." ## default # func_grep expression filename # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $GREP "$1" "$2" >/dev/null 2>&1 } # func_mkdir_p directory-path # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { my_directory_path="$1" my_dir_list= if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then # Protect directory names starting with `-' case $my_directory_path in -*) my_directory_path="./$my_directory_path" ;; esac # While some portion of DIR does not yet exist... while test ! -d "$my_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. my_dir_list="$my_directory_path:$my_dir_list" # If the last portion added has no slash in it, the list is done case $my_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"` done my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'` save_mkdir_p_IFS="$IFS"; IFS=':' for my_dir in $my_dir_list; do IFS="$save_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 "$my_dir" 2>/dev/null || : done IFS="$save_mkdir_p_IFS" # Bail out if we (or some other process) failed to create a directory. test -d "$my_directory_path" || \ func_fatal_error "Failed to create \`$1'" fi } # func_mktempdir [string] # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, STRING is the basename for that directory. func_mktempdir () { my_template="${TMPDIR-/tmp}/${1-$progname}" if test "$opt_dry_run" = ":"; then # Return a directory name, but don't create it in dry-run mode my_tmpdir="${my_template}-$$" else # If mktemp works, use that first and foremost my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` if test ! -d "$my_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race my_tmpdir="${my_template}-${RANDOM-0}$$" save_mktempdir_umask=`umask` umask 0077 $MKDIR "$my_tmpdir" umask $save_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$my_tmpdir" || \ func_fatal_error "cannot create temporary directory \`$my_tmpdir'" fi $ECHO "X$my_tmpdir" | $Xsed } # func_quote_for_eval arg # Aesthetically quote ARG to be evaled later. # This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT # is double-quoted, suitable for a subsequent eval, whereas # FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters # which are still active within double quotes backslashified. func_quote_for_eval () { case $1 in *[\\\`\"\$]*) func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;; *) func_quote_for_eval_unquoted_result="$1" ;; esac case $func_quote_for_eval_unquoted_result in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and and variable # expansion for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" ;; *) func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" esac } # 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 () { case $1 in *[\\\`\"]*) my_arg=`$ECHO "X$1" | $Xsed \ -e "$double_quote_subst" -e "$sed_double_backslash"` ;; *) my_arg="$1" ;; esac case $my_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. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") my_arg="\"$my_arg\"" ;; esac func_quote_for_expand_result="$my_arg" } # func_show_eval cmd [fail_exp] # Unless opt_silent 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 () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$my_cmd" my_status=$? if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_show_eval_locale cmd [fail_exp] # Unless opt_silent 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 () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$lt_user_locale $my_cmd" my_status=$? eval "$lt_safe_locale" if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_version # Echo version message to standard output and exit. func_version () { $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / { s/^# // s/^# *$// s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ p }' < "$progpath" exit $? } # func_usage # Echo short help message to standard output and exit. func_usage () { $SED -n '/^# Usage:/,/# -h/ { s/^# // s/^# *$// s/\$progname/'$progname'/ p }' < "$progpath" $ECHO $ECHO "run \`$progname --help | more' for full usage" exit $? } # func_help # Echo long help message to standard output and exit. func_help () { $SED -n '/^# Usage:/,/# Report bugs to/ { s/^# // s/^# *$// s*\$progname*'$progname'* s*\$host*'"$host"'* s*\$SHELL*'"$SHELL"'* s*\$LTCC*'"$LTCC"'* s*\$LTCFLAGS*'"$LTCFLAGS"'* s*\$LD*'"$LD"'* s/\$with_gnu_ld/'"$with_gnu_ld"'/ s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/ s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/ p }' < "$progpath" exit $? } # func_missing_arg argname # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { func_error "missing argument for $1" exit_cmd=exit } exit_cmd=: # Check that we have a working $ECHO. if test "X$1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X$1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then # Yippee, $ECHO works! : else # Restart under the correct shell, and then maybe $ECHO will work. exec $SHELL "$progpath" --no-reexec ${1+"$@"} fi if test "X$1" = X--fallback-echo; then # used as fallback echo shift cat </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 } # Parse options once, thoroughly. This comes as soon as possible in # the script to make things like `libtool --version' happen quickly. { # 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 # Parse non-mode specific arguments: while test "$#" -gt 0; do opt="$1" shift case $opt in --config) func_config ;; --debug) preserve_args="$preserve_args $opt" func_echo "enabling shell trace mode" opt_debug='set -x' $opt_debug ;; -dlopen) test "$#" -eq 0 && func_missing_arg "$opt" && break execute_dlfiles="$execute_dlfiles $1" shift ;; --dry-run | -n) opt_dry_run=: ;; --features) func_features ;; --finish) mode="finish" ;; --mode) test "$#" -eq 0 && func_missing_arg "$opt" && break 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 $opt" exit_cmd=exit break ;; esac mode="$1" shift ;; --preserve-dup-deps) opt_duplicate_deps=: ;; --quiet|--silent) preserve_args="$preserve_args $opt" opt_silent=: ;; --verbose| -v) preserve_args="$preserve_args $opt" opt_silent=false ;; --tag) test "$#" -eq 0 && func_missing_arg "$opt" && break preserve_args="$preserve_args $opt $1" func_enable_tag "$1" # tagname is set here shift ;; # Separate optargs to long options: -dlopen=*|--mode=*|--tag=*) func_opt_split "$opt" set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"} shift ;; -\?|-h) func_usage ;; --help) opt_help=: ;; --version) func_version ;; -*) func_fatal_help "unrecognized option \`$opt'" ;; *) nonopt="$opt" break ;; esac done case $host in *cygwin* | *mingw* | *pw32* | *cegcc*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_duplicate_deps ;; esac # Having warned about all mis-specified options, bail out if # anything was wrong. $exit_cmd $EXIT_FAILURE } # 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 } ## ----------- ## ## Main. ## ## ----------- ## $opt_help || { # Sanity checks first: func_check_version_match if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then func_fatal_configuration "not configured to build any kind of library" fi test -z "$mode" && func_fatal_error "error: you must specify a MODE." # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$execute_dlfiles" && test "$mode" != execute; 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=$mode' for more information." } # 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 \ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # 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 "$lalib_p" = yes } # 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 () { func_lalib_p "$1" } # 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_ltwrapper_scriptname_result="" if func_ltwrapper_executable_p "$1"; then func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" fi } # 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 () { $opt_debug save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$save_ifs eval cmd=\"$cmd\" 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 () { $opt_debug case $1 in */* | *\\*) . "$1" ;; *) . "./$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 () { $opt_debug if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_quote_for_eval "$arg" CC_quoted="$CC_quoted $func_quote_for_eval_result" done 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 "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) ;; # 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_quote_for_eval "$arg" CC_quoted="$CC_quoted $func_quote_for_eval_result" done case "$@ " in " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) # 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 "$build_libtool_libs" = yes; then write_lobj=\'${2}\' else write_lobj=none fi if test "$build_old_libs" = yes; then write_oldobj=\'${3}\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T <?"'"'"' &()|`$[]' \ && 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 "$build_old_libs" = yes; 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 "$pic_mode" = no && test "$deplibs_check_method" != pass_all; 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 "$compiler_c_o" = no; then output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e '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 "$need_locks" = yes; 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 "$need_locks" = warn; 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 removelist="$removelist $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist removelist="$removelist $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 if test -n "$fix_srcfile_path"; then eval srcfile=\"$fix_srcfile_path\" fi func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test "$build_libtool_libs" = yes; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test "$pic_mode" != no; 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 command="$command -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && 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 "$suppress_opt" = yes; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test "$build_old_libs" = yes; then if test "$pic_mode" != yes; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test "$compiler_c_o" = yes; then command="$command -o $obj" fi # Suppress compiler output if we already did a PIC compilation. command="$command$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && 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 "$need_locks" != no; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test "$mode" = compile && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $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 building PIC objects only -prefer-non-pic try to building 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 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 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 -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 -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 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 \`$mode'" ;; esac $ECHO $ECHO "Try \`$progname --help' for more information about other modes." exit $? } # Now that we've collected a possible --mode arg, show help if necessary $opt_help && func_mode_help # func_mode_execute arg... func_mode_execute () { $opt_debug # 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 $execute_dlfiles; do test -f "$file" \ || func_fatal_help "\`$file' is not a file" dir= case $file in *.la) # 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 dir="$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 -*) ;; *) # 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_quote_for_eval "$file" args="$args $func_quote_for_eval_result" done if test "X$opt_dry_run" = Xfalse; then 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" else # 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 fi } test "$mode" = execute && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $opt_debug libdirs="$nonopt" admincmds= if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for dir do libdirs="$libdirs $dir" done 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" || admincmds="$admincmds $cmds" fi done fi # Exit here if they wanted silent mode. $opt_silent && exit $EXIT_SUCCESS $ECHO "X----------------------------------------------------------------------" | $Xsed $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 "X----------------------------------------------------------------------" | $Xsed exit $EXIT_SUCCESS } test "$mode" = finish && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $opt_debug # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || # Allow the use of GNU shtool's install command. $ECHO "X$nonopt" | $GREP shtool >/dev/null; 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" install_prog="$install_prog$func_quote_for_eval_result" # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= for arg do if test -n "$dest"; then files="$files $dest" dest=$arg continue fi case $arg in -d) isdir=yes ;; -f) case " $install_prog " in *[\\\ /]cp\ *) ;; *) prev=$arg ;; esac ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" install_prog="$install_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 -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=yes if test "$isdir" = yes; 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. staticlibs="$staticlibs $file" ;; *.la) # 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 "*) ;; *) current_libdirs="$current_libdirs $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) future_libdirs="$future_libdirs $libdir" ;; esac fi func_dirname "$file" "/" "" dir="$func_dirname_result" dir="$dir$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "X$destdir" | $Xsed -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 "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "X$relink_command" | $Xsed -e "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_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme="$stripme" case $host_os in cygwin* | mingw* | pw32* | cegcc*) 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" && staticlibs="$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 "$build_old_libs" = yes; 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=yes 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 "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then func_warning "\`$lib' has not been installed in \`$libdir'" finalize=no fi done relink_command= func_source "$wrapper" outputname= if test "$fast_install" = no && test -n "$relink_command"; then $opt_dry_run || { if test "$finalize" = yes; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file="$func_basename_result" outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$ECHO "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` $opt_silent || { 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 "X$file$stripped_ext" | $Xsed -e "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_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $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 "$mode" = install && 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 () { $opt_debug my_outputname="$1" my_originator="$2" my_pic_p="${3-no}" my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; 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$TIMESTAMP) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; 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 "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` for progfile in $progfiles; do func_verbose "extracting global C symbols from \`$progfile'" $opt_dry_run || eval "$NM $progfile | $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" $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'" } 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 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 $ECHO >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; " case $host in *cygwin* | *mingw* | *cegcc* ) $ECHO >> "$output_objdir/$my_dlsyms" "\ /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */" lt_dlsym_const= ;; *osf5*) echo >> "$output_objdir/$my_dlsyms" "\ /* This system does not cope well with relocations in const data */" lt_dlsym_const= ;; *) lt_dlsym_const=const ;; esac $ECHO >> "$output_objdir/$my_dlsyms" "\ extern $lt_dlsym_const lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[]; $lt_dlsym_const lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = {\ { \"$my_originator\", (void *) 0 }," 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" ;; *) if test "X$my_pic_p" != Xno; then pic_flag_for_symtable=" $pic_flag" fi ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) symtab_cflags="$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"' # 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 "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "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 "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` fi } # 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. func_win32_libid () { $opt_debug 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 if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then win32_nmres=`eval $NM -f posix -A $1 | $SED -n -e ' 1,100{ / I /{ s,.*,import, p q } }'` 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_extract_an_archive dir oldlib func_extract_an_archive () { $opt_debug f_ex_an_ar_dir="$1"; shift f_ex_an_ar_oldlib="$1" func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" 'exit $?' 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 () { $opt_debug 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` darwin_base_archive=`basename "$darwin_archive"` 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 "$basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | $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 | $NL2SP` done func_extract_archives_result="$my_oldobjs" } # func_emit_wrapper_part1 [arg=no] # # Emit the first part of a libtool wrapper script on stdout. # For more information, see the description associated with # func_emit_wrapper(), below. func_emit_wrapper_part1 () { func_emit_wrapper_part1_arg1=no if test -n "$1" ; then func_emit_wrapper_part1_arg1=$1 fi $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $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. Xsed='${SED} -e 1s/^X//' 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 ECHO=\"$qecho\" file=\"\$0\" # Make sure echo works. if test \"X\$1\" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test \"X\`{ \$ECHO '\t'; } 2>/dev/null\`\" = 'X\t'; then # Yippee, \$ECHO works! : else # Restart under the correct shell, and then maybe \$ECHO will work. exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} fi fi\ " $ECHO "\ # Find the directory that this script lives in. thisdir=\`\$ECHO \"X\$file\" | \$Xsed -e '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 \"X\$file\" | \$Xsed -e '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 \"X\$file\" | \$Xsed -e 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` done " } # end: func_emit_wrapper_part1 # func_emit_wrapper_part2 [arg=no] # # Emit the second part of a libtool wrapper script on stdout. # For more information, see the description associated with # func_emit_wrapper(), below. func_emit_wrapper_part2 () { func_emit_wrapper_part2_arg1=no if test -n "$1" ; then func_emit_wrapper_part2_arg1=$1 fi $ECHO "\ # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_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 \"X\$thisdir\" | \$Xsed -e 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; 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" # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && 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 \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` export $shlibpath_var " fi # fixup the dll searchpath if we need to. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 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\ " } # end: func_emit_wrapper_part2 # 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 in which it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=no if test -n "$1" ; then func_emit_wrapper_arg1=$1 fi # split this up so that func_emit_cwrapperexe_src # can call each part independently. func_emit_wrapper_part1 "${func_emit_wrapper_arg1}" func_emit_wrapper_part2 "${func_emit_wrapper_arg1}" } # func_to_host_path arg # # Convert paths to host format when used with build tools. # Intended for use with "native" mingw (where libtool itself # is running under the msys shell), or in the following cross- # build environments: # $build $host # mingw (msys) mingw [e.g. native] # cygwin mingw # *nix + wine mingw # where wine is equipped with the `winepath' executable. # In the native mingw case, the (msys) shell automatically # converts paths for any non-msys applications it launches, # but that facility isn't available from inside the cwrapper. # Similar accommodations are necessary for $host mingw and # $build cygwin. Calling this function does no harm for other # $host/$build combinations not listed above. # # ARG is the path (on $build) that should be converted to # the proper representation for $host. The result is stored # in $func_to_host_path_result. func_to_host_path () { func_to_host_path_result="$1" if test -n "$1" ; then case $host in *mingw* ) lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' case $build in *mingw* ) # actually, msys # awkward: cmd appends spaces to result lt_sed_strip_trailing_spaces="s/[ ]*\$//" func_to_host_path_tmp1=`( cmd //c echo "$1" |\ $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ $SED -e "$lt_sed_naive_backslashify"` ;; *cygwin* ) func_to_host_path_tmp1=`cygpath -w "$1"` func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ $SED -e "$lt_sed_naive_backslashify"` ;; * ) # 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_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null` if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ $SED -e "$lt_sed_naive_backslashify"` else # Allow warning below. func_to_host_path_result="" fi ;; esac if test -z "$func_to_host_path_result" ; then func_error "Could not determine host path corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_path_result="$1" fi ;; esac fi } # end: func_to_host_path # func_to_host_pathlist arg # # Convert pathlists to host format when used with build tools. # See func_to_host_path(), above. This function supports the # following $build/$host combinations (but does no harm for # combinations not listed here): # $build $host # mingw (msys) mingw [e.g. native] # cygwin mingw # *nix + wine mingw # # 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. # # ARG is a pathlist (on $build) that should be converted to # the proper representation on $host. The result is stored # in $func_to_host_pathlist_result. func_to_host_pathlist () { func_to_host_pathlist_result="$1" if test -n "$1" ; then case $host in *mingw* ) lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # 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_to_host_pathlist_tmp2="$1" # Once set for this call, this variable should not be # reassigned. It is used in tha fallback case. func_to_host_pathlist_tmp1=`echo "$func_to_host_pathlist_tmp2" |\ $SED -e 's|^:*||' -e 's|:*$||'` case $build in *mingw* ) # Actually, msys. # Awkward: cmd appends spaces to result. lt_sed_strip_trailing_spaces="s/[ ]*\$//" func_to_host_pathlist_tmp2=`( cmd //c echo "$func_to_host_pathlist_tmp1" |\ $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ $SED -e "$lt_sed_naive_backslashify"` ;; *cygwin* ) func_to_host_pathlist_tmp2=`cygpath -w -p "$func_to_host_pathlist_tmp1"` func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ $SED -e "$lt_sed_naive_backslashify"` ;; * ) # unfortunately, winepath doesn't convert pathlists func_to_host_pathlist_result="" func_to_host_pathlist_oldIFS=$IFS IFS=: for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do IFS=$func_to_host_pathlist_oldIFS if test -n "$func_to_host_pathlist_f" ; then func_to_host_path "$func_to_host_pathlist_f" if test -n "$func_to_host_path_result" ; then if test -z "$func_to_host_pathlist_result" ; then func_to_host_pathlist_result="$func_to_host_path_result" else func_to_host_pathlist_result="$func_to_host_pathlist_result;$func_to_host_path_result" fi fi fi IFS=: done IFS=$func_to_host_pathlist_oldIFS ;; esac if test -z "$func_to_host_pathlist_result" ; then func_error "Could not determine the host path(s) corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This may break if $1 contains DOS-style drive # specifications. The fix is not to complicate the expression # below, but for the user to provide a working wine installation # with winepath so that path translation in the cross-to-mingw # case works properly. lt_replace_pathsep_nix_to_dos="s|:|;|g" func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\ $SED -e "$lt_replace_pathsep_nix_to_dos"` fi # Now, add the leading and trailing path separators back case "$1" in :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result" ;; esac case "$1" in *: ) func_to_host_pathlist_result="$func_to_host_pathlist_result;" ;; esac ;; esac fi } # end: func_to_host_pathlist # 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 < #include #ifdef _MSC_VER # include # include # include # define setmode _setmode #else # include # include # ifdef __CYGWIN__ # include # define HAVE_SETENV # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif # endif #endif #include #include #include #include #include #include #include #include #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 #ifdef _MSC_VER # define S_IXUSR _S_IEXEC # define stat _stat # ifndef _INTPTR_T_DEFINED # define intptr_t int # endif #endif #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 */ #ifdef __CYGWIN__ # define FOPEN_WB "wb" #endif #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 ((void *) stale); stale = 0; } \ } while (0) #undef LTWRAPPER_DEBUGPRINTF #if defined DEBUGWRAPPER # define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args static void ltwrapper_debugprintf (const char *fmt, ...) { va_list args; va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } #else # define LTWRAPPER_DEBUGPRINTF(args) #endif const char *program_name = NULL; 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_fatal (const char *message, ...); 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_opt_process_env_set (const char *arg); void lt_opt_process_env_prepend (const char *arg); void lt_opt_process_env_append (const char *arg); int lt_split_name_value (const char *arg, char** name, char** value); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); static const char *script_text_part1 = EOF func_emit_wrapper_part1 yes | $SED -e 's/\([\\"]\)/\\\1/g' \ -e 's/^/ "/' -e 's/$/\\n"/' echo ";" cat <"))); for (i = 0; i < newargc; i++) { LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d] : %s\n", i, (newargz[i] ? newargz[i] : ""))); } EOF case $host_os in mingw*) cat <<"EOF" /* execv doesn't actually work on mingw as expected on unix */ rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz); if (rval == -1) { /* failed to start process */ LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, 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 ("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; LTWRAPPER_DEBUGPRINTF (("(check_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!")); 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; LTWRAPPER_DEBUGPRINTF (("(make_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!")); 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]; int tmp_len; char *concat_name; LTWRAPPER_DEBUGPRINTF (("(find_executable) : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!")); 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 = 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 ("getcwd failed"); 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 ("getcwd failed"); 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) { LTWRAPPER_DEBUGPRINTF (("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 { char *errstr = strerror (errno); lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal ("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 (strcmp (str, pat) == 0) *str = '\0'; } return str; } static void lt_error_core (int exit_status, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s: %s: ", program_name, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, "FATAL", message, ap); va_end (ap); } void lt_setenv (const char *name, const char *value) { LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n", (name ? name : ""), (value ? value : ""))); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else int 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) { int orig_value_len = strlen (orig_value); int 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; } int lt_split_name_value (const char *arg, char** name, char** value) { const char *p; int len; if (!arg || !*arg) return 1; p = strchr (arg, (int)'='); if (!p) return 1; *value = xstrdup (++p); len = strlen (arg) - strlen (*value); *name = XMALLOC (char, len); strncpy (*name, arg, len-1); (*name)[len - 1] = '\0'; return 0; } void lt_opt_process_env_set (const char *arg) { char *name = NULL; char *value = NULL; if (lt_split_name_value (arg, &name, &value) != 0) { XFREE (name); XFREE (value); lt_fatal ("bad argument for %s: '%s'", env_set_opt, arg); } lt_setenv (name, value); XFREE (name); XFREE (value); } void lt_opt_process_env_prepend (const char *arg) { char *name = NULL; char *value = NULL; char *new_value = NULL; if (lt_split_name_value (arg, &name, &value) != 0) { XFREE (name); XFREE (value); lt_fatal ("bad argument for %s: '%s'", env_prepend_opt, arg); } new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); XFREE (name); XFREE (value); } void lt_opt_process_env_append (const char *arg) { char *name = NULL; char *value = NULL; char *new_value = NULL; if (lt_split_name_value (arg, &name, &value) != 0) { XFREE (name); XFREE (value); lt_fatal ("bad argument for %s: '%s'", env_append_opt, arg); } new_value = lt_extend_str (getenv (name), value, 1); lt_setenv (name, new_value); XFREE (new_value); XFREE (name); XFREE (value); } void lt_update_exe_path (const char *name, const char *value) { LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n", (name ? name : ""), (value ? 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 #' */ int len = strlen (new_value); while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[len-1] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n", (name ? name : ""), (value ? 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 } # end: func_emit_cwrapperexe_src # func_mode_link arg... func_mode_link () { $opt_debug 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 # which 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 which 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 dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=no 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 "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test "$build_libtool_libs" = yes && 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 dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=yes fi case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then dlfiles="$dlfiles $arg" else dlprefiles="$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 "*) ;; *) deplibs="$deplibs $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir="$arg" prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # moreargs="$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 "$pic_object" = none && test "$non_pic_object" = none; 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 "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then dlfiles="$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 "$prev" = dlprefiles; then # Preload the old-style object. dlprefiles="$dlprefiles $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; 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 "$pic_object" = none ; 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 ;; 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 "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) rpath="$rpath $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) xrpath="$xrpath $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds="$arg" prev= continue ;; weak) weak_libs="$weak_libs $arg" prev= continue ;; xcclinker) linker_flags="$linker_flags $qarg" compiler_flags="$compiler_flags $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) compiler_flags="$compiler_flags $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) linker_flags="$linker_flags $qarg" compiler_flags="$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 ;; -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$arg" = "X-export-symbols"; 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" dir=$func_stripname_result if test -z "$dir"; 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 # 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 "*) ;; *) deplibs="$deplibs -L$dir" lib_search_path="$lib_search_path $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "X$dir" | $Xsed -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) dllsearchpath="$dllsearchpath:$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) dllsearchpath="$dllsearchpath:$testbindir";; esac ;; esac continue ;; -l*) if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*) # 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$arg" = "X-lc" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework deplibs="$deplibs System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test "X$arg" = "X-lc" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test "X$arg" = "X-lc" && continue ;; esac elif test "X$arg" = "X-lc_r"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi deplibs="$deplibs $arg" 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) compiler_flags="$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) compiler_flags="$compiler_flags $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) new_inherited_linker_flags="$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 ;; -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_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) xrpath="$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" arg="$arg $wl$func_quote_for_eval_result" compiler_flags="$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" arg="$arg $wl$func_quote_for_eval_result" compiler_flags="$compiler_flags $wl$func_quote_for_eval_result" linker_flags="$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" ;; # -64, -mips[0-9] enable 64-bit mode on the SGI compiler # -r[0-9][0-9]* specifies the processor on the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler # +DA*, +DD* enable 64-bit mode on the HP compiler # -q* pass through compiler args for the IBM compiler # -m*, -t[45]*, -txscale* pass through architecture-specific # compiler args for GCC # -F/path gives path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC # @file GCC response files -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" func_append compile_command " $arg" func_append finalize_command " $arg" compiler_flags="$compiler_flags $arg" continue ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; *.$objext) # A standard object. objs="$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 "$pic_object" = none && test "$non_pic_object" = none; 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 "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then dlfiles="$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 "$prev" = dlprefiles; then # Preload the old-style object. dlprefiles="$dlprefiles $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; 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 "$pic_object" = none ; 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. deplibs="$deplibs $arg" old_deplibs="$old_deplibs $arg" continue ;; *.la) # A libtool-controlled library. if test "$prev" = dlfiles; then # This library was specified with -dlopen. dlfiles="$dlfiles $arg" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. dlprefiles="$dlprefiles $arg" prev= else deplibs="$deplibs $arg" 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 if test "$module" = yes ; then # [Mandriva] dropping ld option "--no-undefined" which is wrong for plugins linker_flags=`$ECHO "X $linker_flags" | $Xsed -e 's/ --no-undefined//'` compiler_flags=`$ECHO "X $compiler_flags" | $Xsed -e 's/ -Wl,--no-undefined//'` fi test -n "$prev" && \ func_fatal_help "the \`$prevarg' option requires an argument" if test "$export_dynamic" = yes && 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 \"X\${$shlibpath_var}\" \| \$Xsed -e \'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\" func_dirname "$output" "/" "" output_objdir="$func_dirname_result$objdir" # 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_duplicate_deps ; then case "$libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi libs="$libs $deplib" done if test "$linkmode" = lib; 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 "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; esac pre_post_deps="$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=no 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 "$linkmode,$pass" = "lib,link"; 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 "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan"; then libs="$deplibs" deplibs= fi if test "$linkmode" = prog; 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 "$linkmode,$pass" = "lib,dlpreopen"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= case $lib in *.la) func_source "$lib" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do deplib_base=`$ECHO "X$deplib" | $Xsed -e "$basename"` case " $weak_libs " in *" $deplib_base "*) ;; *) deplibs="$deplibs $deplib" ;; esac done done libs="$dlprefiles" fi if test "$pass" = dlopen; then # Collect dlpreopened libraries save_deplibs="$deplibs" deplibs= fi for deplib in $libs; do lib= found=no case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else compiler_flags="$compiler_flags $deplib" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; esac fi fi continue ;; -l*) if test "$linkmode" != lib && test "$linkmode" != prog; then func_warning "\`-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test "$linkmode" = lib; 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 "$search_ext" = ".la"; then found=yes else found=no fi break 2 fi done done if test "$found" != yes; then # deplib doesn't seem to be a libtool library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue else # 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 "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; 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=no func_dirname "$lib" "" "." ladir="$func_dirname_result" lib=$ladir/$old_library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi fi ;; # -l *.ltframework) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test "$pass" = conv && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" newlib_search_path="$newlib_search_path $func_stripname_result" ;; prog) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi if test "$pass" = scan; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" newlib_search_path="$newlib_search_path $func_stripname_result" ;; *) func_warning "\`-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test "$pass" = link; then func_stripname '-R' '' "$deplib" dir=$func_stripname_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) xrpath="$xrpath $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) lib="$deplib" ;; *.$libext) if test "$pass" = conv; 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=no case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=yes fi ;; pass_all) valid_a_lib=yes ;; esac if test "$valid_a_lib" != yes; then $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." else $ECHO $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi ;; esac continue ;; prog) if test "$pass" != link; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test "$pass" = conv; then deplibs="$deplib $deplibs" elif test "$linkmode" = prog; then if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlopen support or we're linking statically, # we need to preload. newdlprefiles="$newdlprefiles $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else newdlfiles="$newdlfiles $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test "$found" = yes || test -f "$lib"; then : else func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" fi # 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 "X$inherited_linker_flags" | $Xsed -e '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 "*) ;; *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test "$linkmode" != prog && test "$linkmode" != lib; }; then test -n "$dlopen" && dlfiles="$dlfiles $dlopen" test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" fi if test "$pass" = conv; 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. convenience="$convenience $ladir/$objdir/$old_library" old_convenience="$old_convenience $ladir/$objdir/$old_library" elif test "$linkmode" != prog && test "$linkmode" != lib; then func_fatal_error "\`$lib' is not a convenience library" fi tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_duplicate_deps ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done continue fi # $pass = conv # Get the name of the library we link against. linklib= for l in $old_library $library_names; do linklib="$l" done 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 "$pass" = dlopen; then if test -z "$libdir"; then func_fatal_error "cannot -dlopen a convenience library: \`$lib'" fi if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; 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. dlprefiles="$dlprefiles $lib $dependency_libs" else newdlfiles="$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 "X$installed" = Xyes; then if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library \`$lib' was moved." dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$libdir" absdir="$libdir" fi test "X$hardcode_automatic" = Xyes && 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 notinst_path="$notinst_path $abs_ladir" else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later notinst_path="$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 "$pass" = dlpreopen; then if test -z "$libdir" && test "$linkmode" = prog; then func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" fi # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then newdlprefiles="$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" && \ dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then newdlprefiles="$newdlprefiles $dir/$dlname" else newdlprefiles="$newdlprefiles $dir/$linklib" fi fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test "$linkmode" = lib; then deplibs="$dir/$old_library $deplibs" elif test "$linkmode,$pass" = "prog,link"; 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 "$linkmode" = prog && test "$pass" != link; then newlib_search_path="$newlib_search_path $ladir" deplibs="$lib $deplibs" linkalldeplibs=no if test "$link_all_deplibs" != no || test -z "$library_names" || test "$build_libtool_libs" = no; then linkalldeplibs=yes fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" newlib_search_path="$newlib_search_path $func_stripname_result" ;; esac # Need to link against all dependency_libs? if test "$linkalldeplibs" = yes; 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_duplicate_deps ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done # for deplib continue fi # $linkmode = prog... if test "$linkmode,$pass" = "prog,link"; then if test -n "$library_names" && { { test "$prefer_static_libs" = no || test "$prefer_static_libs,$installed" = "built,yes"; } || 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:"*) ;; *) temp_rpath="$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 "*) ;; *) compile_rpath="$compile_rpath $absdir" esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" esac ;; esac fi # $linkmode,$pass = prog,link... if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && 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 "$use_static_libs" = built && test "$installed" = yes; then use_static_libs=no fi if test -n "$library_names" && { test "$use_static_libs" = no || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc*) # No point in relinking DLLs because paths are not encoded notinst_deplibs="$notinst_deplibs $lib" need_relink=no ;; *) if test "$installed" = no; then notinst_deplibs="$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 "$shouldnotlink" = yes && test "$pass" = link; then $ECHO if test "$linkmode" = prog; 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 "$linkmode" = lib && test "$hardcode_into_libs" = yes; 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 "*) ;; *) compile_rpath="$compile_rpath $absdir" esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$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*) 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 "$linkmode" = prog || test "$mode" != relink; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test "$hardcode_direct" = no; 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 can not # 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 "$hardcode_minus_L" = no; then case $host in *-*-sunos*) add_shlibpath="$dir" ;; esac add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = no; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$dir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) add_dir="$add_dir -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; esac fi if test "$linkmode" = prog; 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 "$hardcode_direct" != yes && test "$hardcode_minus_L" != yes && test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; esac fi fi fi if test "$linkmode" = prog || test "$mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$libdir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$libdir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; esac add="-l$name" elif test "$hardcode_automatic" = yes; 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 [\\/]*) add_dir="$add_dir -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" fi if test "$linkmode" = prog; 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 "$linkmode" = prog; 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 "$hardcode_direct" != unsupported; 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 "$build_libtool_libs" = yes; then # Not a shared library if test "$deplibs_check_method" != pass_all; 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 can not 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 "$module" = yes; 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 "$build_old_libs" = no; 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 "$linkmode" = lib; then if test -n "$dependency_libs" && { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || test "$link_static" = yes; }; 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 "*) ;; *) xrpath="$xrpath $temp_xrpath";; esac;; *) temp_deplibs="$temp_deplibs $libdir";; esac done dependency_libs="$temp_deplibs" fi newlib_search_path="$newlib_search_path $absdir" # Link against this library test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" if $opt_duplicate_deps ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do case $deplib in -L*) path="$deplib" ;; *.la) 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 compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" linker_flags="$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 "$pass" = link; then if test "$linkmode" = "prog"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs="$newdependency_libs" if test "$pass" = dlpreopen; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test "$pass" != dlopen; then if test "$pass" != conv; then # 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 "*) ;; *) lib_search_path="$lib_search_path $dir" ;; esac done newlib_search_path= fi if test "$linkmode,$pass" != "prog,link"; then vars="deplibs" else vars="compile_deplibs finalize_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 "*) ;; *) tmp_libs="$tmp_libs $deplib" ;; esac ;; *) tmp_libs="$tmp_libs $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # 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 tmp_libs="$tmp_libs $i" fi done dependency_libs=$tmp_libs done # for pass if test "$linkmode" = prog; then dlfiles="$newdlfiles" fi if test "$linkmode" = prog || test "$linkmode" = lib; then dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; 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" objs="$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 "$module" = no && \ func_fatal_help "libtool library \`$output' must begin with \`lib'" if test "$need_lib_prefix" != no; 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 "$deplibs_check_method" != pass_all; 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!" libobjs="$libobjs $objs" fi fi test "$dlself" != no && \ func_warning "\`-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test "$#" -gt 1 && \ func_warning "ignoring multiple \`-rpath's for a libtool library" install_libdir="$1" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; 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 # which has an extra 1 added just for fun # case $version_type in darwin|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_revision" ;; freebsd-aout|freebsd-elf|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 ;; 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" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current" ;; irix | nonstopux) if test "X$lt_irix_increment" = "Xno"; 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 "$loop" -ne 0; 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) 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 "$loop" -ne 0; 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. verstring="$verstring:${current}.0" ;; qnx) major=".$current" versuffix=".$current" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. 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 "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then func_warning "undefined symbols not allowed in $host shared libraries" build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi func_generate_dlsyms "$libname" "$libname" "yes" libobjs="$libobjs $symfileobj" test "X$libobjs" = "X " && libobjs= if test "$mode" != relink; 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 "X$precious_files_regex" != "X"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi removelist="$removelist $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then oldlibs="$oldlibs $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "X$lib_search_path " | $Xsed -e "s% $path % %g"` # deplibs=`$ECHO "X$deplibs " | $Xsed -e "s% -L$path % %g"` # dependency_libs=`$ECHO "X$dependency_libs " | $Xsed -e "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 temp_xrpath="$temp_xrpath -R$libdir" case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" ;; esac done if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; 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 "*) ;; *) dlfiles="$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 "*) ;; *) dlprefiles="$dlprefiles $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework deplibs="$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 "$build_libtool_need_lc" = "yes"; then deplibs="$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 </dev/null` 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 "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then newdeplibs="$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. newdeplibs="$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 "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) newdeplibs="$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 \"X$potent_lib\"" 2>/dev/null | $Xsed -e 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then newdeplibs="$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. newdeplibs="$newdeplibs $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" tmp_deplibs=`$ECHO "X $deplibs" | $Xsed \ -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then for i in $predeps $postdeps ; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO "X $tmp_deplibs" | $Xsed -e "s,$i,,"` done fi if $ECHO "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' | $GREP . >/dev/null; then $ECHO if test "X$deplibs_check_method" = "Xnone"; 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 fi ;; 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 "X $newdeplibs" | $Xsed -e 's/ -lc / System.ltframework /'` ;; esac if test "$droppeddeps" = yes; then if test "$module" = yes; 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 "$build_old_libs" = no; 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 "$allow_undefined" = no; 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 "$build_old_libs" = no; 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 "X $newdeplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO "X $deplibs" | $Xsed -e '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 "*) new_libs="$new_libs -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$new_libs $deplib" ;; esac ;; *) new_libs="$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 "$build_libtool_libs" = yes; then if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$mode" != relink && rpath="$compile_rpath$rpath" for libdir in $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"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" dep_rpath="$dep_rpath $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath="$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" if test -n "$hardcode_libdir_flag_spec_ld"; then eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" else eval dep_rpath=\"$hardcode_libdir_flag_spec\" fi fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do rpath="$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 "$mode" != relink && 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 linknames="$linknames $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "X$libobjs" | $SP2NL | $Xsed -e "$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" delfiles="$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 if test "x`$SED 1q $export_symbols`" != xEXPORTS; then # 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 fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || 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 cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" func_len " $cmd" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then func_show_eval "$cmd" 'exit $?' 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 "X$skipped_export" != "X:"; 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 "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' fi if test "X$skipped_export" != "X:" && 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 delfiles="$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= inst_prefix_arg= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) if test -n "$inst_prefix_dir" && (echo "$test_deplib" | grep -- "$inst_prefix_dir" >/dev/null); then inst_prefix_arg="$inst_prefix_arg $test_deplib" else tmp_deplibs="$tmp_deplibs $test_deplib" fi ;; esac done deplibs="$tmp_deplibs" if test -n "$inst_prefix_arg"; then deplibs="$inst_prefix_arg $deplibs" fi if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test "$compiler_needs_object" = yes && 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" generated="$generated $gentop" func_extract_archives $gentop $convenience libobjs="$libobjs $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" linker_flags="$linker_flags $flag" fi # Make a backup of the uninstalled library when relinking if test "$mode" = relink; 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 "$module" = yes && 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 "X$skipped_export" != "X:" && 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 output_la=`$ECHO "X$output" | $Xsed -e "$basename"` # 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 "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then output=${output_objdir}/${output_la}.lnkscript func_verbose "creating GNU ld script: $output" $ECHO 'INPUT (' > $output for obj in $save_libobjs do $ECHO "$obj" >> $output done $ECHO ')' >> $output delfiles="$delfiles $output" elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then output=${output_objdir}/${output_la}.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test "$compiler_needs_object" = yes; then firstobj="$1 " shift fi for obj do $ECHO "$obj" >> $output done delfiles="$delfiles $output" output=$firstobj\"$file_list_spec$output\" 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 "X$objlist" = X || 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 "$k" -eq 1 ; then # The first file doesn't have a previous command to add. eval concat_cmds=\"$reload_cmds $objlist $last_robj\" else # All subsequent reloadable object files will link in # the last one created. eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$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~ eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" if test -n "$last_robj"; then eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" fi delfiles="$delfiles $output" else output= fi if ${skipped_export-false}; then 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 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_silent || { 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 "$mode" = relink; 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 if ${skipped_export-false}; then 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 "X$include_expsyms" | $Xsed | $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 delfiles="$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 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 "$module" = yes && 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" generated="$generated $gentop" func_extract_archives $gentop $dlprefiles libobjs="$libobjs $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $opt_silent || { 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 "$mode" = relink; 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 "$mode" = relink; 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 "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; 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= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec and hope we can get by with # turning comma into space.. wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" reload_conv_objs=$reload_objs\ `$ECHO "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'` else gentop="$output_objdir/${obj}x" generated="$generated $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # Create the old-style object. reload_objs="$objs$old_deplibs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test 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 if test "$build_libtool_libs" != yes; then 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 fi if test -n "$pic_flag" || test "$pic_mode" != default; 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" test "$preload" = yes \ && test "$dlopen_support" = unknown \ && test "$dlopen_self" = unknown \ && test "$dlopen_self_static" = unknown && \ 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 "X $compile_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e '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 "$tagname" = CXX ; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) compile_command="$compile_command ${wl}-bind_at_load" finalize_command="$finalize_command ${wl}-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e '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 "*) new_libs="$new_libs -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$new_libs $deplib" ;; esac ;; *) new_libs="$new_libs $deplib" ;; esac done compile_deplibs="$new_libs" compile_command="$compile_command $compile_deplibs" finalize_command="$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 "*) ;; *) finalize_rpath="$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"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath="$rpath $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath="$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;; *) dllsearchpath="$dllsearchpath:$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) dllsearchpath="$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"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath="$rpath $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) finalize_perm_rpath="$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 "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$ECHO "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` finalize_command=`$ECHO "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" "no" # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=yes case $host in *cygwin* | *mingw* ) if test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; *cegcc) # Disable wrappers for cegcc, we are cross compiling anyway. wrappers_required=no ;; *) if test "$need_relink" = no || test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; esac if test "$wrappers_required" = no; then # Replace the output file specification. compile_command=`$ECHO "X$compile_command" | $Xsed -e '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=$?' # 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 fi 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 rpath="$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 rpath="$rpath$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$no_install" = yes; 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 "X$link_command" | $Xsed -e '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 $?' exit $EXIT_SUCCESS fi if test "$hardcode_action" = relink; then # 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" else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$ECHO "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$ECHO "X$link_command" | $Xsed -e '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 $?' # 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 "X$relink_command" | $Xsed -e "$sed_quote_subst"` fi # Quote $ECHO for shipping. if test "X$ECHO" = "X$SHELL $progpath --fallback-echo"; then case $progpath in [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; esac qecho=`$ECHO "X$qecho" | $Xsed -e "$sed_quote_subst"` else qecho=`$ECHO "X$ECHO" | $Xsed -e "$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 if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save $symfileobj" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$old_deplibs $non_pic_objects" if test "$preload" = yes && test -f "$symfileobj"; then oldobjs="$oldobjs $symfileobj" fi fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $addlibs oldobjs="$oldobjs $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; 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" generated="$generated $gentop" func_extract_archives $gentop $dlprefiles oldobjs="$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" generated="$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" oldobjs="$oldobjs $gentop/$newobj" ;; *) oldobjs="$oldobjs $obj" ;; esac done fi 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 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 "X$oldobjs" = "X" ; 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 "$build_old_libs" = yes && 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 "X$relink_command" | $Xsed -e "$sed_quote_subst"` if test "$hardcode_automatic" = yes ; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test "$installed" = yes; 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" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" newdependency_libs="$newdependency_libs $libdir/$name" ;; *) newdependency_libs="$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" newdlfiles="$newdlfiles $libdir/$name" ;; *) newdlfiles="$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" newdlprefiles="$newdlprefiles $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 newdlfiles="$newdlfiles $abs" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac newdlprefiles="$newdlprefiles $abs" done dlprefiles="$newdlprefiles" fi $RM $output # place dlname in correct position for cygwin tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $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 can not 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 "$installed" = no && test "$need_relink" = yes; 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 } { test "$mode" = link || test "$mode" = relink; } && func_mode_link ${1+"$@"} # func_mode_uninstall arg... func_mode_uninstall () { $opt_debug RM="$nonopt" files= rmforce= 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) RM="$RM $arg"; rmforce=yes ;; -*) RM="$RM $arg" ;; *) files="$files $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= origobjdir="$objdir" for file in $files; do func_dirname "$file" "" "." dir="$func_dirname_result" if test "X$dir" = X.; then objdir="$origobjdir" else objdir="$dir/$origobjdir" fi func_basename "$file" name="$func_basename_result" test "$mode" = uninstall && objdir="$dir" # Remember objdir for removal later, being careful to avoid duplicates if test "$mode" = clean; then case " $rmdirs " in *" $objdir "*) ;; *) rmdirs="$rmdirs $objdir" ;; 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 test "$rmforce" = yes; 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 rmfiles="$rmfiles $objdir/$n" done test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" case "$mode" in clean) case " $library_names " in # " " in the beginning catches empty $dlname *" $dlname "*) ;; *) rmfiles="$rmfiles $objdir/$dlname" ;; esac test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || 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 "$pic_object" != none; then rmfiles="$rmfiles $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test "$non_pic_object" != none; then rmfiles="$rmfiles $dir/$non_pic_object" fi fi ;; *) if test "$mode" = clean ; 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 rmfiles="$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 rmfiles="$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 rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then rmfiles="$rmfiles $objdir/lt-$name" fi if test "X$noexename" != "X$name" ; then rmfiles="$rmfiles $objdir/lt-${noexename}.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done objdir="$origobjdir" # 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 } { test "$mode" = uninstall || test "$mode" = clean; } && func_mode_uninstall ${1+"$@"} test -z "$mode" && { help="$generic_help" func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode \`$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 # in which 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: # vi:sw=2 ode-0.11.1/ou/0000777000076400007640000000000011206343456010005 500000000000000ode-0.11.1/ou/build/0000777000076400007640000000000011206343361011077 500000000000000ode-0.11.1/ou/build/make/0000777000076400007640000000000011206343361012014 500000000000000ode-0.11.1/ou/build/make/makefile.os0000644000076400007640000000172510777204760014070 00000000000000ifeq ($(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 ode-0.11.1/ou/build/make/makefile0000644000076400007640000000707310776472337013460 00000000000000PRODUCTNAME = 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) ode-0.11.1/ou/build/vs6/0000777000076400007640000000000011206343361011615 500000000000000ode-0.11.1/ou/build/vs6/ou.dsw0000644000076400007640000000145210776472337012716 00000000000000Microsoft 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> {{{ }}} ############################################################################### ode-0.11.1/ou/build/vs6/ou.dsp0000644000076400007640000001063310776472337012710 00000000000000# 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 ode-0.11.1/ou/build/vs2005/0000777000076400007640000000000011206343361012036 500000000000000ode-0.11.1/ou/build/vs2005/ou.vcproj0000644000076400007640000002516410776472337013653 00000000000000 ode-0.11.1/ou/build/vs2005/ou.sln0000644000076400007640000000414010776472337013133 00000000000000 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 ode-0.11.1/ou/LICENSE-ZLIB.TXT0000644000076400007640000000163310776643320012151 00000000000000The 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. ode-0.11.1/ou/CHANGELOG.TXT0000644000076400007640000000171111030751225011601 00000000000000======================= Legend ======================= [+] A feature added [-] A bug fixed [*] A change [!] An important note ======================= 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 ode-0.11.1/ou/Makefile.in0000644000076400007640000004633511206343422011772 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 = . DIST_COMMON = $(am__configure_deps) $(srcdir)/../config.guess \ $(srcdir)/../config.sub $(srcdir)/../install-sh \ $(srcdir)/../ltmain.sh $(srcdir)/../missing \ $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ $(top_srcdir)/configure 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) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-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 uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ { test ! -d $(distdir) \ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr $(distdir); }; } DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ 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@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ OU_NAMESPACE = @OU_NAMESPACE@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ 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_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@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ 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: @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \ cd $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile .PRECIOUS: 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) cd $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) 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. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; 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; \ (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" $(RECURSIVE_CLEAN_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ 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 || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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 \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ distdir) \ || exit 1; \ fi; \ done -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -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__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-lzma: distdir tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma $(am__remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__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) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ unlzma -c $(distdir).tar.lzma | $(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) gunzip -c $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && cd $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(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 $(am__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: @cd $(distuninstallcheck_dir) \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-exec-am: install-html: install-html-recursive install-info: install-info-recursive install-man: install-pdf: install-pdf-recursive install-ps: install-ps-recursive 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: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am am--refresh check check-am clean clean-generic \ clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \ dist-gzip dist-lzma 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-recursive uninstall uninstall-am # 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: ode-0.11.1/ou/INSTALL.TXT0000644000076400007640000000141710776472337011447 00000000000000Currently 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. ode-0.11.1/ou/aclocal.m40000644000076400007640000114630311206343420011560 00000000000000# generated automatically by aclocal 1.10.2 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008 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_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.63],, [m4_warning([this file was generated for autoconf 2.63. 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, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008 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) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) # serial 56 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.58])dnl We use AC_INCLUDES_DEFAULT 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 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_CC_BASENAME(CC) # ------------------- # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. m4_defun([_LT_CC_BASENAME], [for cc_temp in $1""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ]) # _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 _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_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options which 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 _LT_PROG_ECHO_BACKSLASH 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 "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # 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. 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' # 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_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 "X$][$1" | $Xsed -e "$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: # # ='`$ECHO "X$" | $Xsed -e "$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' # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) 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 "X\\\\\$\$var"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Fix-up fallback echo if it was mangled by the above quoting rules. case \$lt_ECHO in *'\\\[$]0 --fallback-echo"')dnl " lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\` ;; esac _LT_OUTPUT_LIBTOOL_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]) cat >"$CONFIG_LT" <<_LTEOF #! $SHELL # Generated by $as_me. # Run this file to recreate a libtool stub with the current configuration. lt_cl_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 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 ." 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) 2008 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. if test "$no_create" != yes; then lt_cl_success=: test "$silent" = yes && 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) fi ])# 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 which 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 # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $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. # _LT_COPYING _LT_LIBTOOL_TAGS # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _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 "X${COLLECT_NAMES+set}" != Xset; 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 '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) _LT_PROG_XSI_SHELLFNS sed -n '/^# Generated shell functions inserted here/,$p' "$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' TIMESTAMP='$TIMESTAMP' 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)], [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 # _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([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)]) 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], []) # _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 test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; 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" ]) 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 "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; 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" != ":"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES # -------------------------- # 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 _LT_TAGVAR(whole_archive_flag_spec, $1)='' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=echo _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 "$lt_cv_apple_cc_single_mod" != "yes"; 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 # ----------------------- # 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. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl AC_LINK_IFELSE(AC_LANG_PROGRAM,[ lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/ p } }' 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 "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [ifdef([AC_DIVERSION_NOTICE], [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], [AC_DIVERT_PUSH(NOTICE)]) $1 AC_DIVERT_POP ])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Add some code to the start of the generated configure script which # will find an echo command which doesn't interpret backslashes. m4_defun([_LT_PROG_ECHO_BACKSLASH], [_LT_SHELL_INIT([ # Check that we are running under the correct shell. SHELL=${CONFIG_SHELL-/bin/sh} case X$lt_ECHO in X*--fallback-echo) # Remove one level of quotation (which was required for Make). ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` ;; esac ECHO=${lt_ECHO-echo} if test "X[$]1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X[$]1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then # Yippee, $ECHO works! : else # Restart under the correct shell. exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} fi if test "X[$]1" = X--fallback-echo; then # used as fallback echo shift cat <<_LT_EOF [$]* _LT_EOF exit 0 fi # 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 if test -z "$lt_ECHO"; then if test "X${echo_test_string+set}" != Xset; then # find a string as large as possible, as long as the shell can cope with it for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... if { echo_test_string=`eval $cmd`; } 2>/dev/null && { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null then break fi done fi if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then : else # The Solaris, AIX, and Digital Unix default echo programs unquote # backslashes. This makes it impossible to quote backslashes using # echo "$something" | sed 's/\\/\\\\/g' # # So, first we look for a working echo in the user's PATH. lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for dir in $PATH /usr/ucb; do IFS="$lt_save_ifs" if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then ECHO="$dir/echo" break fi done IFS="$lt_save_ifs" if test "X$ECHO" = Xecho; then # We didn't find a better echo, so look for alternatives. if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # This shell has a builtin print -r that does the trick. ECHO='print -r' elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && test "X$CONFIG_SHELL" != X/bin/ksh; then # If we have ksh, try running configure again with it. ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} export ORIGINAL_CONFIG_SHELL CONFIG_SHELL=/bin/ksh export CONFIG_SHELL exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} else # Try using printf. ECHO='printf %s\n' if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # Cool, printf works : elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL export CONFIG_SHELL SHELL="$CONFIG_SHELL" export SHELL ECHO="$CONFIG_SHELL [$]0 --fallback-echo" elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then ECHO="$CONFIG_SHELL [$]0 --fallback-echo" else # maybe with a smaller string... prev=: for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null then break fi prev="$cmd" done if test "$prev" != 'sed 50q "[$]0"'; then echo_test_string=`eval $prev` export echo_test_string exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} else # Oops. We lost completely, so just stick with echo. ECHO=echo fi fi fi fi fi fi # Copy echo and quote the copy suitably for passing to libtool from # the Makefile, instead of quoting the original, which is used later. lt_ECHO=$ECHO if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" fi AC_SUBST(lt_ECHO) ]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that does not interpret backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _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 "x$enable_libtool_lock" != xno && 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 which ABI we are using. 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 which ABI we are using. echo '[#]line __oline__ "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test "$lt_cv_prog_gnu_ld" = yes; 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* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. 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*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|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" ;; ppc*-*linux*|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 x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; sparc*-*solaris*) # Find out which ABI we are using. 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*) LD="${LD-ld} -m elf64_sparc" ;; *) 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_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [AC_CHECK_TOOL(AR, ar, false) test -z "$AR" && AR=ar test -z "$AR_FLAGS" && AR_FLAGS=cru _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1]) 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 openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" fi _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_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" # 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:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:__oline__: \$? = $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 "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/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 x"[$]$2" = xyes; 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 "X$_lt_linker_boilerplate" | $Xsed -e '/^$/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 x"[$]$2" = xyes; 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; ;; 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; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # 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 ;; 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"; 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"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ = "XX$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 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 "$cross_compiling" = yes; 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 __oline__ "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #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 void fnord() { int i=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; /* 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 "x$enable_dlopen" != xyes; 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 ]) ;; *) 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 "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && 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 "x$lt_cv_dlopen_self" = xyes; 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:__oline__: $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:__oline__: \$? = $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 "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/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 "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; 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 "$hard_links" = no; 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 in which 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 "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then # We can hardcode non-existent directories. if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && # 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 "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; 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 "$_LT_TAGVAR(hardcode_action, $1)" = relink || test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; 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_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 AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then # 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 -e 's/;/ /g'` else lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # 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` 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" else 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; } }'` sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` 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 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 need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; 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 # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.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}' else # 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' fi 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=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $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 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,$host_os in yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) 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="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. 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 ;; 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 ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # 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 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 ;; freebsd1*) dynamic_linker=no ;; 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[[123]]*) 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} $libname${shared_ext}' 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 ;; 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 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 "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; 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' ;; interix[[3-9]]*) 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' 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 "$lt_cv_prog_gnu_ld" = yes; then version_type=linux 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 ;; # This must be Linux ELF. linux* | k*bsd*-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' 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 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], [shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir # 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 # find out which ABI we are using libsuff= case "$host_cpu" in x86_64*|s390x*|powerpc64*) echo '[#]line __oline__ "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *64-bit*) libsuff=64 ;; esac fi rm -rf conftest* ;; esac sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff}" # Append ld.so.conf contents 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;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $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' ;; 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 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*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac 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 if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[[89]] | openbsd2.[[89]].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; 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 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 "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux 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 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=freebsd-elf 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 "$with_gnu_ld" = yes; 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 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 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 "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi _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([], [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], [2], [Run-time system search path for libraries]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program which 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 which 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 AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test "$GCC" = yes; 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 "$with_gnu_ld" = yes; 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 &1 /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 lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' 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 ;; gnu*) 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]) 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 Linux ELF. linux* | k*bsd*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd*) 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*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; 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 ;; esac ]) 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_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 case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) 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 "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :) 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:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:__oline__: $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:__oline__: 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_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cygwin* | *-*-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 "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' _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([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 "$host_cpu" = ia64; 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 # 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 -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$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 -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/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 # and D for any global 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};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print 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 # 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 #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. */ const struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$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_save_LIBS="$LIBS" lt_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_save_LIBS" CFLAGS="$lt_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 "$pipe_works" = yes; 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 _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_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_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)= AC_MSG_CHECKING([for $compiler option to produce PIC]) m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; 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 "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; 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']) ;; 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)= ;; 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 "$host_cpu" = ia64; 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 ;; 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 "$host_cpu" != ia64; 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) 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*) # IBM XL 8.0 on PPC _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*) ;; *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*) # 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 "$GCC" = yes; 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 "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; 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']) ;; 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' ;; 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 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 "$host_cpu" = ia64; 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 ;; 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']) ;; 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) 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' ;; pgcc* | pgf77* | pgf90* | pgf95*) # 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*) # IBM XL C 8.0/Fortran 10.1 on PPC _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)='-Wl,' ;; *Sun\ F*) # 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)='' ;; 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*) _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 which 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_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # 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]) # # 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_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' 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 AIX nm, but means don't demangle with GNU 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")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' ;; linux* | k*bsd*-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 _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] ], [ 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_flag_spec_ld, $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 "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes if test "$with_gnu_ld" = yes; 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 2>&1` in *\ [[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 "$host_cpu" != ia64; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.9.1, 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 modify your PATH *** so that a non-GNU linker is found, and then restart. _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 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(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/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' 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 (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; 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 ;; 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) tmp_diet=no if test "$host_os" = linux-dietlibc; 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 "$tmp_diet" = no then tmp_addflag= 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; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95*) # 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; $ECHO \"$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' ;; xl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; 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; $ECHO \"$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 "x$supports_anon_versioning" = xyes; 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 xlf*) # 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)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; 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 $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd*) 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 $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' 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 $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 ;; 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 can not *** 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 $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 if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; 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 "$GCC" = yes && 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 "$host_cpu" = ia64; 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 AIX nm, but means don't demangle with GNU 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")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | 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 # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; 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,' if test "$GCC" = yes; 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 "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi _LT_TAGVAR(link_all_deplibs, $1)=no else # not using gcc if test "$host_cpu" = ia64; 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 "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi 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_use_runtimelinking" = yes; 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 _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 "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; 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 _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' # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' 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. _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 `$ECHO "X$deplibs" | $Xsed -e '\''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(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; 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 ;; freebsd1*) _LT_TAGVAR(ld_shlibs, $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 -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 "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $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 $output_objdir/$soname = $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 "$GCC" = yes -a "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${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 "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $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 "$GCC" = yes -a "$with_gnu_ld" = no; 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 -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${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' ;; *) _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 "$with_gnu_ld" = no; 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 "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${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. save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" AC_LINK_IFELSE(int foo(void) {}, _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' ) LDFLAGS="$save_LDFLAGS" else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -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" && $ECHO "X-set_version $verstring" | $Xsed` -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 ;; netbsd*) 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*) 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__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; 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 case $host_os in openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ;; *) _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' ;; esac 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 _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; 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" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${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" && $ECHO "X-set_version $verstring" | $Xsed` -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 "$GCC" = yes; 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}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${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" && $ECHO "X-set_version $verstring" | $Xsed` -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 "X-set_version $verstring" | $Xsed` -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 "$GCC" = yes; then wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${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 ${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 "$GCC" = yes; 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 "x$host_vendor" = xsequent; 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 "$GCC" = yes; 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 can NOT 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 "$GCC" = yes; 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 x$host_vendor = xsni; 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 "$_LT_TAGVAR(ld_shlibs, $1)" = no && 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 "$enable_shared" = yes && test "$GCC" = yes; 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_MSG_CHECKING([whether -lc should be explicitly linked in]) $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_TAGVAR(archive_cmds_need_lc, $1)=no else _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* AC_MSG_RESULT([$_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_flag_spec_ld], [1], [[If ld is used when linking, 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([], [fix_srcfile_path], [1], [Fix the shell variable $srcfile for the compiler]) _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([], [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 which 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 "$can_build_shared" = "no" && 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 "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no 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 "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC="$lt_save_CC" ])# _LT_LANG_C_CONFIG # _LT_PROG_CXX # ------------ # Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++ # compiler, we have our own version here. m4_defun([_LT_PROG_CXX], [ pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes]) AC_PROG_CXX if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi popdef([AC_MSG_ERROR]) ])# _LT_PROG_CXX dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([_LT_PROG_CXX], []) # _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], [AC_REQUIRE([_LT_PROG_CXX])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl 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_flag_spec_ld, $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(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 "$_lt_caught_CXX_error" != yes; 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_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++"} 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 "$GXX" = yes; 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 "$GXX" = yes; 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 "$with_gnu_ld" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -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 "\-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 "$host_cpu" = ia64; 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 # need to do runtime linking. 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 ;; 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,' if test "$GXX" = yes; 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 "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; 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 "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi 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_use_runtimelinking" = yes; 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 _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 "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; 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 _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' # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared # libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach 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*) # _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(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 (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; 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 ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; 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 ;; freebsd[[12]]*) # 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 ;; gnu*) ;; 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 $output_objdir/$soname = $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; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $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 $with_gnu_ld = no; 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; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; 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 -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${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" && $ECHO "X-set_version $verstring" | $Xsed` -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 "$GXX" = yes; then if test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -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) 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; $ECHO "X$list" | $Xsed' _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 | $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 | $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 | $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 | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 will 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; $ECHO \"$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=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; xl*) # 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 "x$supports_anon_versioning" = xyes; 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; $ECHO \"$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='echo' # 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 ;; openbsd2*) # C++ shared libraries are fairly broken _LT_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) 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__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; 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=echo 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" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -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" && $ECHO "X-set_version $verstring" | $Xsed` -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 "X-set_version $verstring" | $Xsed` -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=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; 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" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${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 "\-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*) # 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='echo' # 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 "$GXX" = yes && test "$with_gnu_ld" = no; 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 -nostdlib $LDFLAGS $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 -nostdlib ${wl}-M $wl$lib.exp -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 "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $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 -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 "\-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 can NOT 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(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 "$_LT_TAGVAR(ld_shlibs, $1)" = no && 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 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 "$_lt_caught_CXX_error" != yes AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _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 # 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 ]) 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 $p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue else prev= fi if test "$pre_test_object_deps_done" = no; then case $p 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 ;; *.$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 "$pre_test_object_deps_done" = no; 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 # 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)= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; 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_PROG_F77 # ------------ # Since AC_PROG_F77 is broken, in that it returns the empty string # if there is no fortran compiler, we have our own version here. m4_defun([_LT_PROG_F77], [ pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes]) AC_PROG_F77 if test -z "$F77" || test "X$F77" = "Xno"; then _lt_disable_F77=yes fi popdef([AC_MSG_ERROR]) ])# _LT_PROG_F77 dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([_LT_PROG_F77], []) # _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_REQUIRE([_LT_PROG_F77])dnl AC_LANG_PUSH(Fortran 77) _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_flag_spec_ld, $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(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 "$_lt_disable_F77" != yes; 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 CC=${F77-"f77"} 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 "$can_build_shared" = "no" && 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 "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no 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 "$enable_shared" = yes || 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" fi # test "$_lt_disable_F77" != yes AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_PROG_FC # ----------- # Since AC_PROG_FC is broken, in that it returns the empty string # if there is no fortran compiler, we have our own version here. m4_defun([_LT_PROG_FC], [ pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes]) AC_PROG_FC if test -z "$FC" || test "X$FC" = "Xno"; then _lt_disable_FC=yes fi popdef([AC_MSG_ERROR]) ])# _LT_PROG_FC dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([_LT_PROG_FC], []) # _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_REQUIRE([_LT_PROG_FC])dnl AC_LANG_PUSH(Fortran) _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_flag_spec_ld, $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(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 "$_lt_disable_FC" != yes; 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 CC=${FC-"f95"} 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 "$can_build_shared" = "no" && 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 "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no 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 "$enable_shared" = yes || 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" fi # test "$_lt_disable_FC" != yes 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_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} 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 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" ])# _LT_LANG_GCJ_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_GCC=$GCC GCC= CC=${RC-"windres"} 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" ])# _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 "x${GCJFLAGS+set}" = xset || 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_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_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 $lt_ac_count -gt 10 && 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], [AC_MSG_CHECKING([whether the shell understands some XSI constructs]) # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes AC_MSG_RESULT([$xsi_shell]) _LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) AC_MSG_CHECKING([whether the shell understands "+="]) lt_shell_append=no ( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes AC_MSG_RESULT([$lt_shell_append]) _LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) 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_PROG_XSI_SHELLFNS # --------------------- # Bourne and XSI compatible variants of some useful shell functions. m4_defun([_LT_PROG_XSI_SHELLFNS], [case $xsi_shell in yes) cat << \_LT_EOF >> "$cfgfile" # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac } # func_basename file func_basename () { func_basename_result="${1##*/}" } # 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" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}" } # func_stripname 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). func_stripname () { # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"} } # func_opt_split func_opt_split () { func_opt_split_opt=${1%%=*} func_opt_split_arg=${1#*=} } # func_lo2o object func_lo2o () { case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac } # func_xform libobj-or-source func_xform () { func_xform_result=${1%.*}.lo } # func_arith arithmetic-term... func_arith () { func_arith_result=$(( $[*] )) } # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=${#1} } _LT_EOF ;; *) # Bourne compatible functions. cat << \_LT_EOF >> "$cfgfile" # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_basename file func_basename () { func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` } dnl func_dirname_and_basename dnl A portable version of this function is already defined in general.m4sh dnl so there is no need for it here. # func_stripname 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). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "X${3}" \ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "X${3}" \ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; esac } # sed scripts: my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q' my_sed_long_arg='1s/^-[[^=]]*=//' # func_opt_split func_opt_split () { func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` } # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` } # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'` } # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "$[@]"` } # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len` } _LT_EOF esac case $lt_shell_append in yes) cat << \_LT_EOF >> "$cfgfile" # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "$[1]+=\$[2]" } _LT_EOF ;; *) cat << \_LT_EOF >> "$cfgfile" # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "$[1]=\$$[1]\$[2]" } _LT_EOF ;; esac ]) # Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004, 2005, 2007, 2008 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 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_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], [0], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [0], [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_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], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [pic_mode="$withval"], [pic_mode=default]) test -z "$pic_mode" && 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 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 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. # Generated from ltversion.in. # serial 3012 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.2.6]) m4_define([LT_PACKAGE_REVISION], [1.3012]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.2.6' macro_revision='1.3012' _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 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 4 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_RC], [AC_DEFUN([AC_LIBTOOL_RC])]) 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])]) # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 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.10' 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.10.2], [], [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.10.2])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, 2003, 2005 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], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006 # 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. # serial 8 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$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 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, 2000, 2001, 2002, 2003, 2004, 2005, 2006 # 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. # serial 9 # 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", "GCJ", or "OBJC". # 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 ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" 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'. 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 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 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in 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 ;; none) break ;; esac # 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. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} 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 sub/conftest.${OBJEXT-o} 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, [ --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 # 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. #serial 4 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [# Autoconf 2.62 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"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //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' -e 's/\$U/'"$U"'/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, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2008 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. # serial 13 # 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. # 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.60])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], [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], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, [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) AM_PROG_INSTALL_SH AM_PROG_INSTALL_STRIP AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. 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)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES(OBJC)], [define([AC_PROG_OBJC], defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ]) ]) # 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, 2003, 2005 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 install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 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. # serial 2 # 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, 2002, 2003, 2005 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. # serial 3 # 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 done .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 # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi 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, 1999, 2000, 2001, 2003, 2004, 2005 # 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. # serial 5 # 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 supports --run. # If it does, 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 test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # Copyright (C) 2003, 2004, 2005, 2006 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_MKDIR_P # --------------- # Check for `mkdir -p'. AC_DEFUN([AM_PROG_MKDIR_P], [AC_PREREQ([2.60])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, dnl while keeping a definition of mkdir_p for backward compatibility. dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of dnl Makefile.ins that do not define MKDIR_P, so we do our own dnl adjustment using top_builddir (which is defined more often than dnl MKDIR_P). AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl case $mkdir_p in [[\\/$]]* | ?:[[\\/]]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2008 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. # serial 4 # _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])]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # 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. # serial 4 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # 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 ( 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 rm -f conftest.file 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 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)]) # Copyright (C) 2001, 2003, 2005 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 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]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005 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. # serial 2 # _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. AM_MISSING_PROG([AMTAR], [tar]) m4_if([$1], [v7], [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. 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 /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 ode-0.11.1/ou/configure.ac0000644000076400007640000000563711036136204012212 00000000000000# -*- 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_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_FUNC_MALLOC AC_FUNC_REALLOC 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_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" ode-0.11.1/ou/configure0000755000076400007640000240017311206343422011630 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.63 for ou 0. # # Report bugs to . # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008 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 # PATH needs CR # 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_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 if (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 # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false 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. 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); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # Required to use basename. 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 # Name of the executable. 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'` # CDPATH. $as_unset CDPATH if test "x$CONFIG_SHELL" = x; then if (eval ":") 2>/dev/null; then as_have_required=yes else as_have_required=no fi if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=\$LINENO as_lineno_2=\$LINENO test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } ") 2> /dev/null; then : else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in /*) for as_base in sh bash ksh sh5; do as_candidate_shells="$as_candidate_shells $as_dir/$as_base" done;; esac done IFS=$as_save_IFS for as_shell in $as_candidate_shells $SHELL; do # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF 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 : _ASEOF }; then CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF 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_func_return () { (exit $1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = "$1" ); then : else exitcode=1 echo positional parameters were not saved. fi test $exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } _ASEOF }; then break fi fi done if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test $as_have_required = no; then echo This script requires a shell more modern than all the echo shells that I found on your system. Please install a echo modern shell, or manually run the script under such a echo shell if you do have one. { (exit 1); exit 1; } fi fi fi (eval "as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0") || { echo No shell found that supports shell functions. echo Please tell bug-autoconf@gnu.org about your system, echo including any error possibly output before this message. echo This can help us improve future autoconf versions. echo Configuration will now proceed without shell functions. } as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. 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 { (exit 1); exit 1; }; } # 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 } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi 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 -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' 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=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # 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'" # Check that we are running under the correct shell. SHELL=${CONFIG_SHELL-/bin/sh} case X$lt_ECHO in X*--fallback-echo) # Remove one level of quotation (which was required for Make). ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` ;; esac ECHO=${lt_ECHO-echo} if test "X$1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X$1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then # Yippee, $ECHO works! : else # Restart under the correct shell. exec $SHELL "$0" --no-reexec ${1+"$@"} fi if test "X$1" = X--fallback-echo; then # used as fallback echo shift cat <<_LT_EOF $* _LT_EOF exit 0 fi # 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 if test -z "$lt_ECHO"; then if test "X${echo_test_string+set}" != Xset; then # find a string as large as possible, as long as the shell can cope with it for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... if { echo_test_string=`eval $cmd`; } 2>/dev/null && { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null then break fi done fi if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then : else # The Solaris, AIX, and Digital Unix default echo programs unquote # backslashes. This makes it impossible to quote backslashes using # echo "$something" | sed 's/\\/\\\\/g' # # So, first we look for a working echo in the user's PATH. lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for dir in $PATH /usr/ucb; do IFS="$lt_save_ifs" if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then ECHO="$dir/echo" break fi done IFS="$lt_save_ifs" if test "X$ECHO" = Xecho; then # We didn't find a better echo, so look for alternatives. if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # This shell has a builtin print -r that does the trick. ECHO='print -r' elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && test "X$CONFIG_SHELL" != X/bin/ksh; then # If we have ksh, try running configure again with it. ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} export ORIGINAL_CONFIG_SHELL CONFIG_SHELL=/bin/ksh export CONFIG_SHELL exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} else # Try using printf. ECHO='printf %s\n' if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # Cool, printf works : elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL export CONFIG_SHELL SHELL="$CONFIG_SHELL" export SHELL ECHO="$CONFIG_SHELL $0 --fallback-echo" elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then ECHO="$CONFIG_SHELL $0 --fallback-echo" else # maybe with a smaller string... prev=: for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null then break fi prev="$cmd" done if test "$prev" != 'sed 50q "$0"'; then echo_test_string=`eval $prev` export echo_test_string exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} else # Oops. We lost completely, so just stick with echo. ECHO=echo fi fi fi fi fi fi # Copy echo and quote the copy suitably for passing to libtool from # the Makefile, instead of quoting the original, which is used later. lt_ECHO=$ECHO if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" fi exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, 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= SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='ou' PACKAGE_TARNAME='ou' PACKAGE_VERSION='0' PACKAGE_STRING='ou 0' PACKAGE_BUGREPORT='oleh_derevenko@users.sourceforge.net' ac_unique_file="src/ou/atomic.cpp" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='LTLIBOBJS OU_NAMESPACE LIBOBJS CXXCPP OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL lt_ECHO 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__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE 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 localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix 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_shared enable_static with_pic enable_fast_install with_gnu_ld enable_libtool_lock with_namespace enable_asserts ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP CXX CXXFLAGS CCC CXXCPP OU_NAMESPACE' # 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' 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=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_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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 ;; -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_echo "$as_me: error: invalid package name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: invalid package name: $ac_useropt" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } 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_echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2 { (exit 1); exit 1; }; } ;; *) $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 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_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } 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 $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 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_echo "$as_me: error: working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || { $as_echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } # 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_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } 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] --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] --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --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 try to use only PIC/non-PIC objects [default=use both] --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-namespace=name sets the namespace for compiled code Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor CXX C++ compiler command CXXFLAGS C++ compiler flags CXXCPP C++ preprocessor OU_NAMESPACE which namespace OU will be compiled in 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 . _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.63 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 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 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.63. 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) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$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 ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export 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 cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX 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:$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= ;; #( *) $as_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 cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX 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 cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX 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 cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX 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'; { (exit 1); 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 # 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 # 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 ac_site_file1=$CONFIG_SITE 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 -r "$ac_site_file"; then { $as_echo "$as_me:$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" 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. if test -f "$cache_file"; then { $as_echo "$as_me:$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:$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:$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:$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:$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:$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:$LINENO: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:$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. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:$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_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 $as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } 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_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_echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 $as_echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 $as_echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} { (exit 1); exit 1; }; } { $as_echo "$as_me:$LINENO: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if test "${ac_cv_build+set}" = set; 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_echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 $as_echo "$as_me: error: cannot guess build type; you must specify one" >&2;} { (exit 1); exit 1; }; } ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 $as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} { (exit 1); exit 1; }; } fi { $as_echo "$as_me:$LINENO: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 $as_echo "$as_me: error: invalid value of canonical build" >&2;} { (exit 1); exit 1; }; };; 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:$LINENO: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if test "${ac_cv_host+set}" = set; 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_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 $as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} { (exit 1); exit 1; }; } fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 $as_echo "$as_me: error: invalid value of canonical host" >&2;} { (exit 1); exit 1; }; };; 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 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 $as_echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } # Provide some information about the compiler. $as_echo "$as_me:$LINENO: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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:$LINENO: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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 { $as_echo "$as_me:$LINENO: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } if test -z "$ac_file"; then $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 $as_echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; }; } fi ac_exeext=$ac_cv_exeext # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:$LINENO: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi fi fi { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } { $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } { $as_echo "$as_me:$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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi rm -f conftest$ac_cv_exeext { $as_echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT { $as_echo "$as_me:$LINENO: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if test "${ac_cv_objext+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 $as_echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:$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 test "${ac_cv_c_compiler_gnu+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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:$LINENO: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if test "${ac_cv_prog_cc_g+set}" = set; 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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:$LINENO: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* 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" 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$LINENO: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:$LINENO: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; 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 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:$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 test "${ac_cv_prog_CPP+set}" = set; 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 to if __STDC__ is defined, since # 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f 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:$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 to if __STDC__ is defined, since # 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 $as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } 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:$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 test "${ac_cv_path_GREP+set}" = set; 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" { test -f "$ac_path_GREP" && $as_test_x "$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 ac_count=`expr $ac_count + 1` 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_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 $as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:$LINENO: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if test "${ac_cv_path_EGREP+set}" = set; 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" { test -f "$ac_path_EGREP" && $as_test_x "$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 ac_count=`expr $ac_count + 1` 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_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 $as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if test "${ac_cv_header_stdc+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #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 rm -f 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : 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 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF 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` { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done if test "${ac_cv_header_minix_config_h+set}" = set; then { $as_echo "$as_me:$LINENO: checking for minix/config.h" >&5 $as_echo_n "checking for minix/config.h... " >&6; } if test "${ac_cv_header_minix_config_h+set}" = set; then $as_echo_n "(cached) " >&6 fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5 $as_echo "$ac_cv_header_minix_config_h" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking minix/config.h usability" >&5 $as_echo_n "checking minix/config.h usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking minix/config.h presence" >&5 $as_echo_n "checking minix/config.h presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: minix/config.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: minix/config.h: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: minix/config.h: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: minix/config.h: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: minix/config.h: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: minix/config.h: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: minix/config.h: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: minix/config.h: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## --------------------------------------------------- ## ## Report this to oleh_derevenko@users.sourceforge.net ## ## --------------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for minix/config.h" >&5 $as_echo_n "checking for minix/config.h... " >&6; } if test "${ac_cv_header_minix_config_h+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_header_minix_config_h=$ac_header_preproc fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5 $as_echo "$ac_cv_header_minix_config_h" >&6; } fi if test "x$ac_cv_header_minix_config_h" = x""yes; then MINIX=yes else MINIX= fi if test "$MINIX" = yes; then cat >>confdefs.h <<\_ACEOF #define _POSIX_SOURCE 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _POSIX_1_SOURCE 2 _ACEOF cat >>confdefs.h <<\_ACEOF #define _MINIX 1 _ACEOF fi { $as_echo "$as_me:$LINENO: checking whether it is safe to define __EXTENSIONS__" >&5 $as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } if test "${ac_cv_safe_to_define___extensions__+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ # define __EXTENSIONS__ 1 $ac_includes_default int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_safe_to_define___extensions__=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_safe_to_define___extensions__=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$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 && cat >>confdefs.h <<\_ACEOF #define __EXTENSIONS__ 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _ALL_SOURCE 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _GNU_SOURCE 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _POSIX_PTHREAD_SEMANTICS 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define _TANDEM_SOURCE 1 _ACEOF am__api_version='1.10' # 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:$LINENO: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; 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 { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$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:$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:$LINENO: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Just in case sleep 1 echo timestamp > conftest.file # 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 ( 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 rm -f conftest.file 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_echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&5 $as_echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&2;} { (exit 1); exit 1; }; } fi test "$2" = conftest.file ) then # Ok. : else { { $as_echo "$as_me:$LINENO: error: newly created file is older than distributed files! Check your system clock" >&5 $as_echo "$as_me: error: newly created file is older than distributed files! Check your system clock" >&2;} { (exit 1); exit 1; }; } fi { $as_echo "$as_me:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } 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` test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { $as_echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi { $as_echo "$as_me:$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 test "${ac_cv_path_mkdir+set}" = set; 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 { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$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 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. test -d ./--version && rmdir ./--version MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:$LINENO: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } mkdir_p="$MKDIR_P" case $mkdir_p in [\\/$]* | ?:[\\/]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_AWK+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:$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 { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; 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:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:$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 done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:$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 # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi { $as_echo "$as_me:$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='\' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi 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_echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 $as_echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} { (exit 1); exit 1; }; } 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"} install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} # 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_STRIP+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:$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:$LINENO: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:$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:$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" # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. AMTAR=${AMTAR-"${am_missing_run}tar"} am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' depcc="$CC" am_compiler_list= { $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if test "${am_cv_CC_dependencies_compiler_type+set}" = set; 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'. 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 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 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in 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 ;; none) break ;; esac # 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. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} 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 sub/conftest.${OBJEXT-o} 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:$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 { $as_echo "$as_me:$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:$LINENO: result: win32" >&5 $as_echo "win32" >&6; } ;; *qnx*) targetos=_OU_TARGET_OS_QNX { $as_echo "$as_me:$LINENO: result: qnx" >&5 $as_echo "qnx" >&6; } ;; *apple* | *darwin*) targetos=_OU_TARGET_OS_MAC { $as_echo "$as_me:$LINENO: result: darwin" >&5 $as_echo "darwin" >&6; } ;; *sunos*) targetos=_OU_TARGET_OS_SUNOS { $as_echo "$as_me:$LINENO: result: sunos" >&5 $as_echo "sunos" >&6; } ;; *aix*) targetos=_OU_TARGET_OS_AIX { $as_echo "$as_me:$LINENO: result: aix" >&5 $as_echo "aix" >&6; } ;; *) targetos=_OU_TARGET_OS_GENUNIX { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CXX+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CXX+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { $as_echo "$as_me:$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 test "${ac_cv_cxx_compiler_gnu+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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:$LINENO: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if test "${ac_cv_prog_cxx_g+set}" = set; 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CXXFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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 depcc="$CXX" am_compiler_list= { $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; 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'. 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 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 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in 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 ;; none) break ;; esac # 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. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} 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 sub/conftest.${OBJEXT-o} 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:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$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:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 $as_echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } # Provide some information about the compiler. $as_echo "$as_me:$LINENO: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { $as_echo "$as_me:$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 test "${ac_cv_c_compiler_gnu+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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:$LINENO: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if test "${ac_cv_prog_cc_g+set}" = set; 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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:$LINENO: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* 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" 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$LINENO: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:$LINENO: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; 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 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_AWK+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done # 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:$LINENO: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; 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 { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$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:$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' 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_RANLIB+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:$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:$LINENO: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:$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:$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:$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 test "${ac_cv_prog_CPP+set}" = set; 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 to if __STDC__ is defined, since # 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f 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:$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 to if __STDC__ is defined, since # 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 $as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; }; } 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:$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 test "${ac_cv_path_mkdir+set}" = set; 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 { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$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 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. test -d ./--version && rmdir ./--version MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:$LINENO: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_AS+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AS="${ac_tool_prefix}as" $as_echo "$as_me:$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:$LINENO: result: $AS" >&5 $as_echo "$AS" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_AS+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_AS="as" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_AS" >&5 $as_echo "$ac_ct_AS" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_DLLTOOL+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:$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:$LINENO: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_DLLTOOL+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_OBJDUMP+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:$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:$LINENO: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:$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:$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:$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.2.6' macro_revision='1.3012' ltmain="$ac_aux_dir/ltmain.sh" { $as_echo "$as_me:$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 test "${ac_cv_path_SED+set}" = set; 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 $as_unset ac_script || 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" { test -f "$ac_path_SED" && $as_test_x "$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 ac_count=`expr $ac_count + 1` 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_echo "$as_me:$LINENO: error: no acceptable sed could be found in \$PATH" >&5 $as_echo "$as_me: error: no acceptable sed could be found in \$PATH" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:$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:$LINENO: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if test "${ac_cv_path_FGREP+set}" = set; 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" { test -f "$ac_path_FGREP" && $as_test_x "$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 ac_count=`expr $ac_count + 1` 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_echo "$as_me:$LINENO: error: no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 $as_echo "$as_me: error: no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:$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 "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:$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 "$with_gnu_ld" = yes; then { $as_echo "$as_me:$LINENO: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:$LINENO: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if test "${lt_cv_path_LD+set}" = set; 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 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && { { $as_echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 $as_echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} { (exit 1); exit 1; }; } { $as_echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if test "${lt_cv_prog_gnu_ld+set}" = set; 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 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:$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 test "${lt_cv_path_NM+set}" = set; 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 case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) 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:$LINENO: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$ac_tool_prefix"; then for ac_prog in "dumpbin -symbols" "link -dump -symbols" 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_DUMPBIN+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:$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 -symbols" "link -dump -symbols" 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:$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:$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 if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:$LINENO: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if test "${lt_cv_nm_interface+set}" = set; 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:7077: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:7080: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:7083: 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:$LINENO: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } { $as_echo "$as_me:$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:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if test "${lt_cv_sys_max_cmd_len+set}" = set; 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; ;; 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; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # 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 ;; 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"; 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"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ = "XX$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 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:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:$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"} { $as_echo "$as_me:$LINENO: checking whether the shell understands some XSI constructs" >&5 $as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes { $as_echo "$as_me:$LINENO: result: $xsi_shell" >&5 $as_echo "$xsi_shell" >&6; } { $as_echo "$as_me:$LINENO: checking whether the shell understands \"+=\"" >&5 $as_echo_n "checking whether the shell understands \"+=\"... " >&6; } lt_shell_append=no ( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes { $as_echo "$as_me:$LINENO: result: $lt_shell_append" >&5 $as_echo "$lt_shell_append" >&6; } 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:$LINENO: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if test "${lt_cv_ld_reload_flag+set}" = set; then $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:$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 darwin*) if test "$GCC" = yes; 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_OBJDUMP+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:$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:$LINENO: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if test "${lt_cv_deplibs_check_method+set}" = set; 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 # which 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 lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' 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 ;; gnu*) 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]) 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 Linux ELF. linux* | k*bsd*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd*) 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*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; 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 ;; esac fi { $as_echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } 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}ar", so it can be a program name with args. set dummy ${ac_tool_prefix}ar; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_AR+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AR="${ac_tool_prefix}ar" $as_echo "$as_me:$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:$LINENO: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_AR"; then ac_ct_AR=$AR # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_AR+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_AR="ar" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:$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 else AR="$ac_cv_prog_AR" fi test -z "$AR" && AR=ar test -z "$AR_FLAGS" && AR_FLAGS=cru 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_STRIP+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:$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:$LINENO: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_RANLIB+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:$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:$LINENO: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:$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:$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 openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" fi # 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:$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 test "${lt_cv_sys_global_symbol_pipe+set}" = set; 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 "$host_cpu" = ia64; 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 # 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 -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$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 -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/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 # and D for any global 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};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print 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 # 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:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Now try to grab the symbols. nlist=conftest.nm if { (eval echo "$as_me:$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:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && 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 #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. */ const struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$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_save_LIBS="$LIBS" lt_save_CFLAGS="$CFLAGS" LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS="$lt_save_LIBS" CFLAGS="$lt_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 "$pipe_works" = yes; 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:$LINENO: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:$LINENO: result: ok" >&5 $as_echo "ok" >&6; } fi # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then enableval=$enable_libtool_lock; fi test "x$enable_libtool_lock" != xno && 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 which ABI we are using. echo 'int i;' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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 which ABI we are using. echo '#line 8285 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then if test "$lt_cv_prog_gnu_ld" = yes; 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* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|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" ;; ppc*-*linux*|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:$LINENO: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if test "${lt_cv_cc_needs_belf+set}" = set; 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then lt_cv_cc_needs_belf=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 lt_cv_cc_needs_belf=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ 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:$LINENO: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; sparc*-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) LD="${LD-ld} -m elf64_sparc" ;; *) 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" 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_DSYMUTIL+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:$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:$LINENO: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_NMEDIT+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:$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:$LINENO: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_LIPO+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:$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:$LINENO: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_OTOOL+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:$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:$LINENO: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_OTOOL64+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:$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:$LINENO: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if test "${lt_cv_apple_cc_single_mod+set}" = set; 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 test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; 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:$LINENO: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:$LINENO: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if test "${lt_cv_ld_exported_symbols_list+set}" = set; 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then lt_cv_ld_exported_symbols_list=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 lt_cv_ld_exported_symbols_list=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:$LINENO: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&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 "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; 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" != ":"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac for ac_header in dlfcn.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done 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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CXX+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CXX+set}" = set; 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:$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:$LINENO: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:$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:$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:$LINENO: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { $as_echo "$as_me:$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 test "${ac_cv_cxx_compiler_gnu+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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:$LINENO: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if test "${ac_cv_prog_cxx_g+set}" = set; 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CXXFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cxx_g=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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 depcc="$CXX" am_compiler_list= { $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; 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'. 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 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 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in 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 ;; none) break ;; esac # 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. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} 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 sub/conftest.${OBJEXT-o} 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:$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 if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; 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:$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 test "${ac_cv_prog_CXXCPP+set}" = set; 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 to if __STDC__ is defined, since # 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f 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:$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 to if __STDC__ is defined, since # 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} _lt_caught_CXX_error=yes; } 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 # 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; pic_mode="$withval" else pic_mode=default fi test -z "$pic_mode" && pic_mode=default # 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 # 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:$LINENO: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if test "${lt_cv_objdir+set}" = set; 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:$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 "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # 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. 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' # 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 for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` # 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:$LINENO: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if test "${lt_cv_path_MAGIC_CMD+set}" = set; 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:$LINENO: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:$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:$LINENO: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if test "${lt_cv_path_MAGIC_CMD+set}" = set; 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:$LINENO: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:$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 "$GCC" = yes; then lt_prog_compiler_no_builtin_flag=' -fno-builtin' { $as_echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; 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" # 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:10367: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:10371: \$? = $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 "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/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:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; 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= { $as_echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if test "$GCC" = yes; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi ;; 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' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; 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 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 "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; 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' ;; 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) 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' ;; pgcc* | pgf77* | pgf90* | pgf95*) # 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*) # IBM XL C 8.0/Fortran 10.1 on PPC lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Sun\ F*) # 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='' ;; 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*) 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 which 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:$LINENO: result: $lt_prog_compiler_pic" >&5 $as_echo "$lt_prog_compiler_pic" >&6; } # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:$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 test "${lt_cv_prog_compiler_pic_works+set}" = set; 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" # 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:10706: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:10710: \$? = $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 "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/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:$LINENO: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test x"$lt_cv_prog_compiler_pic_works" = xyes; 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:$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 test "${lt_cv_prog_compiler_static_works+set}" = set; 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 "X$_lt_linker_boilerplate" | $Xsed -e '/^$/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:$LINENO: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test x"$lt_cv_prog_compiler_static_works" = xyes; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:$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 test "${lt_cv_prog_compiler_c_o+set}" = set; 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:10811: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:10815: \$? = $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 "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/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:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:$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 test "${lt_cv_prog_compiler_c_o+set}" = set; 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:10866: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:10870: \$? = $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 "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/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:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:$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:$LINENO: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:$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:$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_flag_spec_ld= 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 "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac ld_shlibs=yes if test "$with_gnu_ld" = yes; 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 2>&1` in *\ [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 "$host_cpu" != ia64; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.9.1, 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 modify your PATH *** so that a non-GNU linker is found, and then restart. _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 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' 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/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' 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 (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; 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 ;; 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) tmp_diet=no if test "$host_os" = linux-dietlibc; 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 "$tmp_diet" = no then tmp_addflag= 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; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95*) # 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; $ECHO \"$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' ;; xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; 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; $ECHO \"$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 "x$supports_anon_versioning" = xyes; 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 xlf*) # 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= hardcode_libdir_flag_spec_ld='-rpath $libdir' archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; 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 $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd*) 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 $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' 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 $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 ;; 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 can not *** 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 $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 if test "$ld_shlibs" = no; 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 "$GCC" = yes && 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 "$host_cpu" = ia64; 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 AIX nm, but means don't demangle with GNU 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")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | 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 # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; 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,' if test "$GCC" = yes; 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 "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi link_all_deplibs=no else # not using gcc if test "$host_cpu" = ia64; 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 "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi 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_use_runtimelinking" = yes; 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. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/ p } }' 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 "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; 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 "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; 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. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/ p } }' 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 "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; 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' # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' archive_cmds_need_lc=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' 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. 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 `$ECHO "X$deplibs" | $Xsed -e '\''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' fix_srcfile_path='`cygpath -w "$srcfile"`' enable_shared_with_static_runtimes=yes ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported whole_archive_flag_spec='' link_all_deplibs=yes allow_undefined_flag="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=echo 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 ;; freebsd1*) ld_shlibs=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 -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $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 $output_objdir/$soname = $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 "$GCC" = yes -a "$with_gnu_ld" = no; then archive_cmds='$CC -shared -fPIC ${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 "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_flag_spec_ld='+b $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 "$GCC" = yes -a "$with_gnu_ld" = no; 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 -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared -fPIC ${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' ;; *) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; 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 "$GCC" = yes; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${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. save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" cat >conftest.$ac_ext <<_ACEOF int foo(void) {} _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -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 ;; netbsd*) 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*) 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__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; 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 case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-R$libdir' ;; *) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; 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" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${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" && $ECHO "X-set_version $verstring" | $Xsed` -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 "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${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" && $ECHO "X-set_version $verstring" | $Xsed` -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 "X-set_version $verstring" | $Xsed` -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 "$GCC" = yes; then wlarc='${wl}' archive_cmds='$CC -shared ${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 ${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 "$GCC" = yes; 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 "x$host_vendor" = xsequent; 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 "$GCC" = yes; 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 can NOT 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 "$GCC" = yes; 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 x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='${wl}-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:$LINENO: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test "$ld_shlibs" = no && 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 "$enable_shared" = yes && test "$GCC" = yes; 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:$LINENO: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } 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:$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:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } then archive_cmds_need_lc=no else archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* { $as_echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5 $as_echo "$archive_cmds_need_lc" >&6; } ;; esac fi ;; esac { $as_echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then # 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 -e 's/;/ /g'` else lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # 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` 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" else 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; } }'` sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` 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 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 need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; 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 # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.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}' else # 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' fi 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=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $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 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,$host_os in yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) 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="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. 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 ;; 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 ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # 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 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 ;; freebsd1*) dynamic_linker=no ;; 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[123]*) 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} $libname${shared_ext}' 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 ;; 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 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 "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; 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' ;; interix[3-9]*) 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' 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 "$lt_cv_prog_gnu_ld" = yes; then version_type=linux 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 ;; # This must be Linux ELF. linux* | k*bsd*-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' 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 save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then shlibpath_overrides_runpath=yes fi else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir # 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 # find out which ABI we are using libsuff= case "$host_cpu" in x86_64*|s390x*|powerpc64*) echo '#line 12723 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then case `/usr/bin/file conftest.$ac_objext` in *64-bit*) libsuff=64 ;; esac fi rm -rf conftest* ;; esac sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff}" # Append ld.so.conf contents 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;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $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' ;; 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 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*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac 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 if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; 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 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 "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux 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 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=freebsd-elf 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 "$with_gnu_ld" = yes; 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 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 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:$LINENO: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:$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 "X$hardcode_automatic" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct" != no && # 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 "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && test "$hardcode_minus_L" != no; 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:$LINENO: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test "$hardcode_action" = relink || test "$inherit_rpath" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi if test "x$enable_dlopen" != xyes; 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:$LINENO: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if test "${ac_cv_lib_dl_dlopen+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_dl_dlopen=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlopen=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = x""yes; 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 ;; *) { $as_echo "$as_me:$LINENO: checking for shl_load" >&5 $as_echo_n "checking for shl_load... " >&6; } if test "${ac_cv_func_shl_load+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define shl_load to an innocuous variant, in case declares shl_load. For example, HP-UX 11i declares gettimeofday. */ #define shl_load innocuous_shl_load /* System header to define __stub macros and hopefully few prototypes, which can conflict with char shl_load (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef shl_load /* 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 (); /* 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_shl_load || defined __stub___shl_load choke me #endif int main () { return shl_load (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_shl_load=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_shl_load=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 $as_echo "$ac_cv_func_shl_load" >&6; } if test "x$ac_cv_func_shl_load" = x""yes; then lt_cv_dlopen="shl_load" else { $as_echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if test "${ac_cv_lib_dld_shl_load+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_dld_shl_load=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_shl_load=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$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" = x""yes; then lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else { $as_echo "$as_me:$LINENO: checking for dlopen" >&5 $as_echo_n "checking for dlopen... " >&6; } if test "${ac_cv_func_dlopen+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define dlopen to an innocuous variant, in case declares dlopen. For example, HP-UX 11i declares gettimeofday. */ #define dlopen innocuous_dlopen /* System header to define __stub macros and hopefully few prototypes, which can conflict with char dlopen (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef dlopen /* 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 (); /* 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_dlopen || defined __stub___dlopen choke me #endif int main () { return dlopen (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_dlopen=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_dlopen=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 $as_echo "$ac_cv_func_dlopen" >&6; } if test "x$ac_cv_func_dlopen" = x""yes; then lt_cv_dlopen="dlopen" else { $as_echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if test "${ac_cv_lib_dl_dlopen+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_dl_dlopen=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlopen=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = x""yes; then lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else { $as_echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if test "${ac_cv_lib_svld_dlopen+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_svld_dlopen=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_svld_dlopen=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = x""yes; then lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else { $as_echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if test "${ac_cv_lib_dld_dld_link+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_dld_dld_link=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_dld_link=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$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" = x""yes; then lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" fi fi fi fi fi fi ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && 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:$LINENO: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if test "${lt_cv_dlopen_self+set}" = set; then $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; 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 13689 "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #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 void fnord() { int i=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; /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && 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:$LINENO: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:$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 test "${lt_cv_dlopen_self_static+set}" = set; then $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; 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 13785 "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #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 void fnord() { int i=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; /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && 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:$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:$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:$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:$LINENO: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report which library types will actually be built { $as_echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:$LINENO: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:$LINENO: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test "$can_build_shared" = "no" && 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 "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac { $as_echo "$as_me:$LINENO: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:$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 "$enable_shared" = yes || enable_static=yes { $as_echo "$as_me:$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" 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_flag_spec_ld_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 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 "$_lt_caught_CXX_error" != yes; 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_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++"} compiler=$CC compiler_CXX=$CC for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' else lt_prog_compiler_no_builtin_flag_CXX= fi if test "$GXX" = yes; 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 "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:$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 "$with_gnu_ld" = yes; then { $as_echo "$as_me:$LINENO: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:$LINENO: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if test "${lt_cv_path_LD+set}" = set; 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 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:$LINENO: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && { { $as_echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 $as_echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} { (exit 1); exit 1; }; } { $as_echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if test "${lt_cv_prog_gnu_ld+set}" = set; 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 &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 "$with_gnu_ld" = yes; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -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 "\-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:$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 "$host_cpu" = ia64; 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 # need to do runtime linking. 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 ;; 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,' if test "$GXX" = yes; 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 "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; 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 "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi 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_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag_CXX='-berok' # Determine the default libpath from the value encoded in an empty # executable. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/ p } }' 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 "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; 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 "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; 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. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/ p } }' 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 "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; 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' # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec_CXX='$convenience' archive_cmds_need_lc_CXX=yes # This is similar to how AIX traditionally builds its shared # libraries. archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag_CXX=unsupported # Joseph Beckenbach 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*) # _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' 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 (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; 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 ;; darwin* | rhapsody*) archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes hardcode_shlibpath_var_CXX=unsupported whole_archive_flag_spec_CXX='' link_all_deplibs_CXX=yes allow_undefined_flag_CXX="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=echo 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 "$lt_cv_apple_cc_single_mod" != "yes"; 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 ;; 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 ;; freebsd[12]*) # 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 ;; gnu*) ;; 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 $output_objdir/$soname = $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; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes; then archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; 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; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; 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 -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${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" && $ECHO "X-set_version $verstring" | $Xsed` -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 "$GXX" = yes; then if test "$with_gnu_ld" = no; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -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) 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; $ECHO "X$list" | $Xsed' 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 | $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 | $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 | $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 | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 will 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; $ECHO \"$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=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; xl*) # 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 "x$supports_anon_versioning" = xyes; 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; $ECHO \"$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='echo' # 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 ;; openbsd2*) # C++ shared libraries are fairly broken ld_shlibs_CXX=no ;; openbsd*) 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__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; 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=echo 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" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -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" && $ECHO "X-set_version $verstring" | $Xsed` -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 "X-set_version $verstring" | $Xsed` -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=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; 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" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${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 "\-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*) # 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='echo' # 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 "$GXX" = yes && test "$with_gnu_ld" = no; then no_undefined_flag_CXX=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $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 -nostdlib ${wl}-M $wl$lib.exp -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 "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $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 -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 "\-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 can NOT 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' ;; *) 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:$LINENO: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } test "$ld_shlibs_CXX" = no && 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 if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; 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 $p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue else prev= fi if test "$pre_test_object_deps_done" = no; then case $p 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 ;; *.$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 "$pre_test_object_deps_done" = no; 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 # 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= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then postdeps_CXX='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then postdeps_CXX='-library=Cstd -library=Crun' fi ;; esac ;; 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= { $as_echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; 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 "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' fi ;; 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' ;; 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= ;; 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 "$host_cpu" = ia64; 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 ;; 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 "$host_cpu" != ia64; 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) 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*) # IBM XL 8.0 on PPC 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*) ;; *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*) # 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 which 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:$LINENO: result: $lt_prog_compiler_pic_CXX" >&5 $as_echo "$lt_prog_compiler_pic_CXX" >&6; } # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic_CXX"; then { $as_echo "$as_me:$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 test "${lt_cv_prog_compiler_pic_works_CXX+set}" = set; 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" # 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:15805: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:15809: \$? = $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 "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/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:$LINENO: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 $as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; 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:$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 test "${lt_cv_prog_compiler_static_works_CXX+set}" = set; 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 "X$_lt_linker_boilerplate" | $Xsed -e '/^$/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:$LINENO: result: $lt_cv_prog_compiler_static_works_CXX" >&5 $as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then : else lt_prog_compiler_static_CXX= fi { $as_echo "$as_me:$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 test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; 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:15904: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:15908: \$? = $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 "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/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:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5 $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } { $as_echo "$as_me:$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 test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; 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:15956: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:15960: \$? = $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 "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/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:$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 "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:$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:$LINENO: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:$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:$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' 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 AIX nm, but means don't demangle with GNU 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")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) export_symbols_cmds_CXX="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;/^.*[ ]__nm__/s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' ;; linux* | k*bsd*-gnu) link_all_deplibs_CXX=no ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' { $as_echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } test "$ld_shlibs_CXX" = no && 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 "$enable_shared" = yes && test "$GCC" = yes; 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:$LINENO: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } 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:$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:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } then archive_cmds_need_lc_CXX=no else 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* { $as_echo "$as_me:$LINENO: result: $archive_cmds_need_lc_CXX" >&5 $as_echo "$archive_cmds_need_lc_CXX" >&6; } ;; esac fi ;; esac { $as_echo "$as_me:$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 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 need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; 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 # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.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}' else # 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' fi 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=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $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 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,$host_os in yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) 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="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. 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 ;; 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 ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # 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 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 ;; freebsd1*) dynamic_linker=no ;; 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[123]*) 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} $libname${shared_ext}' 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 ;; 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 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 "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; 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' ;; interix[3-9]*) 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' 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 "$lt_cv_prog_gnu_ld" = yes; then version_type=linux 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 ;; # This must be Linux ELF. linux* | k*bsd*-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' 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 save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then shlibpath_overrides_runpath=yes fi else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir # 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 # find out which ABI we are using libsuff= case "$host_cpu" in x86_64*|s390x*|powerpc64*) echo '#line 16610 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then case `/usr/bin/file conftest.$ac_objext` in *64-bit*) libsuff=64 ;; esac fi rm -rf conftest* ;; esac sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff}" # Append ld.so.conf contents 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;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $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' ;; 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 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*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac 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 if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; 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 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 "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux 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 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=freebsd-elf 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 "$with_gnu_ld" = yes; 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 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 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:$LINENO: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:$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 "X$hardcode_automatic_CXX" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct_CXX" != no && # 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 "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && test "$hardcode_minus_L_CXX" != no; 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:$LINENO: result: $hardcode_action_CXX" >&5 $as_echo "$hardcode_action_CXX" >&6; } if test "$hardcode_action_CXX" = relink || test "$inherit_rpath_CXX" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi fi # test -n "$compiler" CC=$lt_save_CC 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 "$_lt_caught_CXX_error" != yes 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:$LINENO: checking for main in -lc" >&5 $as_echo_n "checking for main in -lc... " >&6; } if test "${ac_cv_lib_c_main+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_c_main=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_c_main=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_c_main" >&5 $as_echo "$ac_cv_lib_c_main" >&6; } if test "x$ac_cv_lib_c_main" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBC 1 _ACEOF LIBS="-lc $LIBS" fi # needed for sunos? { $as_echo "$as_me:$LINENO: checking for main in -lpthread" >&5 $as_echo_n "checking for main in -lpthread... " >&6; } if test "${ac_cv_lib_pthread_main+set}" = set; then $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_lib_pthread_main=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthread_main=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_main" >&5 $as_echo "$ac_cv_lib_pthread_main" >&6; } if test "x$ac_cv_lib_pthread_main" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBPTHREAD 1 _ACEOF LIBS="-lpthread $LIBS" fi cat >>confdefs.h <<\_ACEOF #define _REENTRANT 1 _ACEOF # Checks for header files. { $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if test "${ac_cv_header_stdc+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _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 >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #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 rm -f 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : 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 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF 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` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## --------------------------------------------------- ## ## Report this to oleh_derevenko@users.sourceforge.net ## ## --------------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = 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:$LINENO: checking for stdbool.h that conforms to C99" >&5 $as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } if test "${ac_cv_header_stdbool_h+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #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]; bool e = &s; 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]; # if defined __xlc__ || defined __GNUC__ /* Catch a bug in IBM AIX xlc compiler version 6.0.0.0 reported by James Lemley on 2005-10-05; see http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html This test is not quite right, since xlc is allowed to reject this program, as the initializer for xlcbug is not one of the forms that C requires support for. However, doing the test right would require a runtime test, and that would make cross-compilation harder. Let us hope that IBM fixes the xlc bug, and also adds support for this kind of constant expression. In the meantime, this test will reject xlc, which is OK, since our stdbool.h substitute should suffice. We also test this with GCC, where it should work, to detect more quickly whether someone messes up the test in the future. */ char digs[] = "0123456789"; int xlcbug = 1 / (&(digs + 5)[-2 + (bool) 1] == &digs[4] ? 1 : -1); # endif /* 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 () { *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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdbool_h=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdbool_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdbool_h" >&5 $as_echo "$ac_cv_header_stdbool_h" >&6; } { $as_echo "$as_me:$LINENO: checking for _Bool" >&5 $as_echo_n "checking for _Bool... " >&6; } if test "${ac_cv_type__Bool+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_type__Bool=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if (sizeof (_Bool)) return 0; ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if (sizeof ((_Bool))) return 0; ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type__Bool=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_type__Bool" >&5 $as_echo "$ac_cv_type__Bool" >&6; } if test "x$ac_cv_type__Bool" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE__BOOL 1 _ACEOF fi if test $ac_cv_header_stdbool_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_STDBOOL_H 1 _ACEOF fi { $as_echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if test "${ac_cv_c_const+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { /* FIXME: Include the comments suggested by Paul. */ #ifndef __cplusplus /* Ultrix mips cc rejects this. */ typedef int charset[2]; const charset cs; /* 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. */ char *t; 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 saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; }; struct s *b; 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_const=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then cat >>confdefs.h <<\_ACEOF #define const /**/ _ACEOF fi { $as_echo "$as_me:$LINENO: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if test "${ac_cv_c_inline+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* 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 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_inline=$ac_kw else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 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:$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:$LINENO: checking for int16_t" >&5 $as_echo_n "checking for int16_t... " >&6; } if test "${ac_cv_c_int16_t+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_c_int16_t=no for ac_type in 'int16_t' 'int' 'long int' \ 'long long int' 'short int' 'signed char'; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(0 < ($ac_type) (((($ac_type) 1 << (16 - 2)) - 1) * 2 + 1))]; test_array [0] = 0 ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(($ac_type) (((($ac_type) 1 << (16 - 2)) - 1) * 2 + 1) < ($ac_type) (((($ac_type) 1 << (16 - 2)) - 1) * 2 + 2))]; test_array [0] = 0 ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 case $ac_type in int16_t) ac_cv_c_int16_t=yes ;; *) ac_cv_c_int16_t=$ac_type ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_int16_t" != no && break done fi { $as_echo "$as_me:$LINENO: result: $ac_cv_c_int16_t" >&5 $as_echo "$ac_cv_c_int16_t" >&6; } case $ac_cv_c_int16_t in #( no|yes) ;; #( *) cat >>confdefs.h <<_ACEOF #define int16_t $ac_cv_c_int16_t _ACEOF ;; esac { $as_echo "$as_me:$LINENO: checking for int32_t" >&5 $as_echo_n "checking for int32_t... " >&6; } if test "${ac_cv_c_int32_t+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_c_int32_t=no for ac_type in 'int32_t' 'int' 'long int' \ 'long long int' 'short int' 'signed char'; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(0 < ($ac_type) (((($ac_type) 1 << (32 - 2)) - 1) * 2 + 1))]; test_array [0] = 0 ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(($ac_type) (((($ac_type) 1 << (32 - 2)) - 1) * 2 + 1) < ($ac_type) (((($ac_type) 1 << (32 - 2)) - 1) * 2 + 2))]; test_array [0] = 0 ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 case $ac_type in int32_t) ac_cv_c_int32_t=yes ;; *) ac_cv_c_int32_t=$ac_type ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_int32_t" != no && break done fi { $as_echo "$as_me:$LINENO: result: $ac_cv_c_int32_t" >&5 $as_echo "$ac_cv_c_int32_t" >&6; } 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:$LINENO: checking for int64_t" >&5 $as_echo_n "checking for int64_t... " >&6; } if test "${ac_cv_c_int64_t+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_c_int64_t=no for ac_type in 'int64_t' 'int' 'long int' \ 'long long int' 'short int' 'signed char'; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(0 < ($ac_type) (((($ac_type) 1 << (64 - 2)) - 1) * 2 + 1))]; test_array [0] = 0 ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(($ac_type) (((($ac_type) 1 << (64 - 2)) - 1) * 2 + 1) < ($ac_type) (((($ac_type) 1 << (64 - 2)) - 1) * 2 + 2))]; test_array [0] = 0 ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 case $ac_type in int64_t) ac_cv_c_int64_t=yes ;; *) ac_cv_c_int64_t=$ac_type ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_int64_t" != no && break done fi { $as_echo "$as_me:$LINENO: result: $ac_cv_c_int64_t" >&5 $as_echo "$ac_cv_c_int64_t" >&6; } case $ac_cv_c_int64_t in #( no|yes) ;; #( *) cat >>confdefs.h <<_ACEOF #define int64_t $ac_cv_c_int64_t _ACEOF ;; esac { $as_echo "$as_me:$LINENO: checking for int8_t" >&5 $as_echo_n "checking for int8_t... " >&6; } if test "${ac_cv_c_int8_t+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_c_int8_t=no for ac_type in 'int8_t' 'int' 'long int' \ 'long long int' 'short int' 'signed char'; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(0 < ($ac_type) (((($ac_type) 1 << (8 - 2)) - 1) * 2 + 1))]; test_array [0] = 0 ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(($ac_type) (((($ac_type) 1 << (8 - 2)) - 1) * 2 + 1) < ($ac_type) (((($ac_type) 1 << (8 - 2)) - 1) * 2 + 2))]; test_array [0] = 0 ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 case $ac_type in int8_t) ac_cv_c_int8_t=yes ;; *) ac_cv_c_int8_t=$ac_type ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_int8_t" != no && break done fi { $as_echo "$as_me:$LINENO: result: $ac_cv_c_int8_t" >&5 $as_echo "$ac_cv_c_int8_t" >&6; } case $ac_cv_c_int8_t in #( no|yes) ;; #( *) cat >>confdefs.h <<_ACEOF #define int8_t $ac_cv_c_int8_t _ACEOF ;; esac { $as_echo "$as_me:$LINENO: checking for size_t" >&5 $as_echo_n "checking for size_t... " >&6; } if test "${ac_cv_type_size_t+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_type_size_t=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if (sizeof (size_t)) return 0; ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if (sizeof ((size_t))) return 0; ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_size_t=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 $as_echo "$ac_cv_type_size_t" >&6; } if test "x$ac_cv_type_size_t" = x""yes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi { $as_echo "$as_me:$LINENO: checking for uint16_t" >&5 $as_echo_n "checking for uint16_t... " >&6; } if test "${ac_cv_c_uint16_t+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_c_uint16_t=no for ac_type in 'uint16_t' 'unsigned int' 'unsigned long int' \ 'unsigned long long int' 'unsigned short int' 'unsigned char'; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(($ac_type) -1 >> (16 - 1) == 1)]; test_array [0] = 0 ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then case $ac_type in uint16_t) ac_cv_c_uint16_t=yes ;; *) ac_cv_c_uint16_t=$ac_type ;; esac else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_uint16_t" != no && break done fi { $as_echo "$as_me:$LINENO: result: $ac_cv_c_uint16_t" >&5 $as_echo "$ac_cv_c_uint16_t" >&6; } case $ac_cv_c_uint16_t in #( no|yes) ;; #( *) cat >>confdefs.h <<_ACEOF #define uint16_t $ac_cv_c_uint16_t _ACEOF ;; esac { $as_echo "$as_me:$LINENO: checking for uint32_t" >&5 $as_echo_n "checking for uint32_t... " >&6; } if test "${ac_cv_c_uint32_t+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_c_uint32_t=no for ac_type in 'uint32_t' 'unsigned int' 'unsigned long int' \ 'unsigned long long int' 'unsigned short int' 'unsigned char'; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(($ac_type) -1 >> (32 - 1) == 1)]; test_array [0] = 0 ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then case $ac_type in uint32_t) ac_cv_c_uint32_t=yes ;; *) ac_cv_c_uint32_t=$ac_type ;; esac else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_uint32_t" != no && break done fi { $as_echo "$as_me:$LINENO: result: $ac_cv_c_uint32_t" >&5 $as_echo "$ac_cv_c_uint32_t" >&6; } case $ac_cv_c_uint32_t in #( no|yes) ;; #( *) cat >>confdefs.h <<\_ACEOF #define _UINT32_T 1 _ACEOF cat >>confdefs.h <<_ACEOF #define uint32_t $ac_cv_c_uint32_t _ACEOF ;; esac { $as_echo "$as_me:$LINENO: checking for uint64_t" >&5 $as_echo_n "checking for uint64_t... " >&6; } if test "${ac_cv_c_uint64_t+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_c_uint64_t=no for ac_type in 'uint64_t' 'unsigned int' 'unsigned long int' \ 'unsigned long long int' 'unsigned short int' 'unsigned char'; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(($ac_type) -1 >> (64 - 1) == 1)]; test_array [0] = 0 ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then case $ac_type in uint64_t) ac_cv_c_uint64_t=yes ;; *) ac_cv_c_uint64_t=$ac_type ;; esac else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_uint64_t" != no && break done fi { $as_echo "$as_me:$LINENO: result: $ac_cv_c_uint64_t" >&5 $as_echo "$ac_cv_c_uint64_t" >&6; } case $ac_cv_c_uint64_t in #( no|yes) ;; #( *) cat >>confdefs.h <<\_ACEOF #define _UINT64_T 1 _ACEOF cat >>confdefs.h <<_ACEOF #define uint64_t $ac_cv_c_uint64_t _ACEOF ;; esac { $as_echo "$as_me:$LINENO: checking for uint8_t" >&5 $as_echo_n "checking for uint8_t... " >&6; } if test "${ac_cv_c_uint8_t+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_c_uint8_t=no for ac_type in 'uint8_t' 'unsigned int' 'unsigned long int' \ 'unsigned long long int' 'unsigned short int' 'unsigned char'; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { static int test_array [1 - 2 * !(($ac_type) -1 >> (8 - 1) == 1)]; test_array [0] = 0 ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then case $ac_type in uint8_t) ac_cv_c_uint8_t=yes ;; *) ac_cv_c_uint8_t=$ac_type ;; esac else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_uint8_t" != no && break done fi { $as_echo "$as_me:$LINENO: result: $ac_cv_c_uint8_t" >&5 $as_echo "$ac_cv_c_uint8_t" >&6; } case $ac_cv_c_uint8_t in #( no|yes) ;; #( *) cat >>confdefs.h <<\_ACEOF #define _UINT8_T 1 _ACEOF cat >>confdefs.h <<_ACEOF #define uint8_t $ac_cv_c_uint8_t _ACEOF ;; esac { $as_echo "$as_me:$LINENO: checking for working volatile" >&5 $as_echo_n "checking for working volatile... " >&6; } if test "${ac_cv_c_volatile+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { volatile int x; int * volatile y = (int *) 0; return !x && !y; ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_volatile=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_volatile=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_c_volatile" >&5 $as_echo "$ac_cv_c_volatile" >&6; } if test $ac_cv_c_volatile = no; then cat >>confdefs.h <<\_ACEOF #define volatile /**/ _ACEOF fi { $as_echo "$as_me:$LINENO: checking for ptrdiff_t" >&5 $as_echo_n "checking for ptrdiff_t... " >&6; } if test "${ac_cv_type_ptrdiff_t+set}" = set; then $as_echo_n "(cached) " >&6 else ac_cv_type_ptrdiff_t=no cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if (sizeof (ptrdiff_t)) return 0; ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { if (sizeof ((ptrdiff_t))) return 0; ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_ptrdiff_t=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_type_ptrdiff_t" >&5 $as_echo "$ac_cv_type_ptrdiff_t" >&6; } if test "x$ac_cv_type_ptrdiff_t" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_PTRDIFF_T 1 _ACEOF fi # Checks for library functions. for ac_header in stdlib.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## --------------------------------------------------- ## ## Report this to oleh_derevenko@users.sourceforge.net ## ## --------------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:$LINENO: checking for GNU libc compatible malloc" >&5 $as_echo_n "checking for GNU libc compatible malloc... " >&6; } if test "${ac_cv_func_malloc_0_nonnull+set}" = set; then $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then ac_cv_func_malloc_0_nonnull=no else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #if defined STDC_HEADERS || defined HAVE_STDLIB_H # include #else char *malloc (); #endif int main () { return ! malloc (0); ; return 0; } _ACEOF rm -f 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_malloc_0_nonnull=yes 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 ( exit $ac_status ) ac_cv_func_malloc_0_nonnull=no fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_malloc_0_nonnull" >&5 $as_echo "$ac_cv_func_malloc_0_nonnull" >&6; } if test $ac_cv_func_malloc_0_nonnull = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_MALLOC 1 _ACEOF else cat >>confdefs.h <<\_ACEOF #define HAVE_MALLOC 0 _ACEOF case " $LIBOBJS " in *" malloc.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS malloc.$ac_objext" ;; esac cat >>confdefs.h <<\_ACEOF #define malloc rpl_malloc _ACEOF fi for ac_header in stdlib.h do as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 $as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 $as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { $as_echo "$as_me:$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:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 $as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 $as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## --------------------------------------------------- ## ## Report this to oleh_derevenko@users.sourceforge.net ## ## --------------------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 $as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi as_val=`eval 'as_val=${'$as_ac_Header'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:$LINENO: checking for GNU libc compatible realloc" >&5 $as_echo_n "checking for GNU libc compatible realloc... " >&6; } if test "${ac_cv_func_realloc_0_nonnull+set}" = set; then $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then ac_cv_func_realloc_0_nonnull=no else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #if defined STDC_HEADERS || defined HAVE_STDLIB_H # include #else char *realloc (); #endif int main () { return ! realloc (0, 0); ; return 0; } _ACEOF rm -f 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_realloc_0_nonnull=yes 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 ( exit $ac_status ) ac_cv_func_realloc_0_nonnull=no fi rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_realloc_0_nonnull" >&5 $as_echo "$ac_cv_func_realloc_0_nonnull" >&6; } if test $ac_cv_func_realloc_0_nonnull = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_REALLOC 1 _ACEOF else cat >>confdefs.h <<\_ACEOF #define HAVE_REALLOC 0 _ACEOF case " $LIBOBJS " in *" realloc.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS realloc.$ac_objext" ;; esac cat >>confdefs.h <<\_ACEOF #define realloc rpl_realloc _ACEOF fi for ac_func in memset do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` { $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 $as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* 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 $ac_func (); /* 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_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then eval "$as_ac_var=yes" else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } as_val=`eval 'as_val=${'$as_ac_var'} $as_echo "$as_val"'` if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done if test $targetos = _OU_TARGET_OS_MAC then MAC_OS_X_VERSION=1000 { $as_echo "$as_me:$LINENO: checking for OSAtomicAdd32Barrier" >&5 $as_echo_n "checking for OSAtomicAdd32Barrier... " >&6; } if test "${ac_cv_func_OSAtomicAdd32Barrier+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define OSAtomicAdd32Barrier to an innocuous variant, in case declares OSAtomicAdd32Barrier. For example, HP-UX 11i declares gettimeofday. */ #define OSAtomicAdd32Barrier innocuous_OSAtomicAdd32Barrier /* System header to define __stub macros and hopefully few prototypes, which can conflict with char OSAtomicAdd32Barrier (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef OSAtomicAdd32Barrier /* 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 OSAtomicAdd32Barrier (); /* 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_OSAtomicAdd32Barrier || defined __stub___OSAtomicAdd32Barrier choke me #endif int main () { return OSAtomicAdd32Barrier (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_OSAtomicAdd32Barrier=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_OSAtomicAdd32Barrier=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_OSAtomicAdd32Barrier" >&5 $as_echo "$ac_cv_func_OSAtomicAdd32Barrier" >&6; } if test "x$ac_cv_func_OSAtomicAdd32Barrier" = x""yes; then MAC_OS_X_VERSION=1040 fi { $as_echo "$as_me:$LINENO: checking for OSAtomicAnd32OrigBarrier" >&5 $as_echo_n "checking for OSAtomicAnd32OrigBarrier... " >&6; } if test "${ac_cv_func_OSAtomicAnd32OrigBarrier+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define OSAtomicAnd32OrigBarrier to an innocuous variant, in case declares OSAtomicAnd32OrigBarrier. For example, HP-UX 11i declares gettimeofday. */ #define OSAtomicAnd32OrigBarrier innocuous_OSAtomicAnd32OrigBarrier /* System header to define __stub macros and hopefully few prototypes, which can conflict with char OSAtomicAnd32OrigBarrier (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef OSAtomicAnd32OrigBarrier /* 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 OSAtomicAnd32OrigBarrier (); /* 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_OSAtomicAnd32OrigBarrier || defined __stub___OSAtomicAnd32OrigBarrier choke me #endif int main () { return OSAtomicAnd32OrigBarrier (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_OSAtomicAnd32OrigBarrier=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_OSAtomicAnd32OrigBarrier=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_OSAtomicAnd32OrigBarrier" >&5 $as_echo "$ac_cv_func_OSAtomicAnd32OrigBarrier" >&6; } if test "x$ac_cv_func_OSAtomicAnd32OrigBarrier" = x""yes; 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 { $as_echo "$as_me:$LINENO: checking for atomic_inc_32_nv" >&5 $as_echo_n "checking for atomic_inc_32_nv... " >&6; } if test "${ac_cv_func_atomic_inc_32_nv+set}" = set; then $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define atomic_inc_32_nv to an innocuous variant, in case declares atomic_inc_32_nv. For example, HP-UX 11i declares gettimeofday. */ #define atomic_inc_32_nv innocuous_atomic_inc_32_nv /* System header to define __stub macros and hopefully few prototypes, which can conflict with char atomic_inc_32_nv (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef atomic_inc_32_nv /* 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 atomic_inc_32_nv (); /* 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_atomic_inc_32_nv || defined __stub___atomic_inc_32_nv choke me #endif int main () { return atomic_inc_32_nv (); ; return 0; } _ACEOF 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:$LINENO: $ac_try_echo\"" $as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then ac_cv_func_atomic_inc_32_nv=yes else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_atomic_inc_32_nv=no fi rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:$LINENO: result: $ac_cv_func_atomic_inc_32_nv" >&5 $as_echo "$ac_cv_func_atomic_inc_32_nv" >&6; } if test "x$ac_cv_func_atomic_inc_32_nv" = x""yes; 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 --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:$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= ;; #( *) $as_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 test "x$cache_file" != "x/dev/null" && { $as_echo "$as_me:$LINENO: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { $as_echo "$as_me:$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= 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. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." >&5 $as_echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } 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:$LINENO: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF || ac_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} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_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 # PATH needs CR # 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_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 if (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 # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false 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. 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); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # Required to use basename. 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 # Name of the executable. 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'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. 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 { (exit 1); exit 1; }; } # 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 } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi 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 -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' 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=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # 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 # 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.63. 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="`echo $ac_config_files`" config_commands="`echo $ac_config_commands`" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTION]... [FILE]... -h, --help print this help, then exit -V, --version print version number and configuration settings, 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 ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ ou config.status 0 configured by $0, generated by GNU Autoconf 2.63, with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2008 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=$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 ;; --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"` ;; esac CONFIG_FILES="$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_echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$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 "X$AS" | $Xsed -e "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "X$DLLTOOL" | $Xsed -e "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`' macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`' macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`' enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`' enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`' pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`' host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`' host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`' host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`' build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`' build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`' build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`' SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`' Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`' GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`' EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`' FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`' LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`' NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`' LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`' ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`' exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`' lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`' reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`' reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`' AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`' STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`' RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`' CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`' compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`' GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`' SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`' ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`' need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`' NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`' LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`' OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`' OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`' libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`' fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`' include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`' file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`' version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`' runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`' libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`' library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`' soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`' finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`' sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`' hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`' old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`' striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`' compiler_lib_search_dirs='`$ECHO "X$compiler_lib_search_dirs" | $Xsed -e "$delay_single_quote_subst"`' predep_objects='`$ECHO "X$predep_objects" | $Xsed -e "$delay_single_quote_subst"`' postdep_objects='`$ECHO "X$postdep_objects" | $Xsed -e "$delay_single_quote_subst"`' predeps='`$ECHO "X$predeps" | $Xsed -e "$delay_single_quote_subst"`' postdeps='`$ECHO "X$postdeps" | $Xsed -e "$delay_single_quote_subst"`' compiler_lib_search_path='`$ECHO "X$compiler_lib_search_path" | $Xsed -e "$delay_single_quote_subst"`' LD_CXX='`$ECHO "X$LD_CXX" | $Xsed -e "$delay_single_quote_subst"`' old_archive_cmds_CXX='`$ECHO "X$old_archive_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' compiler_CXX='`$ECHO "X$compiler_CXX" | $Xsed -e "$delay_single_quote_subst"`' GCC_CXX='`$ECHO "X$GCC_CXX" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "X$lt_prog_compiler_no_builtin_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_wl_CXX='`$ECHO "X$lt_prog_compiler_wl_CXX" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_pic_CXX='`$ECHO "X$lt_prog_compiler_pic_CXX" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_static_CXX='`$ECHO "X$lt_prog_compiler_static_CXX" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o_CXX='`$ECHO "X$lt_cv_prog_compiler_c_o_CXX" | $Xsed -e "$delay_single_quote_subst"`' archive_cmds_need_lc_CXX='`$ECHO "X$archive_cmds_need_lc_CXX" | $Xsed -e "$delay_single_quote_subst"`' enable_shared_with_static_runtimes_CXX='`$ECHO "X$enable_shared_with_static_runtimes_CXX" | $Xsed -e "$delay_single_quote_subst"`' export_dynamic_flag_spec_CXX='`$ECHO "X$export_dynamic_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' whole_archive_flag_spec_CXX='`$ECHO "X$whole_archive_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' compiler_needs_object_CXX='`$ECHO "X$compiler_needs_object_CXX" | $Xsed -e "$delay_single_quote_subst"`' old_archive_from_new_cmds_CXX='`$ECHO "X$old_archive_from_new_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds_CXX='`$ECHO "X$old_archive_from_expsyms_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' archive_cmds_CXX='`$ECHO "X$archive_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' archive_expsym_cmds_CXX='`$ECHO "X$archive_expsym_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' module_cmds_CXX='`$ECHO "X$module_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' module_expsym_cmds_CXX='`$ECHO "X$module_expsym_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' with_gnu_ld_CXX='`$ECHO "X$with_gnu_ld_CXX" | $Xsed -e "$delay_single_quote_subst"`' allow_undefined_flag_CXX='`$ECHO "X$allow_undefined_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`' no_undefined_flag_CXX='`$ECHO "X$no_undefined_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_CXX='`$ECHO "X$hardcode_libdir_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_ld_CXX='`$ECHO "X$hardcode_libdir_flag_spec_ld_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_libdir_separator_CXX='`$ECHO "X$hardcode_libdir_separator_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_direct_CXX='`$ECHO "X$hardcode_direct_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_direct_absolute_CXX='`$ECHO "X$hardcode_direct_absolute_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_minus_L_CXX='`$ECHO "X$hardcode_minus_L_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_shlibpath_var_CXX='`$ECHO "X$hardcode_shlibpath_var_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_automatic_CXX='`$ECHO "X$hardcode_automatic_CXX" | $Xsed -e "$delay_single_quote_subst"`' inherit_rpath_CXX='`$ECHO "X$inherit_rpath_CXX" | $Xsed -e "$delay_single_quote_subst"`' link_all_deplibs_CXX='`$ECHO "X$link_all_deplibs_CXX" | $Xsed -e "$delay_single_quote_subst"`' fix_srcfile_path_CXX='`$ECHO "X$fix_srcfile_path_CXX" | $Xsed -e "$delay_single_quote_subst"`' always_export_symbols_CXX='`$ECHO "X$always_export_symbols_CXX" | $Xsed -e "$delay_single_quote_subst"`' export_symbols_cmds_CXX='`$ECHO "X$export_symbols_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' exclude_expsyms_CXX='`$ECHO "X$exclude_expsyms_CXX" | $Xsed -e "$delay_single_quote_subst"`' include_expsyms_CXX='`$ECHO "X$include_expsyms_CXX" | $Xsed -e "$delay_single_quote_subst"`' prelink_cmds_CXX='`$ECHO "X$prelink_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' file_list_spec_CXX='`$ECHO "X$file_list_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_action_CXX='`$ECHO "X$hardcode_action_CXX" | $Xsed -e "$delay_single_quote_subst"`' compiler_lib_search_dirs_CXX='`$ECHO "X$compiler_lib_search_dirs_CXX" | $Xsed -e "$delay_single_quote_subst"`' predep_objects_CXX='`$ECHO "X$predep_objects_CXX" | $Xsed -e "$delay_single_quote_subst"`' postdep_objects_CXX='`$ECHO "X$postdep_objects_CXX" | $Xsed -e "$delay_single_quote_subst"`' predeps_CXX='`$ECHO "X$predeps_CXX" | $Xsed -e "$delay_single_quote_subst"`' postdeps_CXX='`$ECHO "X$postdeps_CXX" | $Xsed -e "$delay_single_quote_subst"`' compiler_lib_search_path_CXX='`$ECHO "X$compiler_lib_search_path_CXX" | $Xsed -e "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # Quote evaled strings. for var in SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ deplibs_check_method \ file_magic_cmd \ AR \ AR_FLAGS \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ SHELL \ ECHO \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_wl \ lt_prog_compiler_pic \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ 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_flag_spec_ld \ hardcode_libdir_separator \ fix_srcfile_path \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ finish_eval \ old_striplib \ striplib \ compiler_lib_search_dirs \ predep_objects \ postdep_objects \ predeps \ postdeps \ compiler_lib_search_path \ LD_CXX \ compiler_CXX \ lt_prog_compiler_no_builtin_flag_CXX \ lt_prog_compiler_wl_CXX \ lt_prog_compiler_pic_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_flag_spec_ld_CXX \ hardcode_libdir_separator_CXX \ fix_srcfile_path_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 "X\\\\\$\$var"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) 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 \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ sys_lib_dlsearch_path_spec \ 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; do case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Fix-up fallback echo if it was mangled by the above quoting rules. case \$lt_ECHO in *'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\` ;; esac ac_aux_dir='$ac_aux_dir' xsi_shell='$xsi_shell' lt_shell_append='$lt_shell_append' # See if we are running on zsh, and set the options which 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' TIMESTAMP='$TIMESTAMP' 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_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 $as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; 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= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || { $as_echo "$as_me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } # 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=' ' ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /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 {' >"$tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } 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_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 $as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } 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 >>"\$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 ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$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 < "$tmp/subs1.awk" > "$tmp/subs.awk" \ || { { $as_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5 $as_echo "$as_me: error: could not setup config files machinery" >&2;} { (exit 1); exit 1; }; } _ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ 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[ ]*=/{ s/:*\$(srcdir):*/:/ s/:*\${srcdir}:*/:/ s/:*@srcdir@:*/:/ s/^\([^=]*=[ ]*\):*/\1/ s/:*$// 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_echo "$as_me:$LINENO: error: invalid tag $ac_tag" >&5 $as_echo "$as_me: error: invalid tag $ac_tag" >&2;} { (exit 1); exit 1; }; };; :[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="$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_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 $as_echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac ac_file_inputs="$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:$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 >"$tmp/stdin" \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } ;; 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" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { 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_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 $as_echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } 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:$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 "$tmp/subs.awk" >$tmp/out \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:$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 "$tmp/stdin" case $ac_file in -) cat "$tmp/out" && rm -f "$tmp/out";; *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 $as_echo "$as_me: error: could not create $ac_file" >&2;} { (exit 1); exit 1; }; } ;; :C) { $as_echo "$as_me:$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"" || # Autoconf 2.62 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"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //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' -e 's/\$U/'"$U"'/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 case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { 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_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 $as_echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ;; "libtool":C) # See if we are running on zsh, and set the options which 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 # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $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. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # 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 GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # The names of the tagged configurations supported by this script. available_tags="CXX " # ### BEGIN LIBTOOL CONFIG # Assembler program. AS=$AS # DLL creation program. DLLTOOL=$DLLTOOL # Object dumper program. OBJDUMP=$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 # 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 # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # 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 # The archiver. AR=$lt_AR AR_FLAGS=$lt_AR_FLAGS # 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 # 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 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 of the directory that contains temporary libtool files. objdir=$objdir # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that does not interpret backslashes. ECHO=$lt_ECHO # 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 # 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 # 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 # Run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # 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 # 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 # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # 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 # If ld is used when linking, flag to hardcode \$libdir into a binary # during linking. This must work even if \$libdir does not exist. hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld # 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 # Fix the shell variable \$srcfile for the compiler. fix_srcfile_path=$lt_fix_srcfile_path # 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 # 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 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 "X${COLLECT_NAMES+set}" != Xset; 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 '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) case $xsi_shell in yes) cat << \_LT_EOF >> "$cfgfile" # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac } # func_basename file func_basename () { func_basename_result="${1##*/}" } # 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" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}" } # func_stripname 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). func_stripname () { # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"} } # func_opt_split func_opt_split () { func_opt_split_opt=${1%%=*} func_opt_split_arg=${1#*=} } # func_lo2o object func_lo2o () { case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac } # func_xform libobj-or-source func_xform () { func_xform_result=${1%.*}.lo } # func_arith arithmetic-term... func_arith () { func_arith_result=$(( $* )) } # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=${#1} } _LT_EOF ;; *) # Bourne compatible functions. cat << \_LT_EOF >> "$cfgfile" # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_basename file func_basename () { func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` } # func_stripname 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). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "X${3}" \ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "X${3}" \ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; esac } # sed scripts: my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q' my_sed_long_arg='1s/^-[^=]*=//' # func_opt_split func_opt_split () { func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` } # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` } # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'` } # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "$@"` } # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` } _LT_EOF esac case $lt_shell_append in yes) cat << \_LT_EOF >> "$cfgfile" # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "$1+=\$2" } _LT_EOF ;; *) cat << \_LT_EOF >> "$cfgfile" # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "$1=\$$1\$2" } _LT_EOF ;; esac sed -n '/^# Generated shell functions inserted here/,$p' "$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 # 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 # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_CXX # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_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 # If ld is used when linking, flag to hardcode \$libdir into a binary # during linking. This must work even if \$libdir does not exist. hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_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 # Fix the shell variable \$srcfile for the compiler. fix_srcfile_path=$lt_fix_srcfile_path_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 # 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 { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5 $as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } # 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 || { (exit 1); exit 1; } fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:$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" ode-0.11.1/ou/LICENSE-LESSER.TXT0000644000076400007640000001717610776472337012427 00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. 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. ode-0.11.1/ou/test/0000777000076400007640000000000011206343456010764 500000000000000ode-0.11.1/ou/test/outest.cpp0000644000076400007640000063517210777212402012743 00000000000000/************************************************************************* * * * 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 #if _OU_COMPILER == _OU_COMPILER_MSVC #pragma warning(disable:4786) #endif #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace _OU_NAMESPACE; #include #include ////////////////////////////////////////////////////////////////////////// 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; } ////////////////////////////////////////////////////////////////////////// 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::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 g_afnTlsFeatureTestProcedures; template<> const char *const CEnumUnsortedElementArray::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 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; } ////////////////////////////////////////////////////////////////////////// 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::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 g_afnAtomicFeatureTestProcedures; template<> const char *const CEnumUnsortedElementArray::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 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; } ////////////////////////////////////////////////////////////////////////// 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::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 g_afnAtomicFlagsFeatureTestProcedures; template<> const char *const CEnumUnsortedElementArray::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 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; } ////////////////////////////////////////////////////////////////////////// typedef CSimpleFlagsTemplate 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::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 g_afnSimpleFlags64FeatureTestProcedures; template<> const char *const CEnumUnsortedElementArray::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 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::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 g_afnSimpleFlags32FeatureTestProcedures; template<> const char *const CEnumUnsortedElementArray::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 g_aszSimpleFlags32FeatureTestNames; bool TestSimpleFlags32(unsigned int &nOutSuccessCount, unsigned int &nOutTestCount) { return TestSubsystem(nOutSuccessCount, nOutTestCount, OSF32__MAX, g_aszSimpleFlags32FeatureTestNames.GetStoragePointer(), g_afnSimpleFlags32FeatureTestProcedures.GetStoragePointer()); } ////////////////////////////////////////////////////////////////////////// typedef CSimpleFlagsTemplate 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::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 g_afnSimpleFlags16FeatureTestProcedures; template<> const char *const CEnumUnsortedElementArray::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 g_aszSimpleFlags16FeatureTestNames; bool TestSimpleFlags16(unsigned int &nOutSuccessCount, unsigned int &nOutTestCount) { return TestSubsystem(nOutSuccessCount, nOutTestCount, OSF16__MAX, g_aszSimpleFlags16FeatureTestNames.GetStoragePointer(), g_afnSimpleFlags16FeatureTestProcedures.GetStoragePointer()); } ////////////////////////////////////////////////////////////////////////// typedef CSimpleFlagsTemplate 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::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 g_afnSimpleFlags8FeatureTestProcedures; template<> const char *const CEnumUnsortedElementArray::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 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::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 g_afnFlagsDefineFeatureTestProcedures; template<>const char *const CEnumUnsortedElementArray::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 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::m_aetElementArray[] = { 1, // ATE_FIRSTELEMENT, 3, // ATE_SECONDELEMENT, 2, // ATE_THIRDELEMENT, }; static const CEnumUnsortedElementArray g_ai_IntUnsortedArray; template<> const int CEnumSortedElementArray::m_aetElementArray[] = { 1, // ATE_FIRSTELEMENT, 2, // ATE_SECONDELEMENT, 3, // ATE_THIRDELEMENT, }; static const CEnumSortedElementArray 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::m_aetElementArray[] = { "first", "third", "second", }; static const CEnumUnsortedElementArray g_aszStringUnsortedArray; template<> const char *const CEnumSortedElementArray::m_aetElementArray[] = { "first", "second", "third", }; static const CEnumSortedElementArray 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::m_aetElementArray[] = { &TestEnumArrays_UnsortedArray, // ORF_UNSORTEDARRAY, &TestEnumArrays_SortedArray, // ORF_SORTEDARRAY, }; static const CEnumUnsortedElementArray g_afnEnumArrayFeatureTestProcedures; template<> const char *const CEnumUnsortedElementArray::m_aetElementArray[] = { "Unsorted Array", // ORF_UNSORTEDARRAY, "Sorted Array", // ORF_SORTEDARRAY, }; static const CEnumUnsortedElementArray 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::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 g_afnTemplateFeatureTestProcedures; template<> const char *const CEnumUnsortedElementArray::m_aetElementArray[] = { "Prefix Increment", // OTF_PREFIXINCREMENT, "Postfix Increment", // OTF_POSTFIXINCREMENT, "Prefix Decrement", // OTF_PREFIXDECREMENT, "Postfix Decrement", // OTF_POSTFIXDECREMENT, "IsEmptySz", // OTF_ISEMPTYSZ, }; static const CEnumUnsortedElementArray g_aszTemplateFeatureTestNames; bool TestTemplates(unsigned int &nOutSuccessCount, unsigned int &nOutTestCount) { return TestSubsystem(nOutSuccessCount, nOutTestCount, OTF__MAX, g_aszTemplateFeatureTestNames.GetStoragePointer(), g_afnTemplateFeatureTestProcedures.GetStoragePointer()); } ////////////////////////////////////////////////////////////////////////// typedef CTypeSimpleWrapper 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::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 g_afnTypeWrapperFeatureTestProcedures; template<> const char *const CEnumUnsortedElementArray::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 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::m_aetElementArray[] = { &TestCustomizations_Asserts, // OCF_ASSERTS, &TestCustomizations_MemMgr, // OCF_MEMMGR, }; static const CEnumUnsortedElementArray g_afnCustomizationFeatureTestProcedures; template<> const char *const CEnumUnsortedElementArray::m_aetElementArray[] = { "Asserts", // OCF_ASSERTS, "Memory Manager", // OCF_MEMMGR, }; static const CEnumUnsortedElementArray 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::m_aetElementArray[] = { &TestMallocs_Allocate, // OLF_ALLOCATE, &TestMallocs_Reallocate, // OLF_REALLOCATE, &TestMallocs_Deallocate, // OLF_DEALLOCATE, }; static const CEnumUnsortedElementArray g_afnMallocFeatureTestProcedures; template<> const char *const CEnumUnsortedElementArray::m_aetElementArray[] = { "AllocateMemoryBlock", // OLF_ALLOCATE, "ReallocateMemoryBlock", // OLF_REALLOCATE, "FreeMemoryBlock", // OLF_DEALLOCATE, }; static const CEnumUnsortedElementArray 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::m_aetElementArray[] = { &TestAsserts_Assert, // OEF_ASSERT, &TestAsserts_Verify, // OEF_VERIFY, &TestAsserts_Check, // OEF_CHECK, }; static const CEnumUnsortedElementArray g_afnAssertFeatureTestProcedures; template<> const char *const CEnumUnsortedElementArray::m_aetElementArray[] = { "OU_ASSERT", // OEF_ASSERT, "OU_VERIFY", // OEF_VERIFY, "OU_CHECK", // OEF_CHECK, }; static const CEnumUnsortedElementArray 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 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_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::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 g_afnIntTypeFeatureTestProcedures; template<> const char *const CEnumUnsortedElementArray::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 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::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 g_afnMacroFeatureTestProcedures; template<> const char *const CEnumUnsortedElementArray::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 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::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 }; static const CEnumSortedElementArray g_ai_TargetOrderCheck; template<> const char *const CEnumUnsortedElementArray::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 }; static const CEnumUnsortedElementArray g_aszOSNames; // Verifies that bits order is not changed template<> int const CEnumSortedElementArray::m_aetElementArray[] = { _OU_TARGET_BITS_32, // _OU_TARGET_BITS_32 _OU_TARGET_BITS_64, // _OU_TARGET_BITS_64 }; static const CEnumSortedElementArray g_ai_BitsOrderCheck; template<> const char *const CEnumUnsortedElementArray::m_aetElementArray[] = { "32", // _OU_TARGET_BITS_32 "64", // _OU_TARGET_BITS_64 }; static const CEnumUnsortedElementArray g_aszBitsNames; // Verifies that architectures order is not changed template<> int const CEnumSortedElementArray::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 }; static const CEnumSortedElementArray g_ai_ArchitecturesOrderCheck; template<> const char *const CEnumUnsortedElementArray::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 }; static const CEnumUnsortedElementArray g_aszArchitecturesNames; // Verifies that compilers order is not changed template<> int const CEnumSortedElementArray::m_aetElementArray[] = { _OU_COMPILER__OTHER, // _OU_COMPILER__OTHER, _OU_COMPILER_GCC, // _OU_COMPILER_GCC, _OU_COMPILER_MSVC, // _OU_COMPILER_MSVC, }; static const CEnumSortedElementArray g_ai_CompilersOrderCheck; template<> const char *const CEnumUnsortedElementArray::m_aetElementArray[] = { "UNKNOWN", // _OU_COMPILER__OTHER, "GCC", // _OU_COMPILER_GCC, "MSVC", // _OU_COMPILER_MSVC, }; static const CEnumUnsortedElementArray g_aszCompilersNames; // Verifies that compiler versions order is not changed template<> int const CEnumSortedElementArray::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 g_ai_CompilersVersionOrderCheck; template<> const char *const CEnumUnsortedElementArray::m_aetElementArray[] = { "OTHER", // _OU_COMPILER_VERSION__OTHER, "MSVC1998", // _OU_COMPILER_VERSION_MSVC1998, "GCC LESS THAN 4.0", // _OU_COMPILER_VERSION_GCCLT4, }; static const CEnumUnsortedElementArray 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 pre definition: %s\n", TESTPLATFORM_TEFINITION_TEXT(=_OU_ALWAYSINLINE_PRE)); printf("Alwaysinline in definition: %s\n", TESTPLATFORM_TEFINITION_TEXT(=_OU_ALWAYSINLINE_IN)); 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, OST_ATOMIC, OST_FLAGSDEFINES, OST_ATOMICFLAGS, OST_SIMPLEFLAGS64, OST_SIMPLEFLAGS32, OST_SIMPLEFLAGS16, OST_SIMPLEFLAGS8, OST_TLS, OST_PLATFORM, OST__MAX, }; typedef bool (*COUSubsystemTestProcedure)(unsigned int &nOutSuccessCount, unsigned int &nOutTestCount); template<> COUSubsystemTestProcedure const CEnumUnsortedElementArray::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, &TestAtomic, // OST_ATOMIC, &TestFlagsDefines, // OST_FLAGSDEFINES, &TestAtomicFlags, // OST_ATOMICFLAGS, &TestSimpleFlags64, // OST_SIMPLEFLAGS64, &TestSimpleFlags32, // OST_SIMPLEFLAGS32, &TestSimpleFlags16, // OST_SIMPLEFLAGS16, &TestSimpleFlags8, // OST_SIMPLEFLAGS8, &TestTLS, // OST_TLS, &TestPlatform, // OST_PLATFORM, }; static const CEnumUnsortedElementArray g_afnOUSubsystemTestProcedures; template<> const char *const CEnumUnsortedElementArray::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, "Atomic", // OST_ATOMIC, "FlagsDefines", // OST_FLAGSDEFINES, "AtomicFlags", // OST_ATOMICFLAGS, "SimpleFlags64", // OST_SIMPLEFLAGS64, "SimpleFlags32", // OST_SIMPLEFLAGS32, "SimpleFlags16", // OST_SIMPLEFLAGS16, "SimpleFlags8", // OST_SIMPLEFLAGS8, "TLS", // OST_TLS, "Platform", // OST_PLATFORM, }; static const CEnumUnsortedElementArray 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; } ode-0.11.1/ou/test/Makefile.in0000644000076400007640000003205411206343422012742 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in 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) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = am_outest_OBJECTS = outest.$(OBJEXT) outest_OBJECTS = $(am_outest_OBJECTS) outest_DEPENDENCIES = $(top_builddir)/src/ou/libou.la DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/../depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(outest_SOURCES) DIST_SOURCES = $(outest_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ 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@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ OU_NAMESPACE = @OU_NAMESPACE@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ 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_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@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ 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'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign test/Makefile .PRECIOUS: 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 clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; for p in $$list; do \ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ echo " rm -f $$p $$f"; \ rm -f $$p $$f ; \ done outest$(EXEEXT): $(outest_OBJECTS) $(outest_DEPENDENCIES) @rm -f outest$(EXEEXT) $(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@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-am info-am: install-data-am: install-dvi: install-dvi-am 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 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 all all-am check check-am clean \ clean-checkPROGRAMS clean-generic clean-libtool ctags \ 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 uninstall uninstall-am # 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: ode-0.11.1/ou/test/Makefile.am0000644000076400007640000000033411005227077012731 00000000000000AM_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 ode-0.11.1/ou/LICENSE.TXT0000644000076400007640000010575710776472337011437 00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. 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. Copyright (C) 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 . 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: Copyright (C) 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 . 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 . ode-0.11.1/ou/LICENSE-BSD.TXT0000644000076400007640000000321510776472337012027 00000000000000 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. ode-0.11.1/ou/bootstrap0000755000076400007640000000040711036136204011655 00000000000000#!/bin/sh aclocal --force || exit 1 # on Mac libtoolize is called glibtoolize LIBTOOLIZE=libtoolize if [ `uname -s` = Darwin ]; then LIBTOOLIZE=glibtoolize fi $LIBTOOLIZE -f --automake -c || exit 1 autoconf -f || exit 1 automake -a -c -f --foreign || exit 1 ode-0.11.1/ou/include/0000777000076400007640000000000011206343456011430 500000000000000ode-0.11.1/ou/include/ou/0000777000076400007640000000000011206343456012053 500000000000000ode-0.11.1/ou/include/ou/macros.h0000644000076400007640000000704710776643320013440 00000000000000/************************************************************************* * * * 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. * * * *************************************************************************/ #ifndef __OU_MACROS_H_INCLUDED #define __OU_MACROS_H_INCLUDED #include ////////////////////////////////////////////////////////////////////////// // 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_SIZE(Size, Alignment) (((size_t)(Size) + ((Alignment) - 1)) & ~((size_t)((Alignment) - 1))) ////////////////////////////////////////////////////////////////////////// // 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 for it to work. * I do not include the header automaticaly to keep * 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 ode-0.11.1/ou/include/ou/atomicflags.h0000644000076400007640000003410510777211273014437 00000000000000/************************************************************************* * * * 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. * * * *************************************************************************/ #ifndef __OU_ATOMICFLAGS_H_INCLUDED #define __OU_ATOMICFLAGS_H_INCLUDED #include #include #include #include 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_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_METHOD /*void */AssignFlagsAllValues(atomicord32 aoFlagsValue) { AtomicExchange(&m_aoFlagsValue, aoFlagsValue); } _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_METHOD /*atomicord32 */QueryFlagsAllValues() const { return m_aoFlagsValue; } // Can operate both on single flag and flag set _OU_ALWAYSINLINE_PRE void _OU_ALWAYSINLINE_IN _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_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_METHOD /*void */SignalFlagsMaskValue(atomicord32 aoFlagsMask) { AtomicOrNoResult(&m_aoFlagsValue, aoFlagsMask); } // Can operate both on single flag and flag set _OU_ALWAYSINLINE_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_METHOD /*void */DropFlagsMaskValue(atomicord32 aoFlagsMask) { AtomicAndNoResult(&m_aoFlagsValue, ~aoFlagsMask); } // Can operate on single flag only // Returns previous flag value _OU_ALWAYSINLINE_PRE bool _OU_ALWAYSINLINE_IN _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_PRE bool _OU_ALWAYSINLINE_IN _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_PRE atomicord32 _OU_ALWAYSINLINE_IN _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_PRE bool _OU_ALWAYSINLINE_IN _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_PRE bool _OU_ALWAYSINLINE_IN _OU_CONVENTION_METHOD /*bool */GetFlagsMaskValue(atomicord32 aoFlagsMask) const { return (m_aoFlagsValue & aoFlagsMask) != (atomicord32)0; } // Returns subset of flags _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN /*atomicord32 */QueryFlagsByMask(atomicord32 aoFlagsMask) const { return (m_aoFlagsValue & aoFlagsMask); } public: // Signal only flag out of mask _OU_ALWAYSINLINE_PRE bool _OU_ALWAYSINLINE_IN _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_PRE void _OU_ALWAYSINLINE_IN _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_PRE void _OU_ALWAYSINLINE_IN _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_PRE void _OU_ALWAYSINLINE_IN _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_PRE bool _OU_ALWAYSINLINE_IN _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_PRE bool _OU_ALWAYSINLINE_IN _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_PRE bool _OU_ALWAYSINLINE_IN _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_PRE bool _OU_ALWAYSINLINE_IN _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_PRE bool _OU_ALWAYSINLINE_IN _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_PRE void _OU_ALWAYSINLINE_IN _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_PRE void _OU_ALWAYSINLINE_IN _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_PRE atomicord32 _OU_ALWAYSINLINE_IN _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_PRE bool _OU_ALWAYSINLINE_IN _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_PRE void _OU_ALWAYSINLINE_IN _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_PRE unsigned int _OU_ALWAYSINLINE_IN _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 ode-0.11.1/ou/include/ou/flagsdefines.h0000644000076400007640000000504610776643320014603 00000000000000/************************************************************************* * * * 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. * * * *************************************************************************/ #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 ode-0.11.1/ou/include/ou/customization.h0000644000076400007640000001240210776643320015053 00000000000000/************************************************************************* * * * 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. * * * *************************************************************************/ #ifndef __OU_CUSTOMIZATION_H_INCLUDED #define __OU_CUSTOMIZATION_H_INCLUDED #include #include #include #include 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_PRE CAssertionFailedProcedure _OU_ALWAYSINLINE_IN _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_PRE CMemoryAllocationProcedure _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*CMemoryAllocationProcedure */GetMemoryAllocationCustomProcedure() { return g_fnMemoryAllocationProcedure; } static _OU_ALWAYSINLINE_PRE CMemoryReallocationProcedure _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*CMemoryReallocationProcedure */GetMemoryReallocationCustomProcedure() { return g_fnMemoryReallocationProcedure; } static _OU_ALWAYSINLINE_PRE CMemoryDeallocationProcedure _OU_ALWAYSINLINE_IN _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 ode-0.11.1/ou/include/ou/assert.h0000644000076400007640000001757111101637101013437 00000000000000/************************************************************************* * * * 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. * * * *************************************************************************/ #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 #include /** * \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)) \ || (*(int *)0 = 0)) #else // #if !defined(NDEBUG) #include #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)) \ || (_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 || (*(int *)0 = 0)); \ } #endif // #if !defined(NDEBUG) #endif // #ifndef __OU_ASSERT_H_INCLUDED ode-0.11.1/ou/include/ou/typewrapper.h0000644000076400007640000001534710776643320014540 00000000000000/************************************************************************* * * * 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. * * * *************************************************************************/ #ifndef __OU_TYPEWRAPPER_H_INCLUDED #define __OU_TYPEWRAPPER_H_INCLUDED #include #include BEGIN_NAMESPACE_OU(); template 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; } private: ContainedType m_ctValue; }; template _OU_INLINE bool _OU_CONVENTION_API operator ==(const CTypeSimpleWrapper &twLeftWrapper, const ContainedType &ctRightValue) { return (const ContainedType &)twLeftWrapper == ctRightValue; } template _OU_INLINE bool _OU_CONVENTION_API operator ==(const ContainedType &ctLeftValue, const CTypeSimpleWrapper &twRightWrapper) { return ctLeftValue == (const ContainedType &)twRightWrapper; } template _OU_INLINE bool _OU_CONVENTION_API operator !=(const CTypeSimpleWrapper &twLeftWrapper, const ContainedType &ctRightValue) { return !(twLeftWrapper == ctRightValue); } template _OU_INLINE bool _OU_CONVENTION_API operator !=(const ContainedType &ctLeftValue, const CTypeSimpleWrapper &twRightWrapper) { return !(ctLeftValue == twRightWrapper); } template _OU_INLINE bool _OU_CONVENTION_API operator <(const CTypeSimpleWrapper &twLeftWrapper, const ContainedType &ctRightValue) { return (const ContainedType &)twLeftWrapper < ctRightValue; } template _OU_INLINE bool _OU_CONVENTION_API operator <(const ContainedType &ctLeftValue, const CTypeSimpleWrapper &twRightWrapper) { return ctLeftValue < (const ContainedType &)twRightWrapper; } template _OU_INLINE bool _OU_CONVENTION_API operator >(const CTypeSimpleWrapper &twLeftWrapper, const ContainedType &ctRightValue) { return ctRightValue < twLeftWrapper; } template _OU_INLINE bool _OU_CONVENTION_API operator >(const ContainedType &ctLeftValue, const CTypeSimpleWrapper &twRightWrapper) { return twRightWrapper < ctLeftValue; } template _OU_INLINE bool _OU_CONVENTION_API operator <=(const CTypeSimpleWrapper &twLeftWrapper, const ContainedType &ctRightValue) { return !(ctRightValue < twLeftWrapper); } template _OU_INLINE bool _OU_CONVENTION_API operator <=(const ContainedType &ctLeftValue, const CTypeSimpleWrapper &twRightWrapper) { return !(twRightWrapper < ctLeftValue); } template _OU_INLINE bool _OU_CONVENTION_API operator >=(const CTypeSimpleWrapper &twLeftWrapper, const ContainedType &ctRightValue) { return !(twLeftWrapper < ctRightValue); } template _OU_INLINE bool _OU_CONVENTION_API operator >=(const ContainedType &ctLeftValue, const CTypeSimpleWrapper &twRightWrapper) { return !(ctLeftValue < twRightWrapper); } END_NAMESPACE_OU(); #endif // #ifndef __OU_TYPEWRAPPER_H_INCLUDED ode-0.11.1/ou/include/ou/templates.h0000644000076400007640000001132110776643320014140 00000000000000/************************************************************************* * * * 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. * * * *************************************************************************/ #ifndef __OU_TEMPLATES_H_INCLUDED #define __OU_TEMPLATES_H_INCLUDED #include #include BEGIN_NAMESPACE_OU(); ////////////////////////////////////////////////////////////////////////// // Enumerated type increment/decrement operator templates /* * Implementation Note: * __attribute__((always_inline)) seems to be unimplemented for templates in GCC */ template _OU_INLINE EnumType &_OU_CONVENTION_API operator ++(EnumType &Value) { if (sizeof(EnumType) == sizeof(unsigned char)) { return (EnumType &)(++((unsigned char &)Value)); } else if (sizeof(EnumType) == sizeof(unsigned short)) { return (EnumType &)(++((unsigned short &)Value)); } else if (sizeof(EnumType) == sizeof(unsigned int)) { return (EnumType &)(++((unsigned int &)Value)); } else { // Compiler has to warn on type cast in case of type size mismatch return (EnumType &)(++((unsigned long &)Value)); } } template _OU_INLINE EnumType _OU_CONVENTION_API operator ++(EnumType &Value, int) { if (sizeof(EnumType) == sizeof(unsigned char)) { return (EnumType)(((unsigned char &)Value)++); } else if (sizeof(EnumType) == sizeof(unsigned short)) { return (EnumType)(((unsigned short &)Value)++); } else if (sizeof(EnumType) == sizeof(unsigned int)) { return (EnumType)(((unsigned int &)Value)++); } else { // Compiler has to warn on type cast in case of type size mismatch return (EnumType)(((unsigned long &)Value)++); } } template _OU_INLINE EnumType &_OU_CONVENTION_API operator --(EnumType &Value) { if (sizeof(EnumType) == sizeof(unsigned char)) { return (EnumType &)(--((unsigned char &)Value)); } else if (sizeof(EnumType) == sizeof(unsigned short)) { return (EnumType &)(--((unsigned short &)Value)); } else if (sizeof(EnumType) == sizeof(unsigned int)) { return (EnumType &)(--((unsigned int &)Value)); } else { // Compiler has to warn on type cast in case of type size mismatch return (EnumType &)(--((unsigned long &)Value)); } } template _OU_INLINE EnumType _OU_CONVENTION_API operator --(EnumType &Value, int) { if (sizeof(EnumType) == sizeof(unsigned char)) { return (EnumType)(((unsigned char &)Value)--); } else if (sizeof(EnumType) == sizeof(unsigned short)) { return (EnumType)(((unsigned short &)Value)--); } else if (sizeof(EnumType) == sizeof(unsigned int)) { return (EnumType)(((unsigned int &)Value)--); } else { // Compiler has to warn on type cast in case of type size mismatch return (EnumType)(((unsigned long &)Value)--); } } ////////////////////////////////////////////////////////////////////////// // Empty "signed zero" check template template _OU_INLINE bool _OU_CONVENTION_API IsEmptySz(const ValueType *szLine) { return !szLine || !(*szLine); } END_NAMESPACE_OU(); #endif // #ifndef __OU_TEMPLATES_H_INCLUDED ode-0.11.1/ou/include/ou/Makefile.in0000644000076400007640000002216111206343422014027 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in 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) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ 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@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ OU_NAMESPACE = @OU_NAMESPACE@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ 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_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@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ 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 \ 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'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign include/ou/Makefile .PRECIOUS: 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 mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags: TAGS TAGS: ctags: CTAGS CTAGS: 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-am info-am: install-data-am: install-dvi: install-dvi-am 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 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 \ 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 uninstall uninstall-am # 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: ode-0.11.1/ou/include/ou/namespace.h0000644000076400007640000000421710776643320014104 00000000000000/************************************************************************* * * * 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. * * * *************************************************************************/ #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 ode-0.11.1/ou/include/ou/platform.h0000644000076400007640000002057511000406540013757 00000000000000/************************************************************************* * * * 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. * * * *************************************************************************/ #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__MAX 7 #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__MAX 7 ////////////////////////////////////////////////////////////////////////// #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__) #define _OU_TARGET_OS _OU_TARGET_OS_MAC #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 #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_PRE__DEFINITION inline #define _OU_ALWAYSINLINE_IN__DEFINITION __attribute__((always_inline)) #elif _OU_COMPILER == _OU_COMPILER_MSVC #define _OU_ALWAYSINLINE_PRE__DEFINITION __forceinline #define _OU_ALWAYSINLINE_IN__DEFINITION #else // if _OU_COMPILER == _OU_COMPILER_OTHER #define _OU_ALWAYSINLINE_PRE__DEFINITION inline #define _OU_ALWAYSINLINE_IN__DEFINITION #endif // #if _OU_COMPILER == ... #if defined(_DEBUG) #define _OU_ALWAYSINLINE_PRE inline #define _OU_ALWAYSINLINE_IN #define _OU_INLINE inline #else // #if !defined(_DEBUG) #define _OU_ALWAYSINLINE_PRE _OU_ALWAYSINLINE_PRE__DEFINITION #define _OU_ALWAYSINLINE_IN _OU_ALWAYSINLINE_IN__DEFINITION #define _OU_INLINE inline #endif // #if !defined(_DEBUG) #endif // #if !defined(__OU_INLINES_DEFINED) #endif // #ifndef __OU_PLATFORM_H_INCLUDED ode-0.11.1/ou/include/ou/malloc.h0000644000076400007640000000443010776643320013414 00000000000000/************************************************************************* * * * 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. * * * *************************************************************************/ #ifndef __OU_MALLOC_H_INCLUDED #define __OU_MALLOC_H_INCLUDED #include #include #include 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 ode-0.11.1/ou/include/ou/enumarrays.h0000644000076400007640000002023610776643320014335 00000000000000/************************************************************************* * * * 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. * * * *************************************************************************/ #ifndef __OU_ENUMARRAYS_H_INCLUDED #define __OU_ENUMARRAYS_H_INCLUDED #include #include #include #include BEGIN_NAMESPACE_OU(); ////////////////////////////////////////////////////////////////////////// // Helper template definitions template struct CTypeStandardEqual { _OU_INLINE bool _OU_CONVENTION_METHOD operator ()(const ElementType &etLeftElement, const ElementType &etRightElement) const { return etLeftElement == etRightElement; } }; template 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 > 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_PRE const EnumType _OU_ALWAYSINLINE_IN _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_PRE const ElementType &_OU_ALWAYSINLINE_IN _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_PRE bool _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*bool */IsValidDecode(const EnumType &etValue) { return etValue != EnumMax; } static _OU_ALWAYSINLINE_PRE const ElementType *_OU_ALWAYSINLINE_IN _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 > 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_PRE const EnumType _OU_ALWAYSINLINE_IN _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_PRE const ElementType &_OU_ALWAYSINLINE_IN _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_PRE bool _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*bool */IsValidDecode(const EnumType &etValue) { return etValue != EnumMax; } static _OU_ALWAYSINLINE_PRE const ElementType *_OU_ALWAYSINLINE_IN _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 ode-0.11.1/ou/include/ou/atomic.h0000644000076400007640000015274711101637101013417 00000000000000/************************************************************************* * * * 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. * * * *************************************************************************/ #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 #include #include /** * \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 pointer 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 pointer 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 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 pointer to by \a paoDestination. * * The function performs atomic exchange of \a aoExchange value with memory location * pointer 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 pointer to by \a paoDestination. * * The function computes sum of \a aoAddend and location pointer 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 pointer 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 pointer 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 pointer to by \a paoDestination before the operation * was performed. Common applications are object state manipulations. * \see AtomicAnd * \see AtomicOr */ /** * \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 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 #include BEGIN_NAMESPACE_OU(); typedef LONG 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 atomicord32 #define __ou_intlck_target_t volatile atomicord32 * #define __ou_xchgadd_target_t LPLONG #define __ou_cmpxchg_value_t atomicord32 #define __ou_cmpxchg_target_t volatile atomicord32 * #endif // #if _OU_COMPILER == _OU_COMPILER_GCC #define __OU_ATOMIC_ORD32_FUNCTIONS_DEFINED static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicIncrement(volatile atomicord32 *paoDestination) { return ::InterlockedIncrement((__ou_intlck_target_t)paoDestination); } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicDecrement(volatile atomicord32 *paoDestination) { return ::InterlockedDecrement((__ou_intlck_target_t)paoDestination); } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange) { return ::InterlockedExchange((__ou_intlck_target_t)paoDestination, aoExchange); } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend) { return ::InterlockedExchangeAdd((__ou_xchgadd_target_t)paoDestination, aoAddend); } static _OU_ALWAYSINLINE_PRE bool _OU_ALWAYSINLINE_IN _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_PRE atomicord32 _OU_ALWAYSINLINE_IN _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_PRE atomicord32 _OU_ALWAYSINLINE_IN _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_PRE atomicord32 _OU_ALWAYSINLINE_IN _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_PRE atomicptr _OU_ALWAYSINLINE_IN _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_PRE bool _OU_ALWAYSINLINE_IN _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) } #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 #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_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicIncrement(volatile atomicord32 *paoDestination) { return (atomic_add_value(paoDestination, 1U) + 1U); } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicDecrement(volatile atomicord32 *paoDestination) { return (atomic_sub_value(paoDestination, 1U) - 1U); } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange) { return _smp_xchg(paoDestination, aoExchange); } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend) { return atomic_add_value(paoDestination, aoAddend); } static _OU_ALWAYSINLINE_PRE bool _OU_ALWAYSINLINE_IN _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_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) { return atomic_clr_value(paoDestination, ~aoBitMask); } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) { return atomic_set_value(paoDestination, aoBitMask); } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _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_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*void */AtomicIncrementNoResult(volatile atomicord32 *paoDestination) { atomic_add(paoDestination, 1U); } static _OU_ALWAYSINLINE_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*void */AtomicDecrementNoResult(volatile atomicord32 *paoDestination) { atomic_sub(paoDestination, 1U); } static _OU_ALWAYSINLINE_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*void */AtomicExchangeAddNoResult(volatile atomicord32 *paoDestination, atomicord32 aoAddend) { atomic_add(paoDestination, aoAddend); } static _OU_ALWAYSINLINE_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*void */AtomicAndNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) { atomic_clr(paoDestination, ~aoBitMask); } static _OU_ALWAYSINLINE_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*void */AtomicOrNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) { atomic_set(paoDestination, aoBitMask); } static _OU_ALWAYSINLINE_PRE void _OU_ALWAYSINLINE_IN _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 #if MAC_OS_X_VERSION >= 1040 END_NAMESPACE_OU(); #include BEGIN_NAMESPACE_OU(); typedef int32_t atomicord32; typedef void *atomicptr; #define __ou_bitmsk_target_t volatile uint32_t * #define __OU_ATOMIC_ORD32_FUNCTIONS_DEFINED static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicIncrement(volatile atomicord32 *paoDestination) { return OSAtomicIncrement32Barrier(paoDestination); } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicDecrement(volatile atomicord32 *paoDestination) { return OSAtomicDecrement32Barrier(paoDestination); } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange) { 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, aoExchange, paoDestination); !bSwapExecuted; bSwapExecuted = OSAtomicCompareAndSwap32(aoOldValue, aoExchange, paoDestination)) { aoOldValue = *paoDestination; } return aoOldValue; } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend) { return (OSAtomicAdd32Barrier(aoAddend, paoDestination) - aoAddend); } static _OU_ALWAYSINLINE_PRE bool _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*bool */AtomicCompareExchange(volatile atomicord32 *paoDestination, atomicord32 aoComparand, atomicord32 aoExchange) { return OSAtomicCompareAndSwap32Barrier(aoComparand, aoExchange, paoDestination); } #if MAC_OS_X_VERSION >= 1050 #define __OU_ATOMIC_BIT_FUNCTIONS_DEFINED static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) { return OSAtomicAnd32OrigBarrier(aoBitMask, (__ou_bitmsk_target_t)paoDestination); } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) { return OSAtomicOr32OrigBarrier(aoBitMask, (__ou_bitmsk_target_t)paoDestination); } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _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_PRE atomicord32 _OU_ALWAYSINLINE_IN _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_PRE atomicord32 _OU_ALWAYSINLINE_IN _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_PRE atomicord32 _OU_ALWAYSINLINE_IN _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_PRE atomicptr _OU_ALWAYSINLINE_IN _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_PRE bool _OU_ALWAYSINLINE_IN _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_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*void */AtomicIncrementNoResult(volatile atomicord32 *paoDestination) { OSAtomicIncrement32Barrier(paoDestination); } static _OU_ALWAYSINLINE_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*void */AtomicDecrementNoResult(volatile atomicord32 *paoDestination) { OSAtomicDecrement32Barrier(paoDestination); } static _OU_ALWAYSINLINE_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*void */AtomicExchangeAddNoResult(volatile atomicord32 *paoDestination, atomicord32 aoAddend) { OSAtomicAdd32Barrier(aoAddend, paoDestination); } static _OU_ALWAYSINLINE_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*void */AtomicAndNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) { OSAtomicAnd32Barrier(aoBitMask, (__ou_bitmsk_target_t)paoDestination); } static _OU_ALWAYSINLINE_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*void */AtomicOrNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) { OSAtomicOr32Barrier(aoBitMask, (__ou_bitmsk_target_t)paoDestination); } static _OU_ALWAYSINLINE_PRE void _OU_ALWAYSINLINE_IN _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 #endif // #if _OU_TARGET_OS == _OU_TARGET_OS_MAC ////////////////////////////////////////////////////////////////////////// // AIX implementation #if _OU_TARGET_OS == _OU_TARGET_OS_AIX END_NAMESPACE_OU(); #include BEGIN_NAMESPACE_OU(); typedef int atomicord32; typedef void *atomicptr; #define __OU_ATOMIC_ORD32_FUNCTIONS_DEFINED static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicIncrement(volatile atomicord32 *paoDestination) { return (fetch_and_add((atomic_p)paoDestination, 1) + 1); } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicDecrement(volatile atomicord32 *paoDestination) { return (fetch_and_add((atomic_p)paoDestination, -1) - 1); } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange) { atomicord32 aoOldValue = *paoDestination; while (!compare_and_swap((atomic_p)paoDestination, &aoOldValue, aoExchange)) { // Do nothing } return aoOldValue; } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend) { return fetch_and_add((atomic_p)paoDestination, aoAddend); } static _OU_ALWAYSINLINE_PRE bool _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*bool */AtomicCompareExchange(volatile atomicord32 *paoDestination, atomicord32 aoComparand, atomicord32 aoExchange) { atomicord32 aoOldValue = aoComparand; return compare_and_swap((atomic_p)paoDestination, &aoOldValue, aoExchange); } #define __OU_ATOMIC_BIT_FUNCTIONS_DEFINED static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) { return fetch_and_and((atomic_p)paoDestination, aoBitMask); } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) { return fetch_and_or((atomic_p)paoDestination, aoBitMask); } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicXor(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) { volatile atomicord32 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_PRE atomicptr _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicptr */AtomicExchangePointer(volatile atomicptr *papDestination, atomicptr apExchange) { long liOldValue = (long)*papDestination; while (!compare_and_swaplp((atomic_l)papDestination, &liOldValue, (long)apExchange)) { // Do nothing } return liOldValue; } static _OU_ALWAYSINLINE_PRE bool _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*bool */AtomicCompareExchangePointer(volatile atomicptr *papDestination, atomicptr apComparand, atomicptr apExchange) { long liOldValue = (long)apComparand; return compare_and_swaplp((atomic_l)papDestination, &liOldValue, (long)apExchange); } #endif // #if _OU_TARGET_BITS == _OU_TARGET_BITS_64 #endif // #if _OU_TARGET_OS == _OU_TARGET_OS_AIX ////////////////////////////////////////////////////////////////////////// // SunOS implementation #if _OU_TARGET_OS == _OU_TARGET_OS_SUNOS END_NAMESPACE_OU(); #include BEGIN_NAMESPACE_OU(); typedef uint32_t atomicord32; typedef void *atomicptr; #define __OU_ATOMIC_ORD32_FUNCTIONS_DEFINED static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicIncrement(volatile atomicord32 *paoDestination) { return atomic_inc_32_nv(paoDestination); } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicDecrement(volatile atomicord32 *paoDestination) { return atomic_dec_32_nv(paoDestination); } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange) { return atomic_swap_32(paoDestination, aoExchange); } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend) { return (atomic_add_32_nv(paoDestination, aoAddend) - aoAddend); } static _OU_ALWAYSINLINE_PRE bool _OU_ALWAYSINLINE_IN _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_PRE atomicord32 _OU_ALWAYSINLINE_IN _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_PRE atomicord32 _OU_ALWAYSINLINE_IN _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_PRE atomicord32 _OU_ALWAYSINLINE_IN _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_PRE atomicptr _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicptr */AtomicExchangePointer(volatile atomicptr *papDestination, atomicptr apExchange) { return atomic_swap_ptr(papDestination, apExchange); } static _OU_ALWAYSINLINE_PRE bool _OU_ALWAYSINLINE_IN _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_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*void */AtomicIncrementNoResult(volatile atomicord32 *paoDestination) { atomic_inc_32(paoDestination); } static _OU_ALWAYSINLINE_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*void */AtomicDecrementNoResult(volatile atomicord32 *paoDestination) { atomic_dec_32(paoDestination); } static _OU_ALWAYSINLINE_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*void */AtomicExchangeAddNoResult(volatile atomicord32 *paoDestination, atomicord32 aoAddend) { atomic_add_32(paoDestination, aoAddend); } static _OU_ALWAYSINLINE_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*void */AtomicAndNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) { atomic_and_32(paoDestination, aoBitMask); } static _OU_ALWAYSINLINE_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*void */AtomicOrNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) { atomic_or_32(paoDestination, aoBitMask); } static _OU_ALWAYSINLINE_PRE void _OU_ALWAYSINLINE_IN _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 // x86 assembler implementation for i486 must be engaged explicitly #if 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_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicIncrement(volatile atomicord32 *paoDestination) { register atomicord32 aoResult = 1; asm volatile ( "lock; xaddl %2, %0;" : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination), "=a" (aoResult) : "1" (aoResult) : "memory"); return aoResult + 1; } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicDecrement(volatile atomicord32 *paoDestination) { register atomicord32 aoResult = (atomicord32)(-1); asm volatile ( "lock; xaddl %2, %0;" : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination), "=a" (aoResult) : "1" (aoResult) : "memory"); return aoResult - 1; } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange) { register atomicord32 aoResult; asm volatile ( "xchg %2, %0;" : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination), "=a" (aoResult) : "1" (aoExchange) : "memory"); return aoResult; } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend) { register atomicord32 aoResult; asm volatile ( "lock; xaddl %2, %0;" : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination), "=a" (aoResult) : "1" (aoAddend) : "memory"); return aoResult; } static _OU_ALWAYSINLINE_PRE bool _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*bool */AtomicCompareExchange(volatile atomicord32 *paoDestination, atomicord32 aoComparand, atomicord32 aoExchange) { register bool bResult; asm volatile ( "lock; cmpxchgl %3, %0;" "setzb %1;" : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination), "=a" (bResult) : "a" (aoComparand), "r" (aoExchange) : "memory"); return bResult; } #define __OU_ATOMIC_BIT_FUNCTIONS_DEFINED static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) { register atomicord32 aoResult; register atomicord32 aoExchange; asm volatile ( "0:;" "movl %4, %2;" "andl %3, %2;" "lock; cmpxchgl %2, %0;" "jnz 0;" : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination), "=a" (aoResult), "=r" (aoExchange) : "a" (*paoDestination), "g" (aoBitMask), "m" (*paoDestination) : "memory"); return aoResult; } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) { register atomicord32 aoResult; register atomicord32 aoExchange; asm volatile ( "0:;" "movl %4, %2;" "orl %3, %2;" "lock; cmpxchgl %2, %0;" "jnz 0;" : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination), "=a" (aoResult), "=r" (aoExchange) : "a" (*paoDestination), "g" (aoBitMask), "m" (*paoDestination) : "memory"); return aoResult; } static _OU_ALWAYSINLINE_PRE atomicord32 _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicord32 */AtomicXor(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) { register atomicord32 aoResult; register atomicord32 aoExchange; asm volatile ( "0:;" "movl %4, %2;" "xorl %3, %2;" "lock; cmpxchgl %2, %0;" "jnz 0;" : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination), "=a" (aoResult), "=r" (aoExchange) : "a" (*paoDestination), "g" (aoBitMask), "m" (*paoDestination) : "memory"); return aoResult; } #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_PRE atomicord32 _OU_ALWAYSINLINE_IN _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_PRE atomicord32 _OU_ALWAYSINLINE_IN _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_PRE atomicord32 _OU_ALWAYSINLINE_IN _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_PRE atomicptr _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*atomicptr */AtomicExchangePointer(volatile atomicptr *papDestination, atomicptr apExchange) { return (atomicptr)AtomicExchange((volatile atomicord32 *)papDestination, (atomicord32)apExchange); } static _OU_ALWAYSINLINE_PRE bool _OU_ALWAYSINLINE_IN _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 BEGIN_NAMESPACE_OU(); typedef int32_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 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); #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_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*void */AtomicIncrementNoResult(volatile atomicord32 *paoDestination) { AtomicIncrement(paoDestination); } static _OU_ALWAYSINLINE_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*void */AtomicDecrementNoResult(volatile atomicord32 *paoDestination) { AtomicDecrement(paoDestination); } static _OU_ALWAYSINLINE_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*void */AtomicExchangeAddNoResult(volatile atomicord32 *paoDestination, atomicord32 aoAddend) { AtomicExchangeAdd(paoDestination, aoAddend); } static _OU_ALWAYSINLINE_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*void */AtomicAndNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) { AtomicAnd(paoDestination, aoBitMask); } static _OU_ALWAYSINLINE_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*void */AtomicOrNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) { AtomicOr(paoDestination, aoBitMask); } static _OU_ALWAYSINLINE_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*void */AtomicXorNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) { AtomicXor(paoDestination, aoBitMask); } #endif // #if !defined(__OU_ATOMIC_ORD32_NORESULT_FUNCTIONS_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 // #ifndef __OU_ATOMIC_H_INCLUDED ode-0.11.1/ou/include/ou/threadlocalstorage.h0000644000076400007640000002303611156775057016025 00000000000000/************************************************************************* * * * 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. * * * *************************************************************************/ #ifndef _OU_THREADLOCALSTORAGE_H_INCLUDED #define _OU_THREADLOCALSTORAGE_H_INCLUDED #include #include #include #include #include #if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS #include #else // #if _OU_TARGET_OS != _OU_TARGET_OS_WINDOWS #include #endif // #if _OU_TARGET_OS == ... BEGIN_NAMESPACE_OU(); ////////////////////////////////////////////////////////////////////////// // API specific types typedef CTypeSimpleWrapper HTLSKEYVALUE; typedef CTypeSimpleWrapper 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_PRE bool _OU_ALWAYSINLINE_IN _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_PRE tlsvaluetype _OU_ALWAYSINLINE_IN _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_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_API /*void */UnsafeSetStorageValue(const HTLSKEY &hskStorageKey, tlsindextype iValueIndex, tlsvaluetype vValueData) { CTLSStorageBlock *psbStorageBlock = GetKeyStorageBlock(hskStorageKey); psbStorageBlock->SetValueData(iValueIndex, vValueData); } static _OU_ALWAYSINLINE_PRE tlsvaluetype _OU_ALWAYSINLINE_IN _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 // #ifndef _OU_THREADLOCALSTORAGE_H_INCLUDED ode-0.11.1/ou/include/ou/flags.h0000644000076400007640000000376510776643320013253 00000000000000/************************************************************************* * * * 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. * * * *************************************************************************/ #ifndef __OU_FLAGS_H_INCLUDED #define __OU_FLAGS_H_INCLUDED #include #include #endif // #ifndef __OU_FLAGS_H_INCLUDED ode-0.11.1/ou/include/ou/Makefile.am0000644000076400007640000000074311005131517014015 00000000000000EXTRA_DIST = assert.h \ atomicflags.h \ atomic.h \ customization.h \ enumarrays.h \ flagsdefines.h \ flags.h \ inttypes.h \ macros.h \ malloc.h \ namespace.h \ platform.h \ simpleflags.h \ templates.h \ threadlocalstorage.h \ typewrapper.h ode-0.11.1/ou/include/ou/inttypes.h0000644000076400007640000001120410776643320014021 00000000000000/************************************************************************* * * * 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. * * * *************************************************************************/ #ifndef __OU_INTTYPES_H_INCLUDED #define __OU_INTTYPES_H_INCLUDED #include #include 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 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 8 #define OU_UINT8_BITS (sizeof(uint8ou) * OU_BITS_IN_BYTE) #define OU_INT8_BITS (sizeof(int8ou) * OU_BITS_IN_BYTE) #define OU_UINT8_MAX ((uint8ou)(-1)) #define OU_UINT8_MIN ((uint8ou)0) #define OU_INT8_MAX ((int8ou)(OU_UINT8_MAX >> 1)) #define OU_INT8_MIN ((int8ou)(OU_UINT8_MAX - OU_INT8_MAX)) #define OU_UINT16_BITS (sizeof(uint16ou) * OU_BITS_IN_BYTE) #define OU_INT16_BITS (sizeof(int16ou) * OU_BITS_IN_BYTE) #define OU_UINT16_MAX ((uint16ou)(-1)) #define OU_UINT16_MIN ((uint16ou)0) #define OU_INT16_MAX ((int16ou)(OU_UINT16_MAX >> 1)) #define OU_INT16_MIN ((int16ou)(OU_UINT16_MAX - OU_INT16_MAX)) #define OU_UINT32_BITS (sizeof(uint32ou) * OU_BITS_IN_BYTE) #define OU_INT32_BITS (sizeof(int32ou) * OU_BITS_IN_BYTE) #define OU_UINT32_MAX ((uint32ou)(-1)) #define OU_UINT32_MIN ((uint32ou)0) #define OU_INT32_MAX ((int32ou)(OU_UINT32_MAX >> 1)) #define OU_INT32_MIN ((int32ou)(OU_UINT32_MAX - OU_INT32_MAX)) #define OU_UINT64_BITS (sizeof(uint64ou) * OU_BITS_IN_BYTE) #define OU_INT64_BITS (sizeof(int64ou) * OU_BITS_IN_BYTE) #define OU_UINT64_MAX ((uint64ou)(-1)) #define OU_UINT64_MIN ((uint64ou)0) #define OU_INT64_MAX ((int64ou)(OU_UINT64_MAX >> 1)) #define OU_INT64_MIN ((int64ou)(OU_UINT64_MAX - OU_INT64_MAX)) END_NAMESPACE_OU(); #endif // #ifndef __OU_INTTYPES_H_INCLUDED ode-0.11.1/ou/include/ou/simpleflags.h0000644000076400007640000003224410777211273014456 00000000000000/************************************************************************* * * * 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. * * * *************************************************************************/ #ifndef __OU_SIMPLEFLAGS_H_INCLUDED #define __OU_SIMPLEFLAGS_H_INCLUDED #include #include #include #include #include BEGIN_NAMESPACE_OU(); template 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_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_METHOD /*void */AssignFlagsAllValues(ContainerType ctFlagsValue) { m_ctFlagsValue = ctFlagsValue; } _OU_ALWAYSINLINE_PRE ContainerType _OU_ALWAYSINLINE_IN _OU_CONVENTION_METHOD /*ContainerType */QueryFlagsAllValues() const { return m_ctFlagsValue; } // Can operate both on single flag and flag set _OU_ALWAYSINLINE_PRE void _OU_ALWAYSINLINE_IN _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_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_METHOD /*void */SignalFlagsMaskValue(ContainerType ctFlagsMask) { m_ctFlagsValue |= ctFlagsMask; } // Can operate both on single flag and flag set _OU_ALWAYSINLINE_PRE void _OU_ALWAYSINLINE_IN _OU_CONVENTION_METHOD /*void */DropFlagsMaskValue(ContainerType ctFlagsMask) { m_ctFlagsValue &= ~ctFlagsMask; } // Can operate on single flag only // Returns previous flag value _OU_ALWAYSINLINE_PRE bool _OU_ALWAYSINLINE_IN _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_PRE bool _OU_ALWAYSINLINE_IN _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_PRE ContainerType _OU_ALWAYSINLINE_IN _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_PRE bool _OU_ALWAYSINLINE_IN _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_PRE bool _OU_ALWAYSINLINE_IN _OU_CONVENTION_METHOD /*bool */GetFlagsMaskValue(ContainerType ctFlagsMask) const { return (m_ctFlagsValue & ctFlagsMask) != (ContainerType)0; } // Returns subset of flags _OU_ALWAYSINLINE_PRE ContainerType _OU_ALWAYSINLINE_IN _OU_CONVENTION_METHOD /*ContainerType */QueryFlagsByMask(ContainerType ctFlagsMask) const { return (m_ctFlagsValue & ctFlagsMask); } public: // Signal only flag out of mask _OU_ALWAYSINLINE_PRE bool _OU_ALWAYSINLINE_IN _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_PRE void _OU_ALWAYSINLINE_IN _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_PRE void _OU_ALWAYSINLINE_IN _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_PRE void _OU_ALWAYSINLINE_IN _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_PRE bool _OU_ALWAYSINLINE_IN _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_PRE bool _OU_ALWAYSINLINE_IN _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_PRE bool _OU_ALWAYSINLINE_IN _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_PRE bool _OU_ALWAYSINLINE_IN _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_PRE bool _OU_ALWAYSINLINE_IN _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_PRE void _OU_ALWAYSINLINE_IN _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_PRE void _OU_ALWAYSINLINE_IN _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_PRE ContainerType _OU_ALWAYSINLINE_IN _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_PRE bool _OU_ALWAYSINLINE_IN _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_PRE void _OU_ALWAYSINLINE_IN _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_PRE unsigned int _OU_ALWAYSINLINE_IN _OU_CONVENTION_METHOD /*unsigned int */RetrieveFlagsEnumeratedValue(ContainerType ctEnumeratedValueMask, unsigned int uiEnumeratedValueShift) const { return (unsigned int)((QueryFlagsAllValues() >> uiEnumeratedValueShift) & ctEnumeratedValueMask); } private: ContainerType m_ctFlagsValue; }; typedef CSimpleFlagsTemplate CSimpleFlags; END_NAMESPACE_OU(); #endif // #ifndef __OU_SIMPLEFLAGS_H_INCLUDED ode-0.11.1/ou/Makefile.am0000644000076400007640000000037111005131517011744 00000000000000AUTOMAKE_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 ode-0.11.1/ou/src/0000777000076400007640000000000011206343456010574 500000000000000ode-0.11.1/ou/src/ou/0000777000076400007640000000000011206343456011217 500000000000000ode-0.11.1/ou/src/ou/atomic.cpp0000644000076400007640000002775311005135646013126 00000000000000/************************************************************************* * * * 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 #include #include 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 #include #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(); ode-0.11.1/ou/src/ou/customization.cpp0000644000076400007640000000556711001422151014543 00000000000000/************************************************************************* * * * 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 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__ = ""; #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(); ode-0.11.1/ou/src/ou/malloc.cpp0000644000076400007640000000757611001422151013104 00000000000000/************************************************************************* * * * 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 #include #include #include #if _OU_TARGET_OS == _OU_TARGET_OS_MAC #include #else // #if _OU_TARGET_OS != _OU_TARGET_OS_MAC #include #endif // #if _OU_TARGET_OS != _OU_TARGET_OS_MAC 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(); ode-0.11.1/ou/src/ou/Makefile.in0000644000076400007640000003276411206343422013205 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in 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) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_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) DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/../depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libou_la_SOURCES) DIST_SOURCES = $(libou_la_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ 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@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ OU_NAMESPACE = @OU_NAMESPACE@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ 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_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@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ 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'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign src/ou/Makefile .PRECIOUS: 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 clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libou.la: $(libou_la_OBJECTS) $(libou_la_DEPENDENCIES) $(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@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-am info-am: install-data-am: install-dvi: install-dvi-am 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 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 all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES ctags 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 uninstall uninstall-am # 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: ode-0.11.1/ou/src/ou/Makefile.am0000644000076400007640000000044011005227077013162 00000000000000AM_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 ode-0.11.1/ou/src/ou/threadlocalstorage.cpp0000644000076400007640000011401111156775057015516 00000000000000/************************************************************************* * * * 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 #include #include #include #include #include #include #include #include #include #if !defined(EOK) #define EOK 0 #endif #if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS #include #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(); ode-0.11.1/ou/README.TXT0000644000076400007640000000440011015764451011255 00000000000000ODER'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. ode-0.11.1/Makefile.am0000644000076400007640000000115611053655105011332 00000000000000if ENABLE_OU OU_DIR = ou 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) \ 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 = autogen.sh build tools \ CHANGELOG.txt INSTALL.txt README.txt LICENSE.TXT pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = ode.pc ode-0.11.1/GIMPACT/0000777000076400007640000000000011206343456010446 500000000000000ode-0.11.1/GIMPACT/Makefile.in0000644000076400007640000003520111206343411012417 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ode/src/config.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-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 uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ 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@ 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@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODE_PRECISION = @ODE_PRECISION@ ODE_RELEASE = @ODE_RELEASE@ 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_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ 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@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ 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'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign GIMPACT/Makefile .PRECIOUS: 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 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. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; 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; \ (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" $(RECURSIVE_CLEAN_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ 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 || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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 \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-exec-am: install-html: install-html-recursive install-info: install-info-recursive install-man: install-pdf: install-pdf-recursive install-ps: install-ps-recursive 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: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ ctags ctags-recursive 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-recursive \ uninstall uninstall-am # 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: ode-0.11.1/GIMPACT/GIMPACT-LICENSE-BSD.TXT0000644000076400007640000000310210520703123013516 00000000000000GIMPACT : Geometric tools for VR. Copyright (c) 2006 , Francisco Len. 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.ode-0.11.1/GIMPACT/include/0000777000076400007640000000000011206343456012071 500000000000000ode-0.11.1/GIMPACT/include/Makefile.in0000644000076400007640000003512711206343411014051 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ode/src/config.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-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 uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ 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@ 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@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODE_PRECISION = @ODE_PRECISION@ ODE_RELEASE = @ODE_RELEASE@ 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_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ 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@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ 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'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign GIMPACT/include/Makefile .PRECIOUS: 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 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. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; 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; \ (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" $(RECURSIVE_CLEAN_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ 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 || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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 \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ 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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-exec-am: install-html: install-html-recursive install-info: install-info-recursive install-man: install-pdf: install-pdf-recursive install-ps: install-ps-recursive 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: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ ctags ctags-recursive 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-recursive \ uninstall uninstall-am # 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: ode-0.11.1/GIMPACT/include/Makefile.am0000644000076400007640000000002210736470567014046 00000000000000SUBDIRS = GIMPACT ode-0.11.1/GIMPACT/include/GIMPACT/0000777000076400007640000000000011206343456013155 500000000000000ode-0.11.1/GIMPACT/include/GIMPACT/gim_boxpruning.h0000644000076400007640000003254111075700417016274 00000000000000#ifndef GIM_BOXPRUNING_H_INCLUDED #define GIM_BOXPRUNING_H_INCLUDED /*! \file gim_boxpruning.h \author Francisco Len */ /* ----------------------------------------------------------------------------- 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 .
  • For using these collision routines, you must create a \ref GIM_AABB_SET by using this function : \ref gim_aabbset_alloc.
  • 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
  • Before calling collision functions, you must create a pair set with \ref GIM_CREATE_PAIR_SET
  • For finding collision pairs on a scene (common space for objects), call \ref gim_aabbset_self_intersections
  • For finding collision pairs between two box sets , call \ref gim_aabbset_box_collision
  • After using collision routines, you must destroy the pairset with \ref GIM_DESTROY_PAIR_SET
  • When the box set is no longer used, you must destroy it by calling \ref gim_aabbset_destroy
*/ //! @{ //! 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;//!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;im_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 ode-0.11.1/GIMPACT/include/GIMPACT/gim_tri_collision.h0000644000076400007640000001653411075700417016756 00000000000000#ifndef GIM_TRI_COLLISION_H_INCLUDED #define GIM_TRI_COLLISION_H_INCLUDED /*! \file gim_tri_collision.h \author Francisco Len Njera */ /* ----------------------------------------------------------------------------- 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 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)\ {\ 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 ode-0.11.1/GIMPACT/include/GIMPACT/gim_radixsort.h0000644000076400007640000001662211075700417016122 00000000000000#ifndef GIM_RADIXSORT_H_INCLUDED #define GIM_RADIXSORT_H_INCLUDED /*! \file gim_radixsort.h \author Francisco Len. 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 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 ode-0.11.1/GIMPACT/include/GIMPACT/gim_math.h0000644000076400007640000001016411102044370015015 00000000000000#ifndef GIM_MATH_H_INCLUDED #define GIM_MATH_H_INCLUDED /*! \file gim_math.h \author Francisco Len */ /* ----------------------------------------------------------------------------- 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 #include #if HAVE_SYS_TYPES_H #include #elif defined(_MSC_VER) typedef __int32 int32_t; typedef unsigned __int32 uint32_t; #elif defined(__GNUC__) #include #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 #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 ode-0.11.1/GIMPACT/include/GIMPACT/gim_memory.h0000644000076400007640000010642611075700417015415 00000000000000#ifndef GIM_MEMORY_H_INCLUDED #define GIM_MEMORY_H_INCLUDED /*! \file gim_memory.h \author Francisco Len */ /* ----------------------------------------------------------------------------- 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 //#define PREFETCH 1 //! \defgroup PREFETCH //! @{ #ifdef PREFETCH #include // 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.
  • For initializes a dynamic array, use GIM_DYNARRAY_CREATE or GIM_DYNARRAY_CREATE_SIZED.
  • When an array is no longer used, must be terminated with the macro GIM_DYNARRAY_DESTROY.
*/ //! @{ #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 .
  • For initializes a bitset array, use \ref GIM_BITSET_CREATE or \ref GIM_BITSET_CREATE_SIZED.
  • When the bitset is no longer used, must be terminated with the macro \ref GIM_DYNARRAY_DESTROY.
  • For putting a mark on the bitset, call \ref GIM_BITSET_SET
  • For clearing a mark on the bitset, call \ref GIM_BITSET_CLEAR
  • For retrieving a bit value from a bitset, call \ref GIM_BITSET_GET-
*/ //! @{ //! 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.
  • Before using buffers you must initializes GIMPACT buffer managers by calling \ref gimpact_init.
  • 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.
  • For accessing to the buffer memory, you must call \ref gim_lock_buffer, and then \ref gim_unlock_buffer for finish the access.
  • When a buffer is no longer needed, you must free it by calling \ref gim_buffer_free.
  • You must call \ref gimpact_terminate when finish your application.
  • For a safe manipulation of buffers, use \ref BUFFER_ARRAYS
\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.
  • Before using buffer arrays you must initializes GIMPACT buffer managers by calling gimpact_init.
  • Before creating buffer arrays, you must create a buffer. see \ref BUFFERS.
  • 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.
  • 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.
  • When a buffer array is no longer needed, you must free it by calling \ref GIM_BUFFER_ARRAY_DESTROY.
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 ode-0.11.1/GIMPACT/include/GIMPACT/Makefile.in0000644000076400007640000002605711206343411015137 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ode/src/config.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = HEADERS = $(noinst_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ 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@ 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@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODE_PRECISION = @ODE_PRECISION@ ODE_RELEASE = @ODE_RELEASE@ 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_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ 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@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ 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'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign GIMPACT/include/GIMPACT/Makefile .PRECIOUS: 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 mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-am info-am: install-data-am: install-dvi: install-dvi-am 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 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 all all-am check check-am clean clean-generic \ clean-libtool ctags 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 uninstall \ uninstall-am # 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: ode-0.11.1/GIMPACT/include/GIMPACT/gim_geometry.h0000644000076400007640000013416511075700417015741 00000000000000#ifndef GIM_VECTOR_H_INCLUDED #define GIM_VECTOR_H_INCLUDED /*! \file gim_geometry.h \author Francisco Len */ /* ----------------------------------------------------------------------------- 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{ 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 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 (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:
  1. 0 : In back of plane
  2. 1 : Spanning
  3. 2 : In front of
*/ #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
  • 0 : Segment in front of plane, s1 closest
  • 1 : Segment in front of plane, s2 closest
  • 2 : Segment in back of plane, s1 closest
  • 3 : Segment in back of plane, s2 closest
  • 4 : Segment collides plane, s1 in back
  • 5 : Segment collides plane, s2 in back */ #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 _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
    • 0 : Segment in front of plane, s1 closest
    • 1 : Segment in front of plane, s2 closest
    • 2 : Segment in back of plane, s1 closest
    • 3 : Segment in back of plane, s2 closest
    • 4 : Segment collides plane, s1 in back
    • 5 : Segment collides plane, s2 in back
    */ #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(_dotdir1.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 ode-0.11.1/GIMPACT/include/GIMPACT/gim_tri_sphere_collision.h0000644000076400007640000000343110520703123020303 00000000000000#ifndef GIM_TRI_SPHERE_COLLISION_H_INCLUDED #define GIM_TRI_SPHERE_COLLISION_H_INCLUDED /*! \file gim_tri_sphere_collision.h \author Francisco Len */ /* ----------------------------------------------------------------------------- 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 ode-0.11.1/GIMPACT/include/GIMPACT/gim_tri_capsule_collision.h0000644000076400007640000000707710520703123020463 00000000000000#ifndef GIM_TRI_CAPSULE_COLLISION_H_INCLUDED #define GIM_TRI_CAPSULE_COLLISION_H_INCLUDED /*! \file gim_tri_capsule_collision.h \author Francisco Len */ /* ----------------------------------------------------------------------------- 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]CREATING TRIMESHES

    • For creating trimeshes, you must initialize Buffer managers by calling \ref gimpact_init
    • 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.
    • An alternative way for creaing trimesh objects is calling \ref gim_trimesh_create_from_data.
    • 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.
    • Each time when the trimesh data is modified, you must call \ref gim_trimesh_update after.
    • When a trimesh is no longer needed, you must call \ref gim_trimesh_destroy.

    This is an example of how to create a deformable trimesh that shares vertices with the user application:

    \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

    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.

    When the trimesh is no longer needed, destroy it safely with gim_trimesh_destroy()

    UPDATING TRIMESHES

    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:

    • 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;itransformed_reply = 0.
    • 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 transformed_reply = 1.

    After updating vertices, you must call \ref gim_trimesh_update()

    TRIMESHES COLLISION

    Before collide trimeshes, you need to update them first.

    Then you must use \ref gim_trimesh_trimesh_collision().

    */ //! @{ //! 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
  • m_handle1 points to trimesh1.
  • m_handle2 points to trimesh2.
  • m_feature1 Is a triangle index of trimesh1.
  • m_feature2 Is a triangle index of trimesh2. \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
  • m_handle1 points to trimesh.
  • m_handle2 points to NULL.
  • m_feature1 Is a triangle index of trimesh. \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
  • m_handle1 points to trimesh.
  • m_handle2 points to NULL.
  • m_feature1 Is a triangle index of trimesh. \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
  • Contact lists must be create by calling \ref GIM_CREATE_CONTACT_LIST
  • After querys, contact lists must be destroy by calling \ref GIM_DYNARRAY_DESTROY
  • Contacts can be merge for avoid duplicate results by calling \ref gim_merge_contacts */ //! @{ /// 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 ode-0.11.1/GIMPACT/include/GIMPACT/Makefile.am0000644000076400007640000000044110736470567015137 00000000000000noinst_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 ode-0.11.1/GIMPACT/include/GIMPACT/gimpact.h0000644000076400007640000000301410520703123014651 00000000000000#ifndef GIMPACT_H_INCLUDED #define GIMPACT_H_INCLUDED /*! \file gimpact.h \author Francisco Len */ /* ----------------------------------------------------------------------------- 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 ode-0.11.1/GIMPACT/Makefile.am0000644000076400007640000000012610736470567012430 00000000000000EXTRA_DIST = GIMPACT-LICENSE-BSD.TXT GIMPACT-LICENSE-LGPL.TXT SUBDIRS = include src ode-0.11.1/GIMPACT/src/0000777000076400007640000000000011206343456011235 500000000000000ode-0.11.1/GIMPACT/src/gim_boxpruning.cpp0000644000076400007640000004235211075700417014710 00000000000000 /* ----------------------------------------------------------------------------- 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(countm_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;im_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;jm_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;i0&&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;im_count; for (i=0;im_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); } } } ode-0.11.1/GIMPACT/src/gim_trimesh.cpp0000644000076400007640000003436111075700417014171 00000000000000 /* ----------------------------------------------------------------------------- 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 #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; im_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 VEC_COPY(v1,transformed_vertices[triangle_indices[0]]); VEC_COPY(v2,transformed_vertices[triangle_indices[1]]); VEC_COPY(v3,transformed_vertices[triangle_indices[2]]); } ode-0.11.1/GIMPACT/src/gim_tri_tri_overlap.cpp0000644000076400007640000002153710520703123015712 00000000000000 /* ----------------------------------------------------------------------------- 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]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;_kmaxdeep)\ {\ 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;_k0)\ {\ _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(distm_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;mostdirm_points[mostdir] ,deep_points2[mostdir]); } } else { contact_data->m_point_count = deep1_count; for(mostdir=0;mostdirm_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
    • m_handle1 points to trimesh1.
    • m_handle2 points to trimesh2.
    • m_feature1 Is a triangle index of trimesh1.
    • m_feature2 Is a triangle index of trimesh2.
    \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;im_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;im_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;im_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;im_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; */ } ode-0.11.1/GIMPACT/src/gim_math.cpp0000644000076400007640000000323410625025227013441 00000000000000/* ----------------------------------------------------------------------------- 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; } ode-0.11.1/GIMPACT/src/Makefile.in0000644000076400007640000003625211206343412013216 00000000000000# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 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@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@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 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/ode/src/config.h CONFIG_CLEAN_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) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/ode/src depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libGIMPACT_la_SOURCES) DIST_SOURCES = $(libGIMPACT_la_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ 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@ 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@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODE_PRECISION = @ODE_PRECISION@ ODE_RELEASE = @ODE_RELEASE@ 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_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ WINDRES = @WINDRES@ XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ 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@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ 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_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'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign GIMPACT/src/Makefile .PRECIOUS: 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 clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libGIMPACT.la: $(libGIMPACT_la_OBJECTS) $(libGIMPACT_la_DEPENDENCIES) $(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@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here 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 $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$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: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 info: info-am info-am: install-data-am: install-dvi: install-dvi-am 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 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 all all-am check check-am clean clean-generic \ clean-libtool clean-noinstLTLIBRARIES ctags 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 uninstall uninstall-am # 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: ode-0.11.1/GIMPACT/src/gim_trimesh_sphere_collision.cpp0000644000076400007640000001443211075700417017607 00000000000000 /* ----------------------------------------------------------------------------- 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
    • m_handle1 points to trimesh.
    • m_handle2 points to NULL.
    • m_feature1 Is a triangle index of trimesh.
    \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;im_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=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 = VEC_DOT(closest_points[0],triangle->m_planes.m_planes[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_sizem_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;im_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); } ode-0.11.1/GIMPACT/src/gimpact.cpp0000644000076400007640000000241011005162546013272 00000000000000 /* ----------------------------------------------------------------------------- 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() { } ode-0.11.1/GIMPACT/src/gim_memory.cpp0000644000076400007640000006462211075700417014031 00000000000000 /* ----------------------------------------------------------------------------- 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 #include #include "GIMPACT/gim_memory.h" #include #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; } static GPTR _shared_buffer_realloc_function(GPTR buffer_handle,GUINT32 oldsize,int old_usage,GUINT32 newsize,int new_usage) { return 0; } 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;im_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;im_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); } ode-0.11.1/GIMPACT/src/Makefile.am0000644000076400007640000000130611021347356013203 00000000000000noinst_LTLIBRARIES = libGIMPACT.la AM_CPPFLAGS = -fno-strict-aliasing \ -I$(top_srcdir)/include \ -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 ode-0.11.1/GIMPACT/src/gim_trimesh_ray_collision.cpp0000644000076400007640000001105511116464372017115 00000000000000 /* ----------------------------------------------------------------------------- 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;itparam = 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;itparam)) { 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; } ode-0.11.1/GIMPACT/GIMPACT-LICENSE-LGPL.TXT0000644000076400007640000006346510520703123013666 00000000000000 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. Copyright (C) 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. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! ode-0.11.1/INSTALL.txt0000644000076400007640000001047310770170151011145 00000000000000As of version 0.6, ODE has two new build systems, one for Visual Studio and another for just about everything else. 1. Building with Visual Studio 2. Building with Autotools (Linux, OS X, etc.) 3. Building with Code::Blocks 4. Building with Something Else 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. See build/readme.txt for more details. If you downloaded this source code package from SourceForge this has already been done for you. The directory ode/build contains project files for all supported versions of Visual Studio. Note that Visual Studio 6 is not supported and users are advised to upgrade to Visual C++ 2005 Express (it's free!) Open the appropriate solution for your version, pick the build configuration you want, and build! The build configuration choices are: Debug or Release Single or Double precision Static Library (Lib) or Shared Library (DLL) 2. BUILDING WITH AUTOTOOLS (Linux, OS X, etc.) If you downloaded the source code from Subversion you must bootstrap the process by running the command: $ sh autogen.sh 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. 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, 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 CPPFLAGS CFLAGS and CXXFLAGS enviroment variables, you can set these with the export command before running configure or by defining them on the same call to configure, so 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: $ CFLAGS="-msse -march=atlon-xp" CXXFLAGS="-msse -march=atlon-xp" ./configure Note that you must set both CFLAGS and CXXFLAGS as ODE contains a mixture of C and C++ files. For preprocessor flags such as -L and -I to define library and header paths respectively use CPPFLAGS. Once configure has run successfully, build and install ODE: $ make $ make install The latter command will also create an `ode-config` script which you can use to pass cflags and ldflags to your projects. run `ode-config` from a command prompt to find out how it works. In addition the option `--with-arch=` allows the user to pass the -march flag to GCC, in order to tune the library for a particular architecture. The arguments for --with-arch are listed on this page for -mtune: http://gcc.gnu.org/onlinedocs/gcc-3.4.1/gcc/i386-and-x86-64-Options.html#i386%20and%20x86-64%20Options Note that the link points to posible values for Intel processors, but other processors are also supported, check the page for your particular processor to see what parameters can be passed to -march in your case. 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 ode/build $ premake --with-tests --target cb-gcc To see a complete list of options: $ cd ode/build $ premake --help 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 `cb-gcc`. ode-0.11.1/configure.in0000644000076400007640000003016111206302536011602 00000000000000dnl AC_INIT does not take a macro as a version nr: set it separately! - Bram AC_INIT([ODE],[0.11.1],[ode@ode.org]) # AC_CONFIG_SRCDIR([ode/src/ode.cpp]) ODE_RELEASE=0.11.1 AC_SUBST(ODE_RELEASE) # 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=2 REVISION=1 AGE=1 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_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 AC_DISABLE_SHARED AC_LIBTOOL_WIN32_DLL AC_PROG_LIBTOOL AC_CHECK_TOOLS([WINDRES], [windres]) AC_C_BIGENDIAN AC_C_INLINE AC_C_VOLATILE AC_HEADER_STDBOOL AC_TYPE_SIZE_T 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) AC_MSG_RESULT($enable_demos) 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 stdint.h stdlib.h math.h string.h stdarg.h malloc.h float.h time.h sys/time.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] ), precision=$enableval,precision=no) AC_MSG_RESULT([$precision]) if test "$precision" = yes; then ODE_PRECISION=-DdDOUBLE else ODE_PRECISION=-DdSINGLE fi CPPFLAGS+=" $ODE_PRECISION" 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.]), [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) AM_CONDITIONAL(ENABLE_DRAWSTUFF, test x$drawstuff != xnone) dnl Set Conditionals AM_CONDITIONAL(WIN32, test x$drawstuff = xWin32) AM_CONDITIONAL(X11, test x$drawstuff = xX11) AM_CONDITIONAL(OSX, test x$drawstuff = xOSX) dnl Set Drawstuff variables AC_MSG_CHECKING(which drawstuff lib to build) AC_MSG_RESULT($drawstuff) if test "x$drawstuff" = "xX11" then AC_PATH_XTRA 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 Carbon -framework AGL" else have_gl_headers=yes AC_CHECK_HEADERS(GL/gl.h GL/glu.h GL/glext.h, , [have_gl_headers=no], [[#ifdef WIN32 #include #endif #if HAVE_GL_GL_H #include #endif #if HAVE_GL_GLU_H #include #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 if test x$enable_demos = xyes; then AC_MSG_WARN([Demos will not be built because OpenGL doesn't seem to work. See `config.log' for details.]) fi enable_demos=no fi fi AC_SUBST(GL_LIBS) 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 dnl Check for autoscan sugested functions AC_CHECK_LIB(m, [main]) AC_CHECK_LIB(sunmath, [main]) AC_CHECK_FUNCS([floor memmove memset select sqrt sqrtf sinf cosf fabsf atan2f fmodf copysignf copysign snprintf vsnprintf gettimeofday isnan isnanf _isnan _isnanf __isnan __isnanf]) AC_FUNC_ALLOCA AC_FUNC_MALLOC AC_FUNC_OBSTACK AC_FUNC_REALLOC AC_FUNC_SELECT_ARGTYPES AC_FUNC_VPRINTF AC_MSG_CHECKING(if alloca should be emulated by malloc) AC_ARG_ENABLE([malloc], AS_HELP_STRING([--enable-malloc], [use malloc to emulate alloca (more portable but slower)] ), usemalloc=$enableval, usemalloc=no) if test "$usemalloc" != no then AC_DEFINE([dUSE_MALLOC_FOR_ALLOCA],[1],[use malloc() instead of alloca()]) AC_MSG_RESULT($usemalloc) else AC_MSG_RESULT(no) fi AC_ARG_ENABLE([ou], AS_HELP_STRING([--enable-ou], [EXPERIMENTAL: use TLS for global variables to allow for running ODE in multiple threads simultaneously] ), use_ou=$enableval,use_ou=no) if test x$use_ou = xyes then OU_NAMESPACE=odeou AC_CONFIG_COMMANDS_POST([export OU_NAMESPACE=odeou]) AC_DEFINE([_OU_NAMESPACE],[odeou],[libou namespace for ODE]) AC_DEFINE([dOU_ENABLED],[1],[Generic OU features are enabled]) AC_DEFINE([dATOMICS_ENABLED],[1],[Atomic API of OU is enabled]) AC_DEFINE([dTLS_ENABLED],[1],[Thread Local Storage API of OU is enabled]) 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]) fi AC_CONFIG_SUBDIRS([ou]) AM_CONDITIONAL(ENABLE_OU, test x$use_ou = xyes) 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" if test x$use_ou = xyes then CPPFLAGS="$CPPFLAGS -DNDEBUG" fi 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 #endif #ifdef HAVE_MALLOC_H #include #endif #ifdef HAVE_STDINT_H #include #endif /* an integer type that we can safely cast a pointer to and * from without loss of bits. */ typedef uintptr_t intP; // Use the error-checking memory allocation system. Because this system uses heap // (malloc) instead of stack (alloca), it is slower. However, it allows you to // simulate larger scenes, as well as handle out-of-memory errors in a somewhat // graceful manner #ifdef dUSE_MALLOC_FOR_ALLOCA enum { d_MEMORY_OK = 0, /* no memory errors */ d_MEMORY_OUT_OF_MEMORY /* malloc failed due to out of memory error */ }; #endif #ifdef dSINGLE #define dEpsilon FLT_EPSILON #else #define dEpsilon DBL_EPSILON #endif #endif /* #define ODE_CONFIG_H */ ]) dnl Finally write our Makefiles AC_CONFIG_FILES([ Makefile include/Makefile include/ode/Makefile include/drawstuff/Makefile ode/Makefile ode/src/Makefile ode/src/joints/Makefile drawstuff/Makefile drawstuff/src/Makefile drawstuff/dstest/Makefile ode/demo/Makefile OPCODE/Makefile OPCODE/Ice/Makefile GIMPACT/Makefile GIMPACT/include/Makefile GIMPACT/include/GIMPACT/Makefile GIMPACT/src/Makefile tests/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: $precision" echo " Use drawstuff: $drawstuff" echo " Demos enabled: $enable_demos" echo " Use OPCODE: $opcode" echo " Use GIMPACT: $gimpact" echo " Is target a Pentium: $pentium" echo " Is target x86-64: $cpu64" echo " Use old opcode trimesh collider: $old_trimesh" echo " TLS for global data: $use_ou" 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" ode-0.11.1/tools/0000777000076400007640000000000011206343334010515 500000000000000ode-0.11.1/tools/src-release.sh0000644000076400007640000000536110703672062013203 00000000000000#!/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 ode-0.11.1/tools/ode_convex_export.py0000644000076400007640000000360611071465231014543 00000000000000#!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 #import struct 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"ode-0.11.1/tools/README.txt0000644000076400007640000000506410704661563012145 00000000000000HOW 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) ode-0.11.1/tools/msw-release.bat0000644000076400007640000000672010703664433013361 00000000000000@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