diff --git a/libraries/ode-0.9/CHANGELOG.txt b/libraries/ode-0.9/CHANGELOG.txt new file mode 100644 index 0000000000..a2baf4e67f --- /dev/null +++ b/libraries/ode-0.9/CHANGELOG.txt @@ -0,0 +1,467 @@ +ODE CHANGELOG +------------- + +the rules for this file: + * entries are sorted newest-first. + * summarize sets of changes - dont reproduce every CVS log comment here. + * don't ever delete anything. + * keep the format consistent (79 char width, M/D/Y date format). + +------------------------------------------------------------------------------ + +11/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. diff --git a/libraries/ode-0.9/GIMPACT/GIMPACT-LICENSE-BSD.TXT b/libraries/ode-0.9/GIMPACT/GIMPACT-LICENSE-BSD.TXT new file mode 100644 index 0000000000..95545aac2c --- /dev/null +++ b/libraries/ode-0.9/GIMPACT/GIMPACT-LICENSE-BSD.TXT @@ -0,0 +1,29 @@ +GIMPACT : Geometric tools for VR. + +Copyright (c) 2006 , Francisco León. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + + * Neither the name of the GIMPACT nor the names of its contributors may be used + to endorse or promote products derived from this software without specific prior + written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + DAMAGE. \ No newline at end of file diff --git a/libraries/ode-0.9/GIMPACT/GIMPACT-LICENSE-LGPL.TXT b/libraries/ode-0.9/GIMPACT/GIMPACT-LICENSE-LGPL.TXT new file mode 100644 index 0000000000..60b81560d8 --- /dev/null +++ b/libraries/ode-0.9/GIMPACT/GIMPACT-LICENSE-LGPL.TXT @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + 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! diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_boxpruning.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_boxpruning.h new file mode 100644 index 0000000000..68b68d073e --- /dev/null +++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_boxpruning.h @@ -0,0 +1,323 @@ +#ifndef GIM_BOXPRUNING_H_INCLUDED +#define GIM_BOXPRUNING_H_INCLUDED + +/*! \file gim_boxpruning.h +\author Francisco León +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + + +#include "GIMPACT/gim_radixsort.h" +#include "GIMPACT/gim_geometry.h" + +/*! \defgroup BOX_PRUNNING + +\brief +Tools for find overlapping objects on a scenary. These functions sort boxes for faster collisioin queries, using radix sort or quick sort as convenience. See \ref SORTING . +
    +
  • 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 +{ + GUINT m_index1; + GUINT m_index2; +}; +//typedef struct _GIM_PAIR GIM_PAIR; + +//! Box container +struct GIM_AABB_SET +{ + GUINT m_count; + aabb3f m_global_bound;//!< Global calculated bound of all boxes + aabb3f * m_boxes; + GUINT * 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(GUINT,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)\ +{\ + GUINT _z = ((GUINT)(vz*ERROR_AABB))+32768;\ + uint_key = ((GUINT)(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)\ +{\ + GUINT _z = ((GUINT)ceilf(vz*ERROR_AABB))+32768;\ + uint_key = ((GUINT)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);\ + GUINT _z = ((GUINT)(_cz*ERROR_AABB))+32768;\ + uint_key = ((GUINT)(_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);\ + GUINT _z = ((GUINT)ceilf(_cz*ERROR_AABB))+32768;\ + uint_key = ((GUINT)ceilf(_cx*ERROR_AABB))+32768;\ + uint_key = (uint_key<<16) + _z;\ +}\ + +//! @} + +#endif // GIM_BOXPRUNING_H_INCLUDED diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_contact.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_contact.h new file mode 100644 index 0000000000..bad8f0f3ec --- /dev/null +++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_contact.h @@ -0,0 +1,115 @@ +#ifndef GIM_CONTACT_H_INCLUDED +#define GIM_CONTACT_H_INCLUDED + +/*! \file gim_contact.h +\author Francisco León +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + + +#include "GIMPACT/gim_geometry.h" +#include "GIMPACT/gim_radixsort.h" + +/*! \defgroup CONTACTS +\brief +Functions for managing and sorting contacts resulting from a collision query. +
    +
  • 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; + GUINT m_feature1;//Face number + GUINT m_feature2;//Face number +}; +//typedef struct _GIM_CONTACT GIM_CONTACT; + +#define CONTACT_DIFF_EPSILON 0.00001f + +#define GIM_CALC_KEY_CONTACT(pos,hash)\ +{\ + GINT _coords[] = {(GINT)(pos[0]*1000.0f+1.0f),(GINT)(pos[1]*1333.0f),(GINT)(pos[2]*2133.0f+3.0f)};\ + GUINT _hash=0;\ + GUINT *_uitmp = (GUINT *)(&_coords[0]);\ + _hash = *_uitmp;\ + _uitmp++;\ + _hash += (*_uitmp)<<4;\ + _uitmp++;\ + _hash += (*_uitmp)<<8;\ + hash = _hash;\ +}\ + +///Creates a contact list for queries +#define GIM_CREATE_CONTACT_LIST(contact_array) GIM_DYNARRAY_CREATE(GIM_CONTACT,contact_array,100) + +#define GIM_PUSH_CONTACT(contact_array, point, normal, deep,handle1, handle2, feat1, feat2)\ +{\ + GIM_DYNARRAY_PUSH_EMPTY(GIM_CONTACT,contact_array);\ + GIM_CONTACT * _last = GIM_DYNARRAY_POINTER_LAST(GIM_CONTACT,contact_array);\ + VEC_COPY(_last->m_point,point);\ + VEC_COPY(_last->m_normal,normal);\ + _last->m_depth = deep;\ + _last->m_handle1 = handle1;\ + _last->m_handle2 = handle2;\ + _last->m_feature1 = feat1;\ + _last->m_feature2 = feat2;\ +}\ + +///Receive pointer to contacts +#define GIM_COPY_CONTACTS(dest_contact, source_contact)\ +{\ + VEC_COPY(dest_contact->m_point,source_contact->m_point);\ + VEC_COPY(dest_contact->m_normal,source_contact->m_normal);\ + dest_contact->m_depth = source_contact->m_depth;\ + dest_contact->m_handle1 = source_contact->m_handle1;\ + dest_contact->m_handle2 = source_contact->m_handle2;\ + dest_contact->m_feature1 = source_contact->m_feature1;\ + dest_contact->m_feature2 = source_contact->m_feature2;\ +}\ + +//! Merges duplicate contacts with minimum depth criterion +void gim_merge_contacts(GDYNAMIC_ARRAY * source_contacts, + GDYNAMIC_ARRAY * dest_contacts); + + +//! Merges to an unique contact +void gim_merge_contacts_unique(GDYNAMIC_ARRAY * source_contacts, + GDYNAMIC_ARRAY * dest_contacts); + +//! @} +#endif // GIM_CONTACT_H_INCLUDED diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_geometry.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_geometry.h new file mode 100644 index 0000000000..6d89a949aa --- /dev/null +++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_geometry.h @@ -0,0 +1,1872 @@ +#ifndef GIM_VECTOR_H_INCLUDED +#define GIM_VECTOR_H_INCLUDED + +/*! \file gim_geometry.h +\author Francisco León +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + + +#include "GIMPACT/gim_math.h" + +/*! \defgroup GEOMETRIC_TYPES +\brief +Basic types and constants for geometry +*/ +//! @{ + +//! Integer vector 2D +typedef GINT vec2i[2]; +//! Integer vector 3D +typedef GINT vec3i[3]; +//! Integer vector 4D +typedef GINT 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;\ + GUINT _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 diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_math.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_math.h new file mode 100644 index 0000000000..68f226e98a --- /dev/null +++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_math.h @@ -0,0 +1,147 @@ +#ifndef GIM_MATH_H_INCLUDED +#define GIM_MATH_H_INCLUDED + +/*! \file gim_math.h +\author Francisco León +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + + +#include +#include + + +/*! \defgroup BASIC_TYPES +Basic types and constants +Conventions: +Types starting with G +Constants starting with G_ +*/ +//! @{ +/*! Types */ +#define GREAL float +#define GINT long +#define GUINT unsigned long +/*! Constants for integers*/ +#define GUINT_BIT_COUNT 32 +#define GUINT_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) ((GUINT&)(x)) + +//! Signed integer representation of a floating-point value. +#define SIR(x) ((GINT&)(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) (ab?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) (numbermaxval?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;\ + GUINT _y = 0x5f3759df - ( IR(va) >> 1);\ + isva = FR(_y);\ + isva = isva * ( 1.5f - ( _x * isva * isva ) );\ + }\ +}\ + +#define GIM_SQRT(va,sva)\ +{\ + GIM_INV_SQRT(va,sva);\ + sva = 1.0f/sva;\ +}\ + +//! Computes 1.0f / sqrtf(x). Comes from Quake3. See http://www.magic-software.com/3DGEDInvSqrt.html +GREAL gim_inv_sqrt(GREAL f); + +//! Computes sqrtf(x) faster. +/*! +\sa gim_inv_sqrt +*/ +GREAL gim_sqrt(GREAL f); + +//!Initializes mathematical functions +void gim_init_math(); + +//! Generates an unit random +GREAL gim_unit_random(); +//! @} + +#endif // GIM_MATH_H_INCLUDED diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_memory.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_memory.h new file mode 100644 index 0000000000..58661f1a17 --- /dev/null +++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_memory.h @@ -0,0 +1,1040 @@ +#ifndef GIM_MEMORY_H_INCLUDED +#define GIM_MEMORY_H_INCLUDED +/*! \file gim_memory.h +\author Francisco León +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + + +#include "GIMPACT/gim_math.h" +#include + +//#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)\ +{\ + GUINT _i_;\ + for (_i_=0;_i_ +
  • 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 100 + +//! Dynamic array handle. +struct GDYNAMIC_ARRAY +{ + char * m_pdata; + GUINT m_size; + GUINT 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,reserve_size) \ +{ \ + if(reserve_size>array_data.m_reserve_size )\ + { \ + array_data.m_pdata = (char *) gim_realloc(array_data.m_pdata,array_data.m_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,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+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+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+G_ARRAY_GROW_SIZE));\ + }\ + type * _pt = GIM_DYNARRAY_POINTER(type,array_data);\ + if(index0) \ + { \ + 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(GUINT,array_data,G_ARRAY_GROW_SIZE) + +//! Creates a bitset, with their bits set to 0. +#define GIM_BITSET_CREATE_SIZED(array_data,bits_count)\ +{\ + array_data.m_size = bits_count/GUINT_BIT_COUNT + 1;\ + GIM_DYNARRAY_CREATE(GUINT,array_data,array_data.m_size);\ + GUINT * _pt = GIM_DYNARRAY_POINTER(GUINT,array_data);\ + memset(_pt,0,sizeof(GUINT)*(array_data.m_size));\ +}\ + +//! Gets the bitset bit count. +#define GIM_BITSET_SIZE(array_data) (array_data.m_size*GUINT_BIT_COUNT) + +//! Resizes a bitset, with their bits set to 0. +#define GIM_BITSET_RESIZE(array_data,new_bits_count)\ +{ \ + GUINT _oldsize = array_data.m_size;\ + array_data.m_size = new_bits_count/GUINT_BIT_COUNT + 1; \ + if(_oldsize array_data.m_reserve_size)\ + {\ + GIM_DYNARRAY_RESERVE_SIZE(GUINT,array_data,array_data.m_size+G_ARRAY_GROW_SIZE);\ + }\ + GUINT * _pt = GIM_DYNARRAY_POINTER(GUINT,array_data);\ + memset(&_pt[_oldsize],0,sizeof(GUINT)*(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(GUINT)*array_data.m_size);\ +}\ + +//! Sets all bitset bit to 1. +#define GIM_BITSET_SET_ALL(array_data)\ +{\ + memset(array_data.m_pdata,0xFF,sizeof(GUINT)*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);\ + }\ + GUINT * _pt = GIM_DYNARRAY_POINTER(GUINT,array_data);\ + _pt[bit_index >> GUINT_EXPONENT] |= (1 << (bit_index & (GUINT_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\ + {\ + GUINT * _pt = GIM_DYNARRAY_POINTER(GUINT,array_data);\ + get_value = _pt[bit_index >> GUINT_EXPONENT] & (1 << (bit_index & (GUINT_BIT_COUNT-1)));\ + }\ +}\ + +///Sets the desired bit to 0 +#define GIM_BITSET_CLEAR(array_data,bit_index) \ +{\ + if(bit_index> GUINT_EXPONENT] &= ~(1 << (bit_index & (GUINT_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 +*/ +//! @{ +#define G_BUFFER_MANAGER_SYSTEM 0 +#define G_BUFFER_MANAGER_SHARED 1 +#define G_BUFFER_MANAGER_USER 2 +//! @} + +/*! \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 +*/ +//! @{ + +//! Buffer handle. +struct GBUFFER_ID +{ + GUINT m_buffer_id; + GUINT m_buffer_manager_id; +}; +//typedef struct _GBUFFER_ID GBUFFER_ID; + +//! Buffer internal data +struct GBUFFER_DATA +{ + GUINT m_buffer_handle;//!< if 0, buffer doesn't exists + GUINT m_size; + GUINT m_usage; + GINT m_access; + GUINT m_lock_count; + char * m_mapped_pointer; + GBUFFER_ID m_shadow_buffer; + GUINT 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 GUINT gim_buffer_alloc_function(GUINT size,int usage); + +//! Returns a Buffer handle, and copies the pdata to the buffer +typedef GUINT gim_buffer_alloc_data_function(const void * pdata,GUINT size,int usage); + +//! Changes the size of the buffer preserving the content, and returns the new buffer id +typedef GUINT gim_buffer_realloc_function(GUINT buffer_handle,GUINT oldsize,int old_usage,GUINT newsize,int new_usage); + +//! It changes the m_buffer_handle member to 0/0 +typedef void gim_buffer_free_function(GUINT buffer_handle,GUINT size); + +//! It maps the m_mapped_pointer. Returns a pointer +typedef char * gim_lock_buffer_function(GUINT buffer_handle,int access); + +//! It sets the m_mapped_pointer to 0 +typedef void gim_unlock_buffer_function(GUINT buffer_handle); + +typedef void gim_download_from_buffer_function( + GUINT source_buffer_handle, + GUINT source_pos, + void * destdata, + GUINT copysize); + +typedef void gim_upload_to_buffer_function( + GUINT dest_buffer_handle, + GUINT dest_pos, + void * sourcedata, + GUINT copysize); + +typedef void gim_copy_buffers_function( + GUINT source_buffer_handle, + GUINT source_pos, + GUINT dest_buffer_handle, + GUINT dest_pos, + GUINT 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 + GBUFFER_MANAGER_PROTOTYPE m_prototype;//! Prototype of functions + GUINT m_active; //!< 0 or 1 +}; +//typedef struct _GBUFFER_MANAGER_DATA GBUFFER_MANAGER_DATA; + +//! Adds a buffer Manager to the Memory Singleton +void gim_create_buffer_manager(GBUFFER_MANAGER_PROTOTYPE * prototype,GUINT buffer_manager_id); +//! Gets buffer manager +GUINT gim_get_buffer_manager_count(); +//! Destroys a buffer manager +void gim_destroy_buffer_manager(GUINT buffer_manager_id); +void gim_get_buffer_manager_data(GUINT buffer_manager_id,GBUFFER_MANAGER_DATA ** pbm_data); +void gim_init_buffer_managers(); +void gim_terminate_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 +*/ +GUINT gim_create_buffer( + GUINT buffer_manager_id, + GUINT 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 +*/ +GUINT gim_create_buffer_from_data( + GUINT buffer_manager_id, + const void * pdata, + GUINT buffer_size, + int usage, + GBUFFER_ID * buffer_id); + +//!Allocates on the G_BUFFER_MANAGER_SYSTEM +GUINT gim_create_common_buffer(GUINT buffer_size, GBUFFER_ID * buffer_id); +//!Allocates on the G_BUFFER_MANAGER_SYSTEM, and copies the data +GUINT gim_create_common_buffer_from_data( + const void * pdata, GUINT buffer_size, GBUFFER_ID * buffer_id); +//!Creates a buffer with shared data +GUINT gim_create_shared_buffer_from_data( + const void * pdata, GUINT buffer_size, GBUFFER_ID * buffer_id); + + +//! Add reference counting to buffer. +GINT 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. +*/ +GINT gim_buffer_realloc(GBUFFER_ID * buffer_id,GUINT newsize); + +//! Eliminates the buffer. +/*! +If the buffer reference counting is <= 1 and is unlocked, then it eliminates the buffer. +*/ +GINT 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. +*/ +GINT gim_lock_buffer(GBUFFER_ID * buffer_id,int access,char ** map_pointer); + +//! Unlocks the buffer for memory access. +GINT gim_unlock_buffer(GBUFFER_ID * buffer_id); + +//! Gets the buffer size in bytes +GINT gim_get_buffer_size(GBUFFER_ID * buffer_id,GUINT * buffer_size); + +//! Determines if the buffer is locked +GINT gim_get_buffer_is_locked(GBUFFER_ID * buffer_id,GUINT * lock_count); + +//! Copies the content of the buffer to a dest pointer +GINT gim_download_from_buffer( + GBUFFER_ID * buffer_id, + GUINT source_pos, + void * destdata, + GUINT copysize); + +//! Copies the content of a memory pointer to the buffer +GINT gim_upload_to_buffer( + GBUFFER_ID * buffer_id, + GUINT dest_pos, + void * sourcedata, + GUINT copysize); + +//! Copies two buffers. +GINT gim_copy_buffers( + GBUFFER_ID * source_buffer_id, + GUINT source_pos, + GBUFFER_ID * dest_buffer_id, + GUINT dest_pos, + GUINT 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; + GUINT m_byte_offset; + GUINT 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)\ + {\ + GUINT _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) \ + { \ + memcpy(&_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);\ + memcpy(&_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_buffer_manager_id = (buffer_id).m_buffer_manager_id;\ + (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 +*/ +GINT 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 +*/ +GINT 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_ARRAY * dest_data, GUINT 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\ + {\ + GUINT _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\ + {\ + GUINT _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);\ +\ + GUINT _i_, _count_=(_src_array).m_element_count;\ +\ + _src_type * _source_vert_;\ + _dst_type * _dest_vert_;\ + if(GIM_BUFFER_ARRAY_IS_ALIGNED(_src_type,_src_array) && GIM_BUFFER_ARRAY_IS_ALIGNED(_dst_type,_dst_array))\ + {\ +\ + _source_vert_ = GIM_BUFFER_ARRAY_POINTER(_src_type,_src_array,0);\ + _dest_vert_ = GIM_BUFFER_ARRAY_POINTER(_dst_type,_dst_array,0);\ + for (_i_ = 0;_i_< _count_; _i_++)\ + {\ + _kernel(_uniform_data,(*_source_vert_),(*_dest_vert_));\ + _source_vert_++;\ + _dest_vert_++;\ + }\ + }\ + else\ + {\ + for (_i_ = 0;_i_< _count_; _i_++)\ + {\ + _source_vert_ = GIM_BUFFER_ARRAY_POINTER(_src_type,_src_array,_i_);\ + _dest_vert_ = GIM_BUFFER_ARRAY_POINTER(_dst_type,_dst_array,_i_);\ + _kernel(_uniform_data,(*_source_vert_),(*_dest_vert_));\ + }\ + }\ + gim_buffer_array_unlock(&_src_array);\ + gim_buffer_array_unlock(&_dst_array);\ +}\ + +//! @} + +#endif // GIM_MEMORY_H_INCLUDED diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_radixsort.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_radixsort.h new file mode 100644 index 0000000000..a5f8e124a4 --- /dev/null +++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_radixsort.h @@ -0,0 +1,258 @@ +#ifndef GIM_RADIXSORT_H_INCLUDED +#define GIM_RADIXSORT_H_INCLUDED +/*! \file gim_radixsort.h +\author Francisco León. +Based on the work of Michael Herf : "fast floating-point radix sort" +Avaliable on http://www.stereopsis.com/radix.html +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + +#include "GIMPACT/gim_memory.h" + +/*! \defgroup SORTING +\brief +Macros for sorting. +*/ +//! @{ +struct GIM_RSORT_TOKEN +{ + GUINT m_key; + GUINT 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 =(GINT)(e);} + +#define SIMPLE_GET_UINTKEY(e,key) {key =(GUINT)(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)\ +{\ + GUINT i;\ + GUINT b0[kHist * 3];\ + GUINT *b1 = b0 + kHist;\ + GUINT *b2 = b1 + kHist;\ + for (i = 0; i < kHist * 3; i++)\ + {\ + b0[i] = 0;\ + }\ + GUINT fi;\ + GUINT pos;\ + for (i = 0; i < element_count; i++)\ + {\ + fi = array[i].m_key;\ + b0[D11_0(fi)] ++;\ + b1[D11_1(fi)] ++;\ + b2[D11_2(fi)] ++;\ + }\ + {\ + GUINT sum0 = 0, sum1 = 0, sum2 = 0;\ + GUINT 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);\ + GUINT _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) ((GINT)((x) - (y))) +//! @} +#endif // GIM_RADIXSORT_H_INCLUDED diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_capsule_collision.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_capsule_collision.h new file mode 100644 index 0000000000..2b31604a48 --- /dev/null +++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_capsule_collision.h @@ -0,0 +1,111 @@ +#ifndef GIM_TRI_CAPSULE_COLLISION_H_INCLUDED +#define GIM_TRI_CAPSULE_COLLISION_H_INCLUDED + +/*! \file gim_tri_capsule_collision.h +\author Francisco León +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + +#include "GIMPACT/gim_memory.h" + +/*! \addtogroup GEOMETRIC_OPERATIONS +*/ +//! @{ + +//! Capsule struct +struct GIM_CAPSULE_DATA +{ + GREAL m_radius; + vec3f m_point1; + vec3f m_point2; +}; +//typedef struct _GIM_CAPSULE_DATA GIM_CAPSULE_DATA; + +#define CALC_CAPSULE_AABB(capsule,aabb)\ +{\ + if(capsule.m_point1[0]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);\ + GUINT _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 diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_sphere_collision.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_sphere_collision.h new file mode 100644 index 0000000000..a2a81d67fa --- /dev/null +++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_tri_sphere_collision.h @@ -0,0 +1,51 @@ +#ifndef GIM_TRI_SPHERE_COLLISION_H_INCLUDED +#define GIM_TRI_SPHERE_COLLISION_H_INCLUDED + +/*! \file gim_tri_sphere_collision.h +\author Francisco León +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + +/*! \addtogroup GEOMETRIC_OPERATIONS +*/ +//! @{ + +//! Finds the contact points from a collision of a triangle and a sphere +/*! +\param tri +\param center +\param radius +\param contact_data Contains the closest points on the Sphere, and the normal is pointing to triangle +*/ +int gim_triangle_sphere_collision( + GIM_TRIANGLE_DATA *tri, + vec3f center, GREAL radius, + GIM_TRIANGLE_CONTACT_DATA * contact_data); + +//! @} +#endif // GIM_TRI_SPHERE_COLLISION_H_INCLUDED diff --git a/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_trimesh.h b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_trimesh.h new file mode 100644 index 0000000000..b1cdf7f808 --- /dev/null +++ b/libraries/ode-0.9/GIMPACT/include/GIMPACT/gim_trimesh.h @@ -0,0 +1,539 @@ +#ifndef GIM_TRIMESH_H_INCLUDED +#define GIM_TRIMESH_H_INCLUDED +/*! \file gim_trimesh.h +\author Francisco León +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + +#include "GIMPACT/gim_boxpruning.h" +#include "GIMPACT/gim_contact.h" + + +///MAsk defines +#define GIM_TRIMESH_TRANSFORMED_REPLY 1 +#define GIM_TRIMESH_NEED_UPDATE 2 + +/*! \addtogroup TRIMESH +\brief +A Trimesh is the basic geometric structure for representing solid objects. +

    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 +GUINT 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(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(GIM_TRIMESH * trimesh, vec3f * vertex_array, GUINT vertex_count,char copy_vertices, GUINT * triindex_array, GUINT 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,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, GUINT 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, GUINT 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;im_count = count; + aabbset->m_boxes = (aabb3f *)gim_alloc(sizeof(aabb3f)*count); + + if(countm_maxcoords = 0; + aabbset->m_sorted_mincoords = 0; + } + else + { + aabbset->m_maxcoords = (GUINT *)gim_alloc(sizeof(GUINT)*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)); + + GUINT 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 = (GUINT *)gim_alloc(sizeof(GUINT)*aabbset->m_count ); + aabbset->m_sorted_mincoords = (GIM_RSORT_TOKEN *)gim_alloc(sizeof(GIM_RSORT_TOKEN)*aabbset->m_count); + } + + GUINT i, count = aabbset->m_count; + aabb3f * paabb = aabbset->m_boxes; + GUINT * 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)\ +{\ + GUINT _i = test_count;\ + char _intersected;\ + GIM_RSORT_TOKEN * _psorted_tokens = sorted_tokens;\ + while(max_coord_uint >= _psorted_tokens->m_key && _i>0)\ + {\ + 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; + GUINT count = aabbset->m_count; + aabb3f * paabb = aabbset->m_boxes; + GUINT * maxcoords = aabbset->m_maxcoords; + GIM_RSORT_TOKEN * sorted_tokens = aabbset->m_sorted_mincoords; + aabb3f test_aabb; + while(count>1) + { + ///current cache variables + GUINT curr_index = sorted_tokens->m_value; + GUINT 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; + GUINT i,j; + GUINT 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; + + GUINT count1 = aabbset1->m_count; + aabb3f * paabb1 = aabbset1->m_boxes; + GUINT * maxcoords1 = aabbset1->m_maxcoords; + GIM_RSORT_TOKEN * sorted_tokens1 = aabbset1->m_sorted_mincoords; + + GUINT count2 = aabbset2->m_count; + aabb3f * paabb2 = aabbset2->m_boxes; + GUINT * maxcoords2 = aabbset2->m_maxcoords; + GIM_RSORT_TOKEN * sorted_tokens2 = aabbset2->m_sorted_mincoords; + + GUINT curr_index; + + GUINT 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); + GUINT 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 + GUINT i,j; + GUINT classified_count = 0; + + GUINT count = aabbset1->m_count; + aabb3f * paabb1 = aabbset1->m_boxes; + aabb3f * paabb2 = aabbset2->m_boxes; + + GUINT * classified = (GUINT *) gim_alloc(sizeof(GUINT)*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; + + GUINT i; + GUINT 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(GUINT,(*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; + + GUINT i; + GUINT 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(GUINT,(*collided),i); + } + } +} diff --git a/libraries/ode-0.9/GIMPACT/src/gim_contact.cpp b/libraries/ode-0.9/GIMPACT/src/gim_contact.cpp new file mode 100644 index 0000000000..762af06e66 --- /dev/null +++ b/libraries/ode-0.9/GIMPACT/src/gim_contact.cpp @@ -0,0 +1,132 @@ + +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + +#include "GIMPACT/gim_contact.h" + +void gim_merge_contacts(GDYNAMIC_ARRAY * source_contacts, + GDYNAMIC_ARRAY * dest_contacts) +{ + dest_contacts->m_size = 0; + + GUINT 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); + + GUINT 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 + GUINT 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 + GUINT 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; + */ +} + + + diff --git a/libraries/ode-0.9/GIMPACT/src/gim_math.cpp b/libraries/ode-0.9/GIMPACT/src/gim_math.cpp new file mode 100644 index 0000000000..18efb2cc8d --- /dev/null +++ b/libraries/ode-0.9/GIMPACT/src/gim_math.cpp @@ -0,0 +1,60 @@ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + + +#include "GIMPACT/gim_math.h" +#include "stdlib.h" +#include "time.h" + + +GREAL gim_inv_sqrt(GREAL f) +{ + GREAL r; + GIM_INV_SQRT(f,r); + return r; +} + +GREAL gim_sqrt(GREAL f) +{ + GREAL r; + GIM_SQRT(f,r); + return r; +} + +//!Initializes mathematical functions +void gim_init_math() +{ + srand( static_cast< unsigned int >( time( 0 ) ) ); +} + +//! Generates an unit random +GREAL gim_unit_random() +{ + GREAL rn = static_cast< GREAL >( rand() ); + rn/=(GREAL)RAND_MAX; + return rn; +} diff --git a/libraries/ode-0.9/GIMPACT/src/gim_memory.cpp b/libraries/ode-0.9/GIMPACT/src/gim_memory.cpp new file mode 100644 index 0000000000..247565a4e9 --- /dev/null +++ b/libraries/ode-0.9/GIMPACT/src/gim_memory.cpp @@ -0,0 +1,848 @@ + +/* +----------------------------------------------------------------------------- +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" +#include "stdlib.h" +#include "malloc.h" +//#include "mm_malloc.h" + +static gim_alloc_function *g_allocfn = 0; +static gim_alloca_function *g_allocafn = 0; +static gim_realloc_function *g_reallocfn = 0; +static gim_free_function *g_freefn = 0; + +// buffer managers +#define MAX_BUFFER_MANAGERS 16 +static GBUFFER_MANAGER_DATA g_buffer_managers[MAX_BUFFER_MANAGERS]; +static GUINT g_buffer_managers_count = 0; + +#define VALIDATE_BUFFER_MANAGER(buffer_manager_id)\ + if(buffer_manager_id>=MAX_BUFFER_MANAGERS) return G_BUFFER_OP_INVALID;\ + GBUFFER_MANAGER_DATA * bm_data;\ + gim_get_buffer_manager_data(buffer_manager_id,&bm_data);\ + if(bm_data == 0) return G_BUFFER_OP_INVALID;\ + +#define VALIDATE_BUFFER_ID_PT(buffer_id)\ + VALIDATE_BUFFER_MANAGER(buffer_id->m_buffer_manager_id)\ + 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; +} + +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; +} + +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 = 0; + ptr = malloc(size); + /*if (g_allocfn) ptr = g_allocfn(size); else ptr = malloc(size);//_mm_malloc(size,0);*/ + if(ptr==0) + { + float * fp = 0; + *fp = 0.0f; + } + return ptr; +} + +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 (g_freefn) + { + g_freefn(ptr,size); + } + else + { + free(ptr);//_mm_free(ptr); + } +} + +///******************************* BUFFER MANAGERS ******************************/// + +//!** Basic buffer prototyoe functions + +GUINT _system_buffer_alloc_function(GUINT size,int usage) +{ + void * newdata = gim_alloc(size); + memset(newdata,0,size); + return (GUINT)(newdata); +} + +GUINT _system_buffer_alloc_data_function(const void * pdata,GUINT size,int usage) +{ + void * newdata = gim_alloc(size); + memcpy(newdata,pdata,size); + return (GUINT)(newdata); +} + +GUINT _system_buffer_realloc_function(GUINT buffer_handle,GUINT oldsize,int old_usage,GUINT newsize,int new_usage) +{ + void * newdata = gim_realloc((void *)buffer_handle,oldsize,newsize); + return (GUINT)(newdata); +} + +void _system_buffer_free_function(GUINT buffer_handle,GUINT size) +{ + gim_free((void*)buffer_handle,size); +} + +char * _system_lock_buffer_function(GUINT buffer_handle,int access) +{ + return (char * )(buffer_handle); +} + + +void _system_unlock_buffer_function(GUINT buffer_handle) +{ +} + +void _system_download_from_buffer_function( + GUINT source_buffer_handle, + GUINT source_pos, + void * destdata, + GUINT copysize) +{ + char * pdata; + pdata = (char *)source_buffer_handle; + memcpy(destdata,pdata+source_pos,copysize); +} + +void _system_upload_to_buffer_function( + GUINT dest_buffer_handle, + GUINT dest_pos, + void * sourcedata, + GUINT copysize) +{ + char * pdata; + pdata = (char * )dest_buffer_handle; + memcpy(pdata+dest_pos,sourcedata,copysize); +} + +void _system_copy_buffers_function( + GUINT source_buffer_handle, + GUINT source_pos, + GUINT dest_buffer_handle, + GUINT dest_pos, + GUINT copysize) +{ + char * pdata1,*pdata2; + pdata1 = (char *)source_buffer_handle; + pdata2 = (char *)dest_buffer_handle; + memcpy(pdata2+dest_pos,pdata1+source_pos,copysize); +} + +GUINT _shared_buffer_alloc_function(GUINT size,int usage) +{ + return 0; +} + +GUINT _shared_buffer_alloc_data_function(const void * pdata,GUINT size,int usage) +{ + return (GUINT)pdata; +} + +GUINT _shared_buffer_realloc_function(GUINT buffer_handle,GUINT oldsize,int old_usage,GUINT newsize,int new_usage) +{ + return 0; +} + +void _shared_buffer_free_function(GUINT buffer_handle,GUINT size) +{ +} + +//!** Buffer manager operations +void gim_create_buffer_manager(GBUFFER_MANAGER_PROTOTYPE * prototype,GUINT buffer_manager_id) +{ + GBUFFER_MANAGER_DATA * bm_data; + bm_data = &g_buffer_managers[buffer_manager_id]; + + if(bm_data->m_active==0) + { + if(g_buffer_managers_count<=buffer_manager_id) + { + g_buffer_managers_count = buffer_manager_id+1; + } + } + else + { + gim_destroy_buffer_manager(buffer_manager_id); + } + bm_data->m_active = 1; + //CREATE ARRAYS + GIM_DYNARRAY_CREATE(GBUFFER_DATA,bm_data->m_buffer_array,G_ARRAY_GROW_SIZE); + GIM_DYNARRAY_CREATE(GUINT,bm_data->m_free_positions,G_ARRAY_GROW_SIZE); + //INIT PROTOTYPE + bm_data->m_prototype.alloc_data_fn = prototype->alloc_data_fn; + bm_data->m_prototype.alloc_fn = prototype->alloc_fn; + bm_data->m_prototype.copy_buffers_fn = prototype->copy_buffers_fn; + bm_data->m_prototype.download_from_buffer_fn = prototype->download_from_buffer_fn; + bm_data->m_prototype.free_fn = prototype->free_fn; + bm_data->m_prototype.lock_buffer_fn = prototype->lock_buffer_fn; + bm_data->m_prototype.realloc_fn = prototype->realloc_fn; + bm_data->m_prototype.unlock_buffer_fn = prototype->unlock_buffer_fn; + bm_data->m_prototype.upload_to_buffer_fn = prototype->upload_to_buffer_fn; +} + +GUINT gim_get_buffer_manager_count() +{ + return g_buffer_managers_count; +} +void gim_destroy_buffer_manager(GUINT buffer_manager_id) +{ + GBUFFER_MANAGER_DATA * bm_data; + gim_get_buffer_manager_data(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); + GUINT i, buffer_count = bm_data->m_buffer_array.m_size; + for (i=0;im_prototype.free_fn(buffers[i].m_buffer_handle,buffers[i].m_size); + } + } + + //destroy buffer array + GIM_DYNARRAY_DESTROY(bm_data->m_buffer_array); + //destroy free positions + GIM_DYNARRAY_DESTROY(bm_data->m_free_positions); + //Mark as innactive + bm_data->m_active = 0; +} +void gim_get_buffer_manager_data(GUINT buffer_manager_id,GBUFFER_MANAGER_DATA ** pbm_data) +{ + GBUFFER_MANAGER_DATA * bm_data; + bm_data = &g_buffer_managers[buffer_manager_id]; + + if(bm_data->m_active==0) + { + *pbm_data = 0; + } + else + { + *pbm_data = bm_data; + } +} + +void gim_init_buffer_managers() +{ + GUINT i; + for (i=0;im_free_positions.m_size>0)\ + { + GUINT * _pointer = GIM_DYNARRAY_POINTER(GUINT,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); + } +} + +GINT _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; +} + +GUINT gim_create_buffer( + GUINT buffer_manager_id, + GUINT buffer_size, + int usage, + GBUFFER_ID * buffer_id) +{ + VALIDATE_BUFFER_MANAGER(buffer_manager_id) + + GUINT 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_buffer_manager_id = buffer_manager_id; + + 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_size,&pbuffer->m_shadow_buffer); + } + else + { + pbuffer->m_shadow_buffer.m_buffer_id = G_UINT_INFINITY; + pbuffer->m_shadow_buffer.m_buffer_manager_id = G_UINT_INFINITY; + } + return G_BUFFER_OP_SUCCESS; +} + + +GUINT gim_create_buffer_from_data( + GUINT buffer_manager_id, + const void * pdata, + GUINT buffer_size, + int usage, + GBUFFER_ID * buffer_id) +{ + VALIDATE_BUFFER_MANAGER(buffer_manager_id) + + GUINT 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_buffer_manager_id = buffer_manager_id; + + 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(pdata,buffer_size,&pbuffer->m_shadow_buffer); + } + else + { + pbuffer->m_shadow_buffer.m_buffer_id = G_UINT_INFINITY; + pbuffer->m_shadow_buffer.m_buffer_manager_id = G_UINT_INFINITY; + } + return G_BUFFER_OP_SUCCESS; +} + +GUINT gim_create_common_buffer(GUINT buffer_size, GBUFFER_ID * buffer_id) +{ + return gim_create_buffer(G_BUFFER_MANAGER_SYSTEM,buffer_size,G_MU_DYNAMIC_READ_WRITE,buffer_id); +} + +GUINT gim_create_common_buffer_from_data( + const void * pdata, GUINT buffer_size, GBUFFER_ID * buffer_id) +{ + return gim_create_buffer_from_data(G_BUFFER_MANAGER_SYSTEM,pdata,buffer_size,G_MU_DYNAMIC_READ_WRITE,buffer_id); +} + +GUINT gim_create_shared_buffer_from_data( + const void * pdata, GUINT buffer_size, GBUFFER_ID * buffer_id) +{ + return gim_create_buffer_from_data(G_BUFFER_MANAGER_SHARED,pdata,buffer_size,G_MU_DYNAMIC_READ_WRITE,buffer_id); +} + +GINT gim_buffer_realloc(GBUFFER_ID * buffer_id,GUINT newsize) +{ + VALIDATE_BUFFER_ID_PT(buffer_id) + if(pbuffer->m_lock_count>0) return G_BUFFER_OP_INVALID; + GUINT newhandle = 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; +} + +GINT gim_buffer_add_ref(GBUFFER_ID * buffer_id) +{ + VALIDATE_BUFFER_ID_PT(buffer_id) + pbuffer->m_refcount++; + return G_BUFFER_OP_SUCCESS; +} + +GINT 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; + + 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(GUINT,bm_data->m_free_positions,buffer_id->m_buffer_id); + pbuffer->m_buffer_handle = 0; + pbuffer->m_size = 0; + pbuffer->m_shadow_buffer.m_buffer_id = G_UINT_INFINITY; + pbuffer->m_shadow_buffer.m_buffer_manager_id = G_UINT_INFINITY; + return G_BUFFER_OP_SUCCESS; +} + +GINT 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; + + GUINT 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 = 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 = 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 = 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; +} + +GINT 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; + } + + + GUINT 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) + { + 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) + { + 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) + { + 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; +} + +GINT gim_get_buffer_size(GBUFFER_ID * buffer_id,GUINT * buffer_size) +{ + VALIDATE_BUFFER_ID_PT(buffer_id) + *buffer_size = pbuffer->m_size; + return G_BUFFER_OP_SUCCESS; +} + +GINT gim_get_buffer_is_locked(GBUFFER_ID * buffer_id,GUINT * lock_count) +{ + VALIDATE_BUFFER_ID_PT(buffer_id) + *lock_count = pbuffer->m_lock_count; + return G_BUFFER_OP_SUCCESS; +} + + +GINT gim_download_from_buffer( + GBUFFER_ID * buffer_id, + GUINT source_pos, + void * destdata, + GUINT copysize) +{ + VALIDATE_BUFFER_ID_PT(buffer_id) + bm_data->m_prototype.download_from_buffer_fn( + pbuffer->m_buffer_handle,source_pos,destdata,copysize); + return G_BUFFER_OP_SUCCESS; +} + +GINT gim_upload_to_buffer( + GBUFFER_ID * buffer_id, + GUINT dest_pos, + void * sourcedata, + GUINT copysize) +{ + VALIDATE_BUFFER_ID_PT(buffer_id) + bm_data->m_prototype.upload_to_buffer_fn( + pbuffer->m_buffer_handle,dest_pos,sourcedata,copysize); + return G_BUFFER_OP_SUCCESS; +} + +GINT gim_copy_buffers( + GBUFFER_ID * source_buffer_id, + GUINT source_pos, + GBUFFER_ID * dest_buffer_id, + GUINT dest_pos, + GUINT 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((source_buffer_id->m_buffer_manager_id == dest_buffer_id->m_buffer_manager_id)|| + (source_buffer_id->m_buffer_manager_id == G_BUFFER_MANAGER_SYSTEM && dest_buffer_id->m_buffer_manager_id == G_BUFFER_MANAGER_SHARED)|| + (source_buffer_id->m_buffer_manager_id == G_BUFFER_MANAGER_SHARED && dest_buffer_id->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(source_buffer_id->m_buffer_manager_id == G_BUFFER_MANAGER_SYSTEM || source_buffer_id->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; +} + +GINT gim_buffer_array_lock(GBUFFER_ARRAY * array_data, int access) +{ + if(array_data->m_buffer_data != 0) return G_BUFFER_OP_SUCCESS; + GINT 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; +} + +GINT gim_buffer_array_unlock(GBUFFER_ARRAY * array_data) +{ + if(array_data->m_buffer_data == 0) return G_BUFFER_OP_SUCCESS; + GINT 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_buffer_manager_id = source_data->m_buffer_id.m_buffer_manager_id; + 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_ARRAY * dest_data, GUINT buffer_manager_id,int usage) +{ + //Create new buffer + GUINT buffsize = source_data->m_element_count*source_data->m_byte_stride; + gim_create_buffer(buffer_manager_id,buffsize,usage,&dest_data->m_buffer_id); + + //copy ref data + dest_data->m_buffer_data = 0; + dest_data->m_byte_stride = source_data->m_byte_stride; + dest_data->m_byte_offset = 0; + dest_data->m_element_count = source_data->m_element_count; + gim_buffer_add_ref(&dest_data->m_buffer_id); + //copy buffers + gim_copy_buffers(&source_data->m_buffer_id,source_data->m_byte_offset,&dest_data->m_buffer_id,0,buffsize); +} diff --git a/libraries/ode-0.9/GIMPACT/src/gim_tri_tri_overlap.cpp b/libraries/ode-0.9/GIMPACT/src/gim_tri_tri_overlap.cpp new file mode 100644 index 0000000000..5b4e08d314 --- /dev/null +++ b/libraries/ode-0.9/GIMPACT/src/gim_tri_tri_overlap.cpp @@ -0,0 +1,251 @@ + +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + +#include "GIMPACT/gim_trimesh.h" + + +#define FABS(x) (float(fabs(x))) /* implement as is fastest on your machine */ + +/* some macros */ + +#define CLASSIFY_TRIPOINTS_BY_FACE(v1,v2,v3,faceplane,out_of_face)\ +{ \ + _distances[0] = DISTANCE_PLANE_POINT(faceplane,v1);\ + _distances[1] = _distances[0] * DISTANCE_PLANE_POINT(faceplane,v2);\ + _distances[2] = _distances[0] * DISTANCE_PLANE_POINT(faceplane,v3); \ + if(_distances[1]>0.0f && _distances[2]>0.0f)\ + {\ + out_of_face = 1;\ + }\ + else\ + {\ + out_of_face = 0;\ + }\ +}\ + +/* sort so that a<=b */ +#define SORT(a,b) \ + if(a>b) \ + { \ + float c; \ + c=a; \ + a=b; \ + b=c; \ + } + + +/* this edge to edge test is based on Franlin Antonio's gem: + "Faster Line Segment Intersection", in Graphics Gems III, + pp. 199-202 */ +#define EDGE_EDGE_TEST(V0,U0,U1) \ + Bx=U0[i0]-U1[i0]; \ + By=U0[i1]-U1[i1]; \ + Cx=V0[i0]-U0[i0]; \ + Cy=V0[i1]-U0[i1]; \ + f=Ay*Bx-Ax*By; \ + d=By*Cx-Bx*Cy; \ + if((f>0 && d>=0 && d<=f) || (f<0 && d<=0 && d>=f)) \ + { \ + e=Ax*Cy-Ay*Cx; \ + if(f>0) \ + { \ + if(e>=0 && e<=f) return 1; \ + } \ + else \ + { \ + if(e<=0 && e>=f) return 1; \ + } \ + } + +#define EDGE_AGAINST_TRI_EDGES(V0,V1,U0,U1,U2) \ +{ \ + float Ax,Ay,Bx,By,Cx,Cy,e,d,f; \ + Ax=V1[i0]-V0[i0]; \ + Ay=V1[i1]-V0[i1]; \ + /* test edge U0,U1 against V0,V1 */ \ + EDGE_EDGE_TEST(V0,U0,U1); \ + /* test edge U1,U2 against V0,V1 */ \ + EDGE_EDGE_TEST(V0,U1,U2); \ + /* test edge U2,U1 against V0,V1 */ \ + EDGE_EDGE_TEST(V0,U2,U0); \ +} + +#define POINT_IN_TRI(V0,U0,U1,U2) \ +{ \ + float a,b,c,d0,d1,d2; \ + /* is T1 completly inside T2? */ \ + /* check if V0 is inside tri(U0,U1,U2) */ \ + a=U1[i1]-U0[i1]; \ + b=-(U1[i0]-U0[i0]); \ + c=-a*U0[i0]-b*U0[i1]; \ + d0=a*V0[i0]+b*V0[i1]+c; \ + \ + a=U2[i1]-U1[i1]; \ + b=-(U2[i0]-U1[i0]); \ + c=-a*U1[i0]-b*U1[i1]; \ + d1=a*V0[i0]+b*V0[i1]+c; \ + \ + a=U0[i1]-U2[i1]; \ + b=-(U0[i0]-U2[i0]); \ + c=-a*U2[i0]-b*U2[i1]; \ + d2=a*V0[i0]+b*V0[i1]+c; \ + if(d0*d1>0.0) \ + { \ + if(d0*d2>0.0) return 1; \ + } \ +} + +int coplanar_tri_tri(GIM_TRIANGLE_DATA *tri1, + GIM_TRIANGLE_DATA *tri2) +{ + short i0,i1; + /* first project onto an axis-aligned plane, that maximizes the area */ + /* of the triangles, compute indices: i0,i1. */ + PLANE_MINOR_AXES(tri1->m_planes.m_planes[0], i0, i1); + + /* test all edges of triangle 1 against the edges of triangle 2 */ + EDGE_AGAINST_TRI_EDGES(tri1->m_vertices[0],tri1->m_vertices[1],tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2]); + EDGE_AGAINST_TRI_EDGES(tri1->m_vertices[1],tri1->m_vertices[2],tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2]); + EDGE_AGAINST_TRI_EDGES(tri1->m_vertices[2],tri1->m_vertices[0],tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2]); + + /* finally, test if tri1 is totally contained in tri2 or vice versa */ + POINT_IN_HULL(tri1->m_vertices[0],(&tri2->m_planes.m_planes[1]),3,i0); + if(i0==0) return 1; + + POINT_IN_HULL(tri2->m_vertices[0],(&tri1->m_planes.m_planes[1]),3,i0); + if(i0==0) return 1; + + return 0; +} + + + +#define NEWCOMPUTE_INTERVALS(VV0,VV1,VV2,D0,D1,D2,D0D1,D0D2,A,B,C,X0,X1) \ +{ \ + if(D0D1>0.0f) \ + { \ + /* here we know that D0D2<=0.0 */ \ + /* that is D0, D1 are on the same side, D2 on the other or on the plane */ \ + A=VV2; B=(VV0-VV2)*D2; C=(VV1-VV2)*D2; X0=D2-D0; X1=D2-D1; \ + } \ + else if(D0D2>0.0f)\ + { \ + /* here we know that d0d1<=0.0 */ \ + A=VV1; B=(VV0-VV1)*D1; C=(VV2-VV1)*D1; X0=D1-D0; X1=D1-D2; \ + } \ + else if(D1*D2>0.0f || D0!=0.0f) \ + { \ + /* here we know that d0d1<=0.0 or that D0!=0.0 */ \ + A=VV0; B=(VV1-VV0)*D0; C=(VV2-VV0)*D0; X0=D0-D1; X1=D0-D2; \ + } \ + else if(D1!=0.0f) \ + { \ + A=VV1; B=(VV0-VV1)*D1; C=(VV2-VV1)*D1; X0=D1-D0; X1=D1-D2; \ + } \ + else if(D2!=0.0f) \ + { \ + A=VV2; B=(VV0-VV2)*D2; C=(VV1-VV2)*D2; X0=D2-D0; X1=D2-D1; \ + } \ + else \ + { \ + /* triangles are coplanar */ \ + return coplanar_tri_tri(tri1,tri2); \ + } \ +}\ + + + +int gim_triangle_triangle_overlap( + GIM_TRIANGLE_DATA *tri1, + GIM_TRIANGLE_DATA *tri2) +{ + vec3f _distances; + char out_of_face; + CLASSIFY_TRIPOINTS_BY_FACE(tri1->m_vertices[0],tri1->m_vertices[1],tri1->m_vertices[2],tri2->m_planes.m_planes[0],out_of_face); + if(out_of_face==1) return 0; + + CLASSIFY_TRIPOINTS_BY_FACE(tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2],tri1->m_planes.m_planes[0],out_of_face); + if(out_of_face==1) return 0; + + + float du0=0,du1=0,du2=0,dv0=0,dv1=0,dv2=0; + float D[3]; + float isect1[2], isect2[2]; + float du0du1=0,du0du2=0,dv0dv1=0,dv0dv2=0; + short index; + float vp0,vp1,vp2; + float up0,up1,up2; + float bb,cc,max; + + /* compute direction of intersection line */ + VEC_CROSS(D,tri1->m_planes.m_planes[0],tri2->m_planes.m_planes[0]); + + /* compute and index to the largest component of D */ + max=(float)FABS(D[0]); + index=0; + bb=(float)FABS(D[1]); + cc=(float)FABS(D[2]); + if(bb>max) max=bb,index=1; + if(cc>max) max=cc,index=2; + + /* this is the simplified projection onto L*/ + vp0= tri1->m_vertices[0][index]; + vp1= tri1->m_vertices[1][index]; + vp2= tri1->m_vertices[2][index]; + + up0= tri2->m_vertices[0][index]; + up1= tri2->m_vertices[1][index]; + up2= tri2->m_vertices[2][index]; + + /* compute interval for triangle 1 */ + float a,b,c,x0,x1; + NEWCOMPUTE_INTERVALS(vp0,vp1,vp2,dv0,dv1,dv2,dv0dv1,dv0dv2,a,b,c,x0,x1); + + /* compute interval for triangle 2 */ + float d,e,f,y0,y1; + NEWCOMPUTE_INTERVALS(up0,up1,up2,du0,du1,du2,du0du1,du0du2,d,e,f,y0,y1); + + float xx,yy,xxyy,tmp; + xx=x0*x1; + yy=y0*y1; + xxyy=xx*yy; + + tmp=a*xxyy; + isect1[0]=tmp+b*x1*yy; + isect1[1]=tmp+c*x0*yy; + + tmp=d*xxyy; + isect2[0]=tmp+e*xx*y1; + isect2[1]=tmp+f*xx*y0; + + SORT(isect1[0],isect1[1]); + SORT(isect2[0],isect2[1]); + + if(isect1[1] +#include "GIMPACT/gim_trimesh.h" + +GUINT 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(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,&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 + GUINT 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(GIM_TRIMESH * trimesh, vec3f * vertex_array, GUINT vertex_count,char copy_vertices, GUINT * triindex_array, GUINT 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(vertex_array, vertex_count*sizeof(vec3f), &buffer_vertex_array.m_buffer_id); + } + else//Create a shared buffer + { + gim_create_shared_buffer_from_data(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(triindex_array, index_count*sizeof(GUINT), &buffer_triindex_array.m_buffer_id); + } + else//Create a shared buffer + { + gim_create_shared_buffer_from_data(triindex_array, index_count*sizeof(GUINT), &buffer_triindex_array.m_buffer_id); + } + GIM_BUFFER_ARRAY_INIT_TYPE(GUINT,buffer_triindex_array,buffer_triindex_array.m_buffer_id,index_count); + + gim_trimesh_create_from_arrays(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,GIM_TRIMESH * dest_trimesh, char copy_by_reference, char transformed_reply) +{ + 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,&buffer_vertex_array,G_BUFFER_MANAGER_SYSTEM,G_MU_DYNAMIC_READ_WRITE); + + gim_buffer_array_copy_value(&source_trimesh->m_tri_index_buffer,&buffer_triindex_array,G_BUFFER_MANAGER_SYSTEM,G_MU_DYNAMIC_READ_WRITE); + + gim_trimesh_create_from_arrays(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) +{ + GINT 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); + + GUINT * triangle_indices = GIM_BUFFER_ARRAY_POINTER(GUINT,trimesh->m_tri_index_buffer,0); + assert(triangle_indices); + // box set + aabb3f * paabb = trimesh->m_aabbset.m_boxes; + GUINT triangle_count = gim_trimesh_get_triangle_count(trimesh); + float * v1,*v2,*v3; + GUINT 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]; + GUINT 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, GUINT triangle_index, GIM_TRIANGLE_DATA * tri_data) +{ + vec3f * transformed_vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_transformed_vertex_buffer,0); + + GUINT * triangle_indices = GIM_BUFFER_ARRAY_POINTER(GUINT,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 + GUINT 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, GUINT triangle_index, vec3f v1,vec3f v2,vec3f v3) +{ + vec3f * transformed_vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_transformed_vertex_buffer,0); + + GUINT * triangle_indices = GIM_BUFFER_ARRAY_POINTER(GUINT,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]]); +} diff --git a/libraries/ode-0.9/GIMPACT/src/gim_trimesh_capsule_collision.cpp b/libraries/ode-0.9/GIMPACT/src/gim_trimesh_capsule_collision.cpp new file mode 100644 index 0000000000..d1f7ca3864 --- /dev/null +++ b/libraries/ode-0.9/GIMPACT/src/gim_trimesh_capsule_collision.cpp @@ -0,0 +1,279 @@ + +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + +#include "GIMPACT/gim_trimesh.h" + +//! Utility function for find the closest point between a segment and a triangle +/*! + +\param triangle +\param s1 +\param s2 +\param contacts Contains the closest points on the segment (1,2), and the normal points to segment, and m_depth contains the distance + +\post The contacts array is not set to 0. It adds aditional contacts +*/ +void gim_closest_point_triangle_segment(GIM_TRIANGLE_DATA * triangle, vec3f s1,vec3f s2, GDYNAMIC_ARRAY * contacts) +{ + vec3f segment_points[4]; + vec3f closest_points[2]; + GUINT intersection_type, out_edge= 10; + GREAL dis, dis_temp,perpend; + vec4f sdiff; + + dis = DISTANCE_PLANE_POINT(triangle->m_planes.m_planes[0],s1); + dis_temp = DISTANCE_PLANE_POINT(triangle->m_planes.m_planes[0],s2); + + if(dis<=0.0f && dis_temp<=0.0f) return; + + VEC_DIFF(sdiff,s2,s1); + perpend = VEC_DOT(sdiff,triangle->m_planes.m_planes[0]); + + if(!IS_ZERO(perpend)) // Not perpendicular + { + if(dis=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; + GUINT 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) +{ + GUINT old_contact_size = contacts->m_size; + gim_closest_point_triangle_segment(triangle,capsule->m_point1,capsule->m_point2,contacts); + 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; + GUINT * boxesresult = GIM_DYNARRAY_POINTER(GUINT,collision_result); + GIM_TRIANGLE_DATA tri_data; + GUINT 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); +} diff --git a/libraries/ode-0.9/GIMPACT/src/gim_trimesh_ray_collision.cpp b/libraries/ode-0.9/GIMPACT/src/gim_trimesh_ray_collision.cpp new file mode 100644 index 0000000000..0c10fe1964 --- /dev/null +++ b/libraries/ode-0.9/GIMPACT/src/gim_trimesh_ray_collision.cpp @@ -0,0 +1,140 @@ + +/* +----------------------------------------------------------------------------- +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 + + GUINT * boxesresult = GIM_DYNARRAY_POINTER(GUINT,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,tridata.m_planes.m_planes[0]); + + 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 + + GUINT * boxesresult = GIM_DYNARRAY_POINTER(GUINT,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,tridata.m_planes.m_planes[0]); + } + } + + gim_trimesh_unlocks_work_data(trimesh); + GIM_DYNARRAY_DESTROY(collision_result); + if(contact->tparam > tmax) return 0; + return 1; +} diff --git a/libraries/ode-0.9/GIMPACT/src/gim_trimesh_sphere_collision.cpp b/libraries/ode-0.9/GIMPACT/src/gim_trimesh_sphere_collision.cpp new file mode 100644 index 0000000000..60444fb607 --- /dev/null +++ b/libraries/ode-0.9/GIMPACT/src/gim_trimesh_sphere_collision.cpp @@ -0,0 +1,196 @@ + +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + GIMPACT-LICENSE-LGPL.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + +#include "GIMPACT/gim_trimesh.h" + +int gim_triangle_sphere_collision( + GIM_TRIANGLE_DATA *tri, + vec3f center, GREAL radius, + GIM_TRIANGLE_CONTACT_DATA * contact_data) +{ + contact_data->m_point_count = 0; + + //Find Face plane distance + GREAL dis = DISTANCE_PLANE_POINT(tri->m_planes.m_planes[0],center); + if(dis>radius) return 0; //out + if(dis<-radius) return 0;//Out of triangle + contact_data->m_penetration_depth = dis; + + //Find the most edge + GUINT 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; + GUINT * boxesresult = GIM_DYNARRAY_POINTER(GUINT,collision_result); + GIM_TRIANGLE_CONTACT_DATA tri_contact_data; + GIM_TRIANGLE_DATA tri_data; + + for(i=0;i0.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;\ + GUINT _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 + GUINT _max_candidates[MAX_TRI_CLIPPING]; + vec3f _temp_clip[MAX_TRI_CLIPPING]; + GUINT _temp_clip_count = 0; + vec3f _temp_clip2[MAX_TRI_CLIPPING]; + GUINT _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 + GUINT mostdir=0; + GUINT 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 + GUINT 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 + + GUINT 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 + GUINT 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; + + + GUINT 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 + GUINT i, vertcount = trimesh->m_transformed_vertex_buffer.m_element_count; + vec3f * vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_transformed_vertex_buffer,0); + + GREAL dist; + vec4f * result_contact; + + for (i=0;i + 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! diff --git a/libraries/ode-0.9/Makefile.am b/libraries/ode-0.9/Makefile.am new file mode 100644 index 0000000000..4b33d05c2e --- /dev/null +++ b/libraries/ode-0.9/Makefile.am @@ -0,0 +1,37 @@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +libtool: $(LIBTOOL_DEPS) + $(SHELL) ./config.status --recheck + +if ENABLE_DEMOS +SUBDIRS = include drawstuff ode tests +else +SUBDIRS = include ode tests +endif + +bin_SCRIPTS = ode-config + +# Utility rule for making a release +release: dist dist-bz2 dist-zip + @echo Created release packages for ${PACKAGE}-${VERSION}. + +# Rules for creating .tar.bz2 and .zip packages +dist-bz2: ${PACKAGE}-${VERSION}.tar.gz + gzip -dc ${PACKAGE}-${VERSION}.tar.gz | bzip2 > ${PACKAGE}-${VERSION}.tar.bz2 + +dist-zip: ${PACKAGE}-${VERSION}.tar.gz + tar -zxf ${PACKAGE}-${VERSION}.tar.gz && \ + zip -r ${PACKAGE}-${VERSION}.zip ${PACKAGE}-${VERSION} && \ + rm -rf ${PACKAGE}-${VERSION} + +if USE_SONAME +install-exec-hook: + ln -s $(libdir)/@ODE_SONAME@.@ODE_REVISION@.@ODE_AGE@ \ + $(libdir)/libode.so + ln -s $(libdir)/@ODE_SONAME@.@ODE_REVISION@.@ODE_AGE@ \ + $(libdir)/@ODE_SONAME@ + ln -s $(libdir)/@ODE_SONAME@.@ODE_REVISION@.@ODE_AGE@ \ + $(libdir)/@ODE_SONAME@.@ODE_REVISION@ + /sbin/ldconfig +else +install-exec-hook: +endif diff --git a/libraries/ode-0.9/Makefile.deps b/libraries/ode-0.9/Makefile.deps new file mode 100644 index 0000000000..8d9e8ba7fc --- /dev/null +++ b/libraries/ode-0.9/Makefile.deps @@ -0,0 +1,1845 @@ +ode/src/array.o: \ + ode/src/array.cpp \ + include/ode/config.h \ + include/ode/memory.h \ + include/ode/error.h \ + ode/src/array.h +ode/src/error.o: \ + ode/src/error.cpp \ + include/ode/config.h \ + include/ode/error.h +ode/src/memory.o: \ + ode/src/memory.cpp \ + include/ode/config.h \ + include/ode/memory.h \ + include/ode/error.h +ode/src/obstack.o: \ + ode/src/obstack.cpp \ + include/ode/common.h \ + include/ode/config.h \ + include/ode/error.h \ + include/ode/memory.h \ + ode/src/obstack.h \ + ode/src/objects.h \ + include/ode/mass.h \ + ode/src/array.h +ode/src/odemath.o: \ + ode/src/odemath.cpp \ + include/ode/common.h \ + include/ode/config.h \ + include/ode/error.h \ + include/ode/odemath.h +ode/src/matrix.o: \ + ode/src/matrix.cpp \ + include/ode/common.h \ + include/ode/config.h \ + include/ode/error.h \ + include/ode/matrix.h +ode/src/misc.o: \ + ode/src/misc.cpp \ + include/ode/config.h \ + include/ode/misc.h \ + include/ode/common.h \ + include/ode/error.h \ + include/ode/matrix.h +ode/src/rotation.o: \ + ode/src/rotation.cpp \ + include/ode/rotation.h \ + include/ode/common.h \ + include/ode/config.h \ + include/ode/error.h \ + include/ode/compatibility.h \ + include/ode/odemath.h +ode/src/mass.o: \ + ode/src/mass.cpp \ + include/ode/config.h \ + include/ode/mass.h \ + include/ode/common.h \ + include/ode/error.h \ + include/ode/odemath.h \ + include/ode/matrix.h +ode/src/ode.o: \ + ode/src/ode.cpp \ + ode/src/objects.h \ + include/ode/common.h \ + include/ode/config.h \ + include/ode/error.h \ + include/ode/memory.h \ + include/ode/mass.h \ + ode/src/array.h \ + include/ode/ode.h \ + include/ode/compatibility.h \ + include/ode/contact.h \ + include/ode/odemath.h \ + include/ode/matrix.h \ + include/ode/timer.h \ + include/ode/rotation.h \ + include/ode/misc.h \ + include/ode/objects.h \ + include/ode/odecpp.h \ + include/ode/collision_space.h \ + include/ode/collision.h \ + include/ode/collision_trimesh.h \ + include/ode/odecpp_collision.h \ + include/ode/export-dif.h \ + ode/src/joint.h \ + ode/src/obstack.h \ + ode/src/step.h \ + ode/src/quickstep.h \ + ode/src/util.h +ode/src/step.o: \ + ode/src/step.cpp \ + ode/src/objects.h \ + include/ode/common.h \ + include/ode/config.h \ + include/ode/error.h \ + include/ode/memory.h \ + include/ode/mass.h \ + ode/src/array.h \ + ode/src/joint.h \ + include/ode/contact.h \ + ode/src/obstack.h \ + include/ode/odemath.h \ + include/ode/rotation.h \ + include/ode/compatibility.h \ + include/ode/timer.h \ + include/ode/matrix.h \ + ode/src/lcp.h \ + ode/src/util.h +ode/src/stepfast.o: \ + ode/src/stepfast.cpp \ + ode/src/objects.h \ + include/ode/common.h \ + include/ode/config.h \ + include/ode/error.h \ + include/ode/memory.h \ + include/ode/mass.h \ + ode/src/array.h \ + ode/src/joint.h \ + include/ode/contact.h \ + ode/src/obstack.h \ + include/ode/objects.h \ + include/ode/odemath.h \ + include/ode/rotation.h \ + include/ode/compatibility.h \ + include/ode/timer.h \ + include/ode/matrix.h \ + include/ode/misc.h \ + ode/src/lcp.h \ + ode/src/step.h \ + ode/src/util.h +ode/src/quickstep.o: \ + ode/src/quickstep.cpp \ + ode/src/objects.h \ + include/ode/common.h \ + include/ode/config.h \ + include/ode/error.h \ + include/ode/memory.h \ + include/ode/mass.h \ + ode/src/array.h \ + ode/src/joint.h \ + include/ode/contact.h \ + ode/src/obstack.h \ + include/ode/odemath.h \ + include/ode/rotation.h \ + include/ode/compatibility.h \ + include/ode/timer.h \ + include/ode/matrix.h \ + ode/src/lcp.h \ + ode/src/util.h +ode/src/util.o: \ + ode/src/util.cpp \ + include/ode/ode.h \ + include/ode/config.h \ + include/ode/compatibility.h \ + include/ode/common.h \ + include/ode/error.h \ + include/ode/contact.h \ + include/ode/memory.h \ + include/ode/odemath.h \ + include/ode/matrix.h \ + include/ode/timer.h \ + include/ode/rotation.h \ + include/ode/mass.h \ + include/ode/misc.h \ + include/ode/objects.h \ + include/ode/odecpp.h \ + include/ode/collision_space.h \ + include/ode/collision.h \ + include/ode/collision_trimesh.h \ + include/ode/odecpp_collision.h \ + include/ode/export-dif.h \ + ode/src/objects.h \ + ode/src/array.h \ + ode/src/joint.h \ + ode/src/obstack.h \ + ode/src/util.h +ode/src/lcp.o: \ + ode/src/lcp.cpp \ + include/ode/common.h \ + include/ode/config.h \ + include/ode/error.h \ + ode/src/lcp.h \ + include/ode/matrix.h \ + include/ode/misc.h \ + ode/src/mat.h \ + include/ode/timer.h +ode/src/joint.o: \ + ode/src/joint.cpp \ + include/ode/odemath.h \ + include/ode/common.h \ + include/ode/config.h \ + include/ode/error.h \ + include/ode/rotation.h \ + include/ode/compatibility.h \ + include/ode/matrix.h \ + ode/src/joint.h \ + ode/src/objects.h \ + include/ode/memory.h \ + include/ode/mass.h \ + ode/src/array.h \ + include/ode/contact.h \ + ode/src/obstack.h +ode/src/timer.o: \ + ode/src/timer.cpp \ + include/ode/common.h \ + include/ode/config.h \ + include/ode/error.h \ + include/ode/timer.h +ode/src/mat.o: \ + ode/src/mat.cpp \ + include/ode/config.h \ + include/ode/misc.h \ + include/ode/common.h \ + include/ode/error.h \ + include/ode/matrix.h \ + include/ode/memory.h \ + ode/src/mat.h +ode/src/testing.o: \ + ode/src/testing.cpp \ + include/ode/config.h \ + include/ode/misc.h \ + include/ode/common.h \ + include/ode/error.h \ + include/ode/memory.h \ + ode/src/testing.h \ + ode/src/array.h +ode/src/export-dif.o: \ + ode/src/export-dif.cpp \ + include/ode/ode.h \ + include/ode/config.h \ + include/ode/compatibility.h \ + include/ode/common.h \ + include/ode/error.h \ + include/ode/contact.h \ + include/ode/memory.h \ + include/ode/odemath.h \ + include/ode/matrix.h \ + include/ode/timer.h \ + include/ode/rotation.h \ + include/ode/mass.h \ + include/ode/misc.h \ + include/ode/objects.h \ + include/ode/odecpp.h \ + include/ode/collision_space.h \ + include/ode/collision.h \ + include/ode/collision_trimesh.h \ + include/ode/odecpp_collision.h \ + include/ode/export-dif.h \ + ode/src/objects.h \ + ode/src/array.h \ + ode/src/joint.h \ + ode/src/obstack.h \ + ode/src/collision_kernel.h +ode/src/collision_kernel.o: \ + ode/src/collision_kernel.cpp \ + include/ode/common.h \ + include/ode/config.h \ + include/ode/error.h \ + include/ode/matrix.h \ + include/ode/rotation.h \ + include/ode/compatibility.h \ + include/ode/objects.h \ + include/ode/mass.h \ + include/ode/contact.h \ + ode/src/collision_kernel.h \ + include/ode/collision.h \ + include/ode/collision_space.h \ + include/ode/collision_trimesh.h \ + ode/src/objects.h \ + include/ode/memory.h \ + ode/src/array.h \ + ode/src/collision_util.h \ + ode/src/collision_std.h \ + ode/src/collision_transform.h \ + ode/src/collision_trimesh_internal.h +ode/src/collision_util.o: \ + ode/src/collision_util.cpp \ + include/ode/common.h \ + include/ode/config.h \ + include/ode/error.h \ + include/ode/collision.h \ + include/ode/collision_space.h \ + include/ode/contact.h \ + include/ode/collision_trimesh.h \ + include/ode/odemath.h \ + ode/src/collision_util.h +ode/src/collision_std.o: \ + ode/src/collision_std.cpp \ + include/ode/common.h \ + include/ode/config.h \ + include/ode/error.h \ + include/ode/collision.h \ + include/ode/collision_space.h \ + include/ode/contact.h \ + include/ode/collision_trimesh.h \ + include/ode/matrix.h \ + include/ode/rotation.h \ + include/ode/compatibility.h \ + include/ode/odemath.h \ + ode/src/collision_kernel.h \ + ode/src/objects.h \ + include/ode/memory.h \ + include/ode/mass.h \ + ode/src/array.h \ + ode/src/collision_std.h \ + ode/src/collision_util.h +ode/src/collision_space.o: \ + ode/src/collision_space.cpp \ + include/ode/common.h \ + include/ode/config.h \ + include/ode/error.h \ + include/ode/matrix.h \ + include/ode/collision_space.h \ + include/ode/collision.h \ + include/ode/contact.h \ + include/ode/collision_trimesh.h \ + ode/src/collision_kernel.h \ + ode/src/objects.h \ + include/ode/memory.h \ + include/ode/mass.h \ + ode/src/array.h \ + ode/src/collision_space_internal.h +ode/src/collision_transform.o: \ + ode/src/collision_transform.cpp \ + include/ode/collision.h \ + include/ode/common.h \ + include/ode/config.h \ + include/ode/error.h \ + include/ode/collision_space.h \ + include/ode/contact.h \ + include/ode/collision_trimesh.h \ + include/ode/matrix.h \ + include/ode/rotation.h \ + include/ode/compatibility.h \ + include/ode/odemath.h \ + ode/src/collision_transform.h \ + ode/src/collision_kernel.h \ + ode/src/objects.h \ + include/ode/memory.h \ + include/ode/mass.h \ + ode/src/array.h \ + ode/src/collision_util.h +ode/src/collision_quadtreespace.o: \ + ode/src/collision_quadtreespace.cpp \ + include/ode/common.h \ + include/ode/config.h \ + include/ode/error.h \ + include/ode/matrix.h \ + include/ode/collision_space.h \ + include/ode/collision.h \ + include/ode/contact.h \ + include/ode/collision_trimesh.h \ + ode/src/collision_kernel.h \ + ode/src/objects.h \ + include/ode/memory.h \ + include/ode/mass.h \ + ode/src/array.h \ + ode/src/collision_space_internal.h +ode/src/OPC_AABBCollider.o: \ + OPCODE/OPC_AABBCollider.cpp \ + OPCODE/Stdafx.h \ + OPCODE/Opcode.h \ + OPCODE/OPC_IceHook.h \ + OPCODE/Ice/IcePreprocessor.h \ + OPCODE/Ice/IceTypes.h \ + OPCODE/Ice/IceFPU.h \ + OPCODE/Ice/IceMemoryMacros.h \ + OPCODE/Ice/IceUtils.h \ + OPCODE/Ice/IceContainer.h \ + OPCODE/Ice/IcePairs.h \ + OPCODE/Ice/IceRevisitedRadix.h \ + OPCODE/Ice/IceRandom.h \ + OPCODE/Ice/IceAxes.h \ + OPCODE/Ice/IcePoint.h \ + OPCODE/Ice/IceHPoint.h \ + OPCODE/Ice/IceMatrix3x3.h \ + OPCODE/Ice/IceMatrix4x4.h \ + OPCODE/Ice/IcePlane.h \ + OPCODE/Ice/IceRay.h \ + OPCODE/Ice/IceIndexedTriangle.h \ + OPCODE/Ice/IceTriangle.h \ + OPCODE/Ice/IceTriList.h \ + OPCODE/Ice/IceAABB.h \ + OPCODE/Ice/IceOBB.h \ + OPCODE/Ice/IceBoundingSphere.h \ + OPCODE/Ice/IceSegment.h \ + OPCODE/Ice/IceLSS.h \ + OPCODE/OPC_Settings.h \ + OPCODE/OPC_Common.h \ + OPCODE/OPC_MeshInterface.h \ + OPCODE/OPC_TreeBuilders.h \ + OPCODE/OPC_AABBTree.h \ + OPCODE/OPC_OptimizedTree.h \ + OPCODE/OPC_BaseModel.h \ + OPCODE/OPC_Model.h \ + OPCODE/OPC_HybridModel.h \ + OPCODE/OPC_Collider.h \ + OPCODE/OPC_VolumeCollider.h \ + OPCODE/OPC_TreeCollider.h \ + OPCODE/OPC_RayCollider.h \ + OPCODE/OPC_SphereCollider.h \ + OPCODE/OPC_OBBCollider.h \ + OPCODE/OPC_AABBCollider.h \ + OPCODE/OPC_LSSCollider.h \ + OPCODE/OPC_PlanesCollider.h \ + OPCODE/OPC_Picking.h \ + OPCODE/OPC_BoxPruning.h \ + OPCODE/OPC_SweepAndPrune.h \ + OPCODE/OPC_BoxBoxOverlap.h \ + OPCODE/OPC_TriBoxOverlap.h +ode/src/OPC_AABBTree.o: \ + OPCODE/OPC_AABBTree.cpp \ + OPCODE/Stdafx.h \ + OPCODE/Opcode.h \ + OPCODE/OPC_IceHook.h \ + OPCODE/Ice/IcePreprocessor.h \ + OPCODE/Ice/IceTypes.h \ + OPCODE/Ice/IceFPU.h \ + OPCODE/Ice/IceMemoryMacros.h \ + OPCODE/Ice/IceUtils.h \ + OPCODE/Ice/IceContainer.h \ + OPCODE/Ice/IcePairs.h \ + OPCODE/Ice/IceRevisitedRadix.h \ + OPCODE/Ice/IceRandom.h \ + OPCODE/Ice/IceAxes.h \ + OPCODE/Ice/IcePoint.h \ + OPCODE/Ice/IceHPoint.h \ + OPCODE/Ice/IceMatrix3x3.h \ + OPCODE/Ice/IceMatrix4x4.h \ + OPCODE/Ice/IcePlane.h \ + OPCODE/Ice/IceRay.h \ + OPCODE/Ice/IceIndexedTriangle.h \ + OPCODE/Ice/IceTriangle.h \ + OPCODE/Ice/IceTriList.h \ + OPCODE/Ice/IceAABB.h \ + OPCODE/Ice/IceOBB.h \ + OPCODE/Ice/IceBoundingSphere.h \ + OPCODE/Ice/IceSegment.h \ + OPCODE/Ice/IceLSS.h \ + OPCODE/OPC_Settings.h \ + OPCODE/OPC_Common.h \ + OPCODE/OPC_MeshInterface.h \ + OPCODE/OPC_TreeBuilders.h \ + OPCODE/OPC_AABBTree.h \ + OPCODE/OPC_OptimizedTree.h \ + OPCODE/OPC_BaseModel.h \ + OPCODE/OPC_Model.h \ + OPCODE/OPC_HybridModel.h \ + OPCODE/OPC_Collider.h \ + OPCODE/OPC_VolumeCollider.h \ + OPCODE/OPC_TreeCollider.h \ + OPCODE/OPC_RayCollider.h \ + OPCODE/OPC_SphereCollider.h \ + OPCODE/OPC_OBBCollider.h \ + OPCODE/OPC_AABBCollider.h \ + OPCODE/OPC_LSSCollider.h \ + OPCODE/OPC_PlanesCollider.h \ + OPCODE/OPC_Picking.h \ + OPCODE/OPC_BoxPruning.h \ + OPCODE/OPC_SweepAndPrune.h +ode/src/OPC_BaseModel.o: \ + OPCODE/OPC_BaseModel.cpp \ + OPCODE/Stdafx.h \ + OPCODE/Opcode.h \ + OPCODE/OPC_IceHook.h \ + OPCODE/Ice/IcePreprocessor.h \ + OPCODE/Ice/IceTypes.h \ + OPCODE/Ice/IceFPU.h \ + OPCODE/Ice/IceMemoryMacros.h \ + OPCODE/Ice/IceUtils.h \ + OPCODE/Ice/IceContainer.h \ + OPCODE/Ice/IcePairs.h \ + OPCODE/Ice/IceRevisitedRadix.h \ + OPCODE/Ice/IceRandom.h \ + OPCODE/Ice/IceAxes.h \ + OPCODE/Ice/IcePoint.h \ + OPCODE/Ice/IceHPoint.h \ + OPCODE/Ice/IceMatrix3x3.h \ + OPCODE/Ice/IceMatrix4x4.h \ + OPCODE/Ice/IcePlane.h \ + OPCODE/Ice/IceRay.h \ + OPCODE/Ice/IceIndexedTriangle.h \ + OPCODE/Ice/IceTriangle.h \ + OPCODE/Ice/IceTriList.h \ + OPCODE/Ice/IceAABB.h \ + OPCODE/Ice/IceOBB.h \ + OPCODE/Ice/IceBoundingSphere.h \ + OPCODE/Ice/IceSegment.h \ + OPCODE/Ice/IceLSS.h \ + OPCODE/OPC_Settings.h \ + OPCODE/OPC_Common.h \ + OPCODE/OPC_MeshInterface.h \ + OPCODE/OPC_TreeBuilders.h \ + OPCODE/OPC_AABBTree.h \ + OPCODE/OPC_OptimizedTree.h \ + OPCODE/OPC_BaseModel.h \ + OPCODE/OPC_Model.h \ + OPCODE/OPC_HybridModel.h \ + OPCODE/OPC_Collider.h \ + OPCODE/OPC_VolumeCollider.h \ + OPCODE/OPC_TreeCollider.h \ + OPCODE/OPC_RayCollider.h \ + OPCODE/OPC_SphereCollider.h \ + OPCODE/OPC_OBBCollider.h \ + OPCODE/OPC_AABBCollider.h \ + OPCODE/OPC_LSSCollider.h \ + OPCODE/OPC_PlanesCollider.h \ + OPCODE/OPC_Picking.h \ + OPCODE/OPC_BoxPruning.h \ + OPCODE/OPC_SweepAndPrune.h +ode/src/OPC_BoxPruning.o: \ + OPCODE/OPC_BoxPruning.cpp \ + OPCODE/Stdafx.h \ + OPCODE/Opcode.h \ + OPCODE/OPC_IceHook.h \ + OPCODE/Ice/IcePreprocessor.h \ + OPCODE/Ice/IceTypes.h \ + OPCODE/Ice/IceFPU.h \ + OPCODE/Ice/IceMemoryMacros.h \ + OPCODE/Ice/IceUtils.h \ + OPCODE/Ice/IceContainer.h \ + OPCODE/Ice/IcePairs.h \ + OPCODE/Ice/IceRevisitedRadix.h \ + OPCODE/Ice/IceRandom.h \ + OPCODE/Ice/IceAxes.h \ + OPCODE/Ice/IcePoint.h \ + OPCODE/Ice/IceHPoint.h \ + OPCODE/Ice/IceMatrix3x3.h \ + OPCODE/Ice/IceMatrix4x4.h \ + OPCODE/Ice/IcePlane.h \ + OPCODE/Ice/IceRay.h \ + OPCODE/Ice/IceIndexedTriangle.h \ + OPCODE/Ice/IceTriangle.h \ + OPCODE/Ice/IceTriList.h \ + OPCODE/Ice/IceAABB.h \ + OPCODE/Ice/IceOBB.h \ + OPCODE/Ice/IceBoundingSphere.h \ + OPCODE/Ice/IceSegment.h \ + OPCODE/Ice/IceLSS.h \ + OPCODE/OPC_Settings.h \ + OPCODE/OPC_Common.h \ + OPCODE/OPC_MeshInterface.h \ + OPCODE/OPC_TreeBuilders.h \ + OPCODE/OPC_AABBTree.h \ + OPCODE/OPC_OptimizedTree.h \ + OPCODE/OPC_BaseModel.h \ + OPCODE/OPC_Model.h \ + OPCODE/OPC_HybridModel.h \ + OPCODE/OPC_Collider.h \ + OPCODE/OPC_VolumeCollider.h \ + OPCODE/OPC_TreeCollider.h \ + OPCODE/OPC_RayCollider.h \ + OPCODE/OPC_SphereCollider.h \ + OPCODE/OPC_OBBCollider.h \ + OPCODE/OPC_AABBCollider.h \ + OPCODE/OPC_LSSCollider.h \ + OPCODE/OPC_PlanesCollider.h \ + OPCODE/OPC_Picking.h \ + OPCODE/OPC_BoxPruning.h \ + OPCODE/OPC_SweepAndPrune.h +ode/src/OPC_Collider.o: \ + OPCODE/OPC_Collider.cpp \ + OPCODE/Stdafx.h \ + OPCODE/Opcode.h \ + OPCODE/OPC_IceHook.h \ + OPCODE/Ice/IcePreprocessor.h \ + OPCODE/Ice/IceTypes.h \ + OPCODE/Ice/IceFPU.h \ + OPCODE/Ice/IceMemoryMacros.h \ + OPCODE/Ice/IceUtils.h \ + OPCODE/Ice/IceContainer.h \ + OPCODE/Ice/IcePairs.h \ + OPCODE/Ice/IceRevisitedRadix.h \ + OPCODE/Ice/IceRandom.h \ + OPCODE/Ice/IceAxes.h \ + OPCODE/Ice/IcePoint.h \ + OPCODE/Ice/IceHPoint.h \ + OPCODE/Ice/IceMatrix3x3.h \ + OPCODE/Ice/IceMatrix4x4.h \ + OPCODE/Ice/IcePlane.h \ + OPCODE/Ice/IceRay.h \ + OPCODE/Ice/IceIndexedTriangle.h \ + OPCODE/Ice/IceTriangle.h \ + OPCODE/Ice/IceTriList.h \ + OPCODE/Ice/IceAABB.h \ + OPCODE/Ice/IceOBB.h \ + OPCODE/Ice/IceBoundingSphere.h \ + OPCODE/Ice/IceSegment.h \ + OPCODE/Ice/IceLSS.h \ + OPCODE/OPC_Settings.h \ + OPCODE/OPC_Common.h \ + OPCODE/OPC_MeshInterface.h \ + OPCODE/OPC_TreeBuilders.h \ + OPCODE/OPC_AABBTree.h \ + OPCODE/OPC_OptimizedTree.h \ + OPCODE/OPC_BaseModel.h \ + OPCODE/OPC_Model.h \ + OPCODE/OPC_HybridModel.h \ + OPCODE/OPC_Collider.h \ + OPCODE/OPC_VolumeCollider.h \ + OPCODE/OPC_TreeCollider.h \ + OPCODE/OPC_RayCollider.h \ + OPCODE/OPC_SphereCollider.h \ + OPCODE/OPC_OBBCollider.h \ + OPCODE/OPC_AABBCollider.h \ + OPCODE/OPC_LSSCollider.h \ + OPCODE/OPC_PlanesCollider.h \ + OPCODE/OPC_Picking.h \ + OPCODE/OPC_BoxPruning.h \ + OPCODE/OPC_SweepAndPrune.h +ode/src/OPC_Common.o: \ + OPCODE/OPC_Common.cpp \ + OPCODE/Stdafx.h \ + OPCODE/Opcode.h \ + OPCODE/OPC_IceHook.h \ + OPCODE/Ice/IcePreprocessor.h \ + OPCODE/Ice/IceTypes.h \ + OPCODE/Ice/IceFPU.h \ + OPCODE/Ice/IceMemoryMacros.h \ + OPCODE/Ice/IceUtils.h \ + OPCODE/Ice/IceContainer.h \ + OPCODE/Ice/IcePairs.h \ + OPCODE/Ice/IceRevisitedRadix.h \ + OPCODE/Ice/IceRandom.h \ + OPCODE/Ice/IceAxes.h \ + OPCODE/Ice/IcePoint.h \ + OPCODE/Ice/IceHPoint.h \ + OPCODE/Ice/IceMatrix3x3.h \ + OPCODE/Ice/IceMatrix4x4.h \ + OPCODE/Ice/IcePlane.h \ + OPCODE/Ice/IceRay.h \ + OPCODE/Ice/IceIndexedTriangle.h \ + OPCODE/Ice/IceTriangle.h \ + OPCODE/Ice/IceTriList.h \ + OPCODE/Ice/IceAABB.h \ + OPCODE/Ice/IceOBB.h \ + OPCODE/Ice/IceBoundingSphere.h \ + OPCODE/Ice/IceSegment.h \ + OPCODE/Ice/IceLSS.h \ + OPCODE/OPC_Settings.h \ + OPCODE/OPC_Common.h \ + OPCODE/OPC_MeshInterface.h \ + OPCODE/OPC_TreeBuilders.h \ + OPCODE/OPC_AABBTree.h \ + OPCODE/OPC_OptimizedTree.h \ + OPCODE/OPC_BaseModel.h \ + OPCODE/OPC_Model.h \ + OPCODE/OPC_HybridModel.h \ + OPCODE/OPC_Collider.h \ + OPCODE/OPC_VolumeCollider.h \ + OPCODE/OPC_TreeCollider.h \ + OPCODE/OPC_RayCollider.h \ + OPCODE/OPC_SphereCollider.h \ + OPCODE/OPC_OBBCollider.h \ + OPCODE/OPC_AABBCollider.h \ + OPCODE/OPC_LSSCollider.h \ + OPCODE/OPC_PlanesCollider.h \ + OPCODE/OPC_Picking.h \ + OPCODE/OPC_BoxPruning.h \ + OPCODE/OPC_SweepAndPrune.h +ode/src/OPC_HybridModel.o: \ + OPCODE/OPC_HybridModel.cpp \ + OPCODE/Stdafx.h \ + OPCODE/Opcode.h \ + OPCODE/OPC_IceHook.h \ + OPCODE/Ice/IcePreprocessor.h \ + OPCODE/Ice/IceTypes.h \ + OPCODE/Ice/IceFPU.h \ + OPCODE/Ice/IceMemoryMacros.h \ + OPCODE/Ice/IceUtils.h \ + OPCODE/Ice/IceContainer.h \ + OPCODE/Ice/IcePairs.h \ + OPCODE/Ice/IceRevisitedRadix.h \ + OPCODE/Ice/IceRandom.h \ + OPCODE/Ice/IceAxes.h \ + OPCODE/Ice/IcePoint.h \ + OPCODE/Ice/IceHPoint.h \ + OPCODE/Ice/IceMatrix3x3.h \ + OPCODE/Ice/IceMatrix4x4.h \ + OPCODE/Ice/IcePlane.h \ + OPCODE/Ice/IceRay.h \ + OPCODE/Ice/IceIndexedTriangle.h \ + OPCODE/Ice/IceTriangle.h \ + OPCODE/Ice/IceTriList.h \ + OPCODE/Ice/IceAABB.h \ + OPCODE/Ice/IceOBB.h \ + OPCODE/Ice/IceBoundingSphere.h \ + OPCODE/Ice/IceSegment.h \ + OPCODE/Ice/IceLSS.h \ + OPCODE/OPC_Settings.h \ + OPCODE/OPC_Common.h \ + OPCODE/OPC_MeshInterface.h \ + OPCODE/OPC_TreeBuilders.h \ + OPCODE/OPC_AABBTree.h \ + OPCODE/OPC_OptimizedTree.h \ + OPCODE/OPC_BaseModel.h \ + OPCODE/OPC_Model.h \ + OPCODE/OPC_HybridModel.h \ + OPCODE/OPC_Collider.h \ + OPCODE/OPC_VolumeCollider.h \ + OPCODE/OPC_TreeCollider.h \ + OPCODE/OPC_RayCollider.h \ + OPCODE/OPC_SphereCollider.h \ + OPCODE/OPC_OBBCollider.h \ + OPCODE/OPC_AABBCollider.h \ + OPCODE/OPC_LSSCollider.h \ + OPCODE/OPC_PlanesCollider.h \ + OPCODE/OPC_Picking.h \ + OPCODE/OPC_BoxPruning.h \ + OPCODE/OPC_SweepAndPrune.h +ode/src/OPC_LSSCollider.o: \ + OPCODE/OPC_LSSCollider.cpp \ + OPCODE/Stdafx.h \ + OPCODE/Opcode.h \ + OPCODE/OPC_IceHook.h \ + OPCODE/Ice/IcePreprocessor.h \ + OPCODE/Ice/IceTypes.h \ + OPCODE/Ice/IceFPU.h \ + OPCODE/Ice/IceMemoryMacros.h \ + OPCODE/Ice/IceUtils.h \ + OPCODE/Ice/IceContainer.h \ + OPCODE/Ice/IcePairs.h \ + OPCODE/Ice/IceRevisitedRadix.h \ + OPCODE/Ice/IceRandom.h \ + OPCODE/Ice/IceAxes.h \ + OPCODE/Ice/IcePoint.h \ + OPCODE/Ice/IceHPoint.h \ + OPCODE/Ice/IceMatrix3x3.h \ + OPCODE/Ice/IceMatrix4x4.h \ + OPCODE/Ice/IcePlane.h \ + OPCODE/Ice/IceRay.h \ + OPCODE/Ice/IceIndexedTriangle.h \ + OPCODE/Ice/IceTriangle.h \ + OPCODE/Ice/IceTriList.h \ + OPCODE/Ice/IceAABB.h \ + OPCODE/Ice/IceOBB.h \ + OPCODE/Ice/IceBoundingSphere.h \ + OPCODE/Ice/IceSegment.h \ + OPCODE/Ice/IceLSS.h \ + OPCODE/OPC_Settings.h \ + OPCODE/OPC_Common.h \ + OPCODE/OPC_MeshInterface.h \ + OPCODE/OPC_TreeBuilders.h \ + OPCODE/OPC_AABBTree.h \ + OPCODE/OPC_OptimizedTree.h \ + OPCODE/OPC_BaseModel.h \ + OPCODE/OPC_Model.h \ + OPCODE/OPC_HybridModel.h \ + OPCODE/OPC_Collider.h \ + OPCODE/OPC_VolumeCollider.h \ + OPCODE/OPC_TreeCollider.h \ + OPCODE/OPC_RayCollider.h \ + OPCODE/OPC_SphereCollider.h \ + OPCODE/OPC_OBBCollider.h \ + OPCODE/OPC_AABBCollider.h \ + OPCODE/OPC_LSSCollider.h \ + OPCODE/OPC_PlanesCollider.h \ + OPCODE/OPC_Picking.h \ + OPCODE/OPC_BoxPruning.h \ + OPCODE/OPC_SweepAndPrune.h \ + OPCODE/OPC_LSSAABBOverlap.h \ + OPCODE/OPC_LSSTriOverlap.h +ode/src/OPC_MeshInterface.o: \ + OPCODE/OPC_MeshInterface.cpp \ + OPCODE/Stdafx.h \ + OPCODE/Opcode.h \ + OPCODE/OPC_IceHook.h \ + OPCODE/Ice/IcePreprocessor.h \ + OPCODE/Ice/IceTypes.h \ + OPCODE/Ice/IceFPU.h \ + OPCODE/Ice/IceMemoryMacros.h \ + OPCODE/Ice/IceUtils.h \ + OPCODE/Ice/IceContainer.h \ + OPCODE/Ice/IcePairs.h \ + OPCODE/Ice/IceRevisitedRadix.h \ + OPCODE/Ice/IceRandom.h \ + OPCODE/Ice/IceAxes.h \ + OPCODE/Ice/IcePoint.h \ + OPCODE/Ice/IceHPoint.h \ + OPCODE/Ice/IceMatrix3x3.h \ + OPCODE/Ice/IceMatrix4x4.h \ + OPCODE/Ice/IcePlane.h \ + OPCODE/Ice/IceRay.h \ + OPCODE/Ice/IceIndexedTriangle.h \ + OPCODE/Ice/IceTriangle.h \ + OPCODE/Ice/IceTriList.h \ + OPCODE/Ice/IceAABB.h \ + OPCODE/Ice/IceOBB.h \ + OPCODE/Ice/IceBoundingSphere.h \ + OPCODE/Ice/IceSegment.h \ + OPCODE/Ice/IceLSS.h \ + OPCODE/OPC_Settings.h \ + OPCODE/OPC_Common.h \ + OPCODE/OPC_MeshInterface.h \ + OPCODE/OPC_TreeBuilders.h \ + OPCODE/OPC_AABBTree.h \ + OPCODE/OPC_OptimizedTree.h \ + OPCODE/OPC_BaseModel.h \ + OPCODE/OPC_Model.h \ + OPCODE/OPC_HybridModel.h \ + OPCODE/OPC_Collider.h \ + OPCODE/OPC_VolumeCollider.h \ + OPCODE/OPC_TreeCollider.h \ + OPCODE/OPC_RayCollider.h \ + OPCODE/OPC_SphereCollider.h \ + OPCODE/OPC_OBBCollider.h \ + OPCODE/OPC_AABBCollider.h \ + OPCODE/OPC_LSSCollider.h \ + OPCODE/OPC_PlanesCollider.h \ + OPCODE/OPC_Picking.h \ + OPCODE/OPC_BoxPruning.h \ + OPCODE/OPC_SweepAndPrune.h +ode/src/OPC_Model.o: \ + OPCODE/OPC_Model.cpp \ + OPCODE/Stdafx.h \ + OPCODE/Opcode.h \ + OPCODE/OPC_IceHook.h \ + OPCODE/Ice/IcePreprocessor.h \ + OPCODE/Ice/IceTypes.h \ + OPCODE/Ice/IceFPU.h \ + OPCODE/Ice/IceMemoryMacros.h \ + OPCODE/Ice/IceUtils.h \ + OPCODE/Ice/IceContainer.h \ + OPCODE/Ice/IcePairs.h \ + OPCODE/Ice/IceRevisitedRadix.h \ + OPCODE/Ice/IceRandom.h \ + OPCODE/Ice/IceAxes.h \ + OPCODE/Ice/IcePoint.h \ + OPCODE/Ice/IceHPoint.h \ + OPCODE/Ice/IceMatrix3x3.h \ + OPCODE/Ice/IceMatrix4x4.h \ + OPCODE/Ice/IcePlane.h \ + OPCODE/Ice/IceRay.h \ + OPCODE/Ice/IceIndexedTriangle.h \ + OPCODE/Ice/IceTriangle.h \ + OPCODE/Ice/IceTriList.h \ + OPCODE/Ice/IceAABB.h \ + OPCODE/Ice/IceOBB.h \ + OPCODE/Ice/IceBoundingSphere.h \ + OPCODE/Ice/IceSegment.h \ + OPCODE/Ice/IceLSS.h \ + OPCODE/OPC_Settings.h \ + OPCODE/OPC_Common.h \ + OPCODE/OPC_MeshInterface.h \ + OPCODE/OPC_TreeBuilders.h \ + OPCODE/OPC_AABBTree.h \ + OPCODE/OPC_OptimizedTree.h \ + OPCODE/OPC_BaseModel.h \ + OPCODE/OPC_Model.h \ + OPCODE/OPC_HybridModel.h \ + OPCODE/OPC_Collider.h \ + OPCODE/OPC_VolumeCollider.h \ + OPCODE/OPC_TreeCollider.h \ + OPCODE/OPC_RayCollider.h \ + OPCODE/OPC_SphereCollider.h \ + OPCODE/OPC_OBBCollider.h \ + OPCODE/OPC_AABBCollider.h \ + OPCODE/OPC_LSSCollider.h \ + OPCODE/OPC_PlanesCollider.h \ + OPCODE/OPC_Picking.h \ + OPCODE/OPC_BoxPruning.h \ + OPCODE/OPC_SweepAndPrune.h +ode/src/OPC_OBBCollider.o: \ + OPCODE/OPC_OBBCollider.cpp \ + OPCODE/Stdafx.h \ + OPCODE/Opcode.h \ + OPCODE/OPC_IceHook.h \ + OPCODE/Ice/IcePreprocessor.h \ + OPCODE/Ice/IceTypes.h \ + OPCODE/Ice/IceFPU.h \ + OPCODE/Ice/IceMemoryMacros.h \ + OPCODE/Ice/IceUtils.h \ + OPCODE/Ice/IceContainer.h \ + OPCODE/Ice/IcePairs.h \ + OPCODE/Ice/IceRevisitedRadix.h \ + OPCODE/Ice/IceRandom.h \ + OPCODE/Ice/IceAxes.h \ + OPCODE/Ice/IcePoint.h \ + OPCODE/Ice/IceHPoint.h \ + OPCODE/Ice/IceMatrix3x3.h \ + OPCODE/Ice/IceMatrix4x4.h \ + OPCODE/Ice/IcePlane.h \ + OPCODE/Ice/IceRay.h \ + OPCODE/Ice/IceIndexedTriangle.h \ + OPCODE/Ice/IceTriangle.h \ + OPCODE/Ice/IceTriList.h \ + OPCODE/Ice/IceAABB.h \ + OPCODE/Ice/IceOBB.h \ + OPCODE/Ice/IceBoundingSphere.h \ + OPCODE/Ice/IceSegment.h \ + OPCODE/Ice/IceLSS.h \ + OPCODE/OPC_Settings.h \ + OPCODE/OPC_Common.h \ + OPCODE/OPC_MeshInterface.h \ + OPCODE/OPC_TreeBuilders.h \ + OPCODE/OPC_AABBTree.h \ + OPCODE/OPC_OptimizedTree.h \ + OPCODE/OPC_BaseModel.h \ + OPCODE/OPC_Model.h \ + OPCODE/OPC_HybridModel.h \ + OPCODE/OPC_Collider.h \ + OPCODE/OPC_VolumeCollider.h \ + OPCODE/OPC_TreeCollider.h \ + OPCODE/OPC_RayCollider.h \ + OPCODE/OPC_SphereCollider.h \ + OPCODE/OPC_OBBCollider.h \ + OPCODE/OPC_AABBCollider.h \ + OPCODE/OPC_LSSCollider.h \ + OPCODE/OPC_PlanesCollider.h \ + OPCODE/OPC_Picking.h \ + OPCODE/OPC_BoxPruning.h \ + OPCODE/OPC_SweepAndPrune.h \ + OPCODE/OPC_BoxBoxOverlap.h \ + OPCODE/OPC_TriBoxOverlap.h +ode/src/Opcode.o: \ + OPCODE/Opcode.cpp \ + OPCODE/Stdafx.h \ + OPCODE/Opcode.h \ + OPCODE/OPC_IceHook.h \ + OPCODE/Ice/IcePreprocessor.h \ + OPCODE/Ice/IceTypes.h \ + OPCODE/Ice/IceFPU.h \ + OPCODE/Ice/IceMemoryMacros.h \ + OPCODE/Ice/IceUtils.h \ + OPCODE/Ice/IceContainer.h \ + OPCODE/Ice/IcePairs.h \ + OPCODE/Ice/IceRevisitedRadix.h \ + OPCODE/Ice/IceRandom.h \ + OPCODE/Ice/IceAxes.h \ + OPCODE/Ice/IcePoint.h \ + OPCODE/Ice/IceHPoint.h \ + OPCODE/Ice/IceMatrix3x3.h \ + OPCODE/Ice/IceMatrix4x4.h \ + OPCODE/Ice/IcePlane.h \ + OPCODE/Ice/IceRay.h \ + OPCODE/Ice/IceIndexedTriangle.h \ + OPCODE/Ice/IceTriangle.h \ + OPCODE/Ice/IceTriList.h \ + OPCODE/Ice/IceAABB.h \ + OPCODE/Ice/IceOBB.h \ + OPCODE/Ice/IceBoundingSphere.h \ + OPCODE/Ice/IceSegment.h \ + OPCODE/Ice/IceLSS.h \ + OPCODE/OPC_Settings.h \ + OPCODE/OPC_Common.h \ + OPCODE/OPC_MeshInterface.h \ + OPCODE/OPC_TreeBuilders.h \ + OPCODE/OPC_AABBTree.h \ + OPCODE/OPC_OptimizedTree.h \ + OPCODE/OPC_BaseModel.h \ + OPCODE/OPC_Model.h \ + OPCODE/OPC_HybridModel.h \ + OPCODE/OPC_Collider.h \ + OPCODE/OPC_VolumeCollider.h \ + OPCODE/OPC_TreeCollider.h \ + OPCODE/OPC_RayCollider.h \ + OPCODE/OPC_SphereCollider.h \ + OPCODE/OPC_OBBCollider.h \ + OPCODE/OPC_AABBCollider.h \ + OPCODE/OPC_LSSCollider.h \ + OPCODE/OPC_PlanesCollider.h \ + OPCODE/OPC_Picking.h \ + OPCODE/OPC_BoxPruning.h \ + OPCODE/OPC_SweepAndPrune.h +ode/src/OPC_OptimizedTree.o: \ + OPCODE/OPC_OptimizedTree.cpp \ + OPCODE/Stdafx.h \ + OPCODE/Opcode.h \ + OPCODE/OPC_IceHook.h \ + OPCODE/Ice/IcePreprocessor.h \ + OPCODE/Ice/IceTypes.h \ + OPCODE/Ice/IceFPU.h \ + OPCODE/Ice/IceMemoryMacros.h \ + OPCODE/Ice/IceUtils.h \ + OPCODE/Ice/IceContainer.h \ + OPCODE/Ice/IcePairs.h \ + OPCODE/Ice/IceRevisitedRadix.h \ + OPCODE/Ice/IceRandom.h \ + OPCODE/Ice/IceAxes.h \ + OPCODE/Ice/IcePoint.h \ + OPCODE/Ice/IceHPoint.h \ + OPCODE/Ice/IceMatrix3x3.h \ + OPCODE/Ice/IceMatrix4x4.h \ + OPCODE/Ice/IcePlane.h \ + OPCODE/Ice/IceRay.h \ + OPCODE/Ice/IceIndexedTriangle.h \ + OPCODE/Ice/IceTriangle.h \ + OPCODE/Ice/IceTriList.h \ + OPCODE/Ice/IceAABB.h \ + OPCODE/Ice/IceOBB.h \ + OPCODE/Ice/IceBoundingSphere.h \ + OPCODE/Ice/IceSegment.h \ + OPCODE/Ice/IceLSS.h \ + OPCODE/OPC_Settings.h \ + OPCODE/OPC_Common.h \ + OPCODE/OPC_MeshInterface.h \ + OPCODE/OPC_TreeBuilders.h \ + OPCODE/OPC_AABBTree.h \ + OPCODE/OPC_OptimizedTree.h \ + OPCODE/OPC_BaseModel.h \ + OPCODE/OPC_Model.h \ + OPCODE/OPC_HybridModel.h \ + OPCODE/OPC_Collider.h \ + OPCODE/OPC_VolumeCollider.h \ + OPCODE/OPC_TreeCollider.h \ + OPCODE/OPC_RayCollider.h \ + OPCODE/OPC_SphereCollider.h \ + OPCODE/OPC_OBBCollider.h \ + OPCODE/OPC_AABBCollider.h \ + OPCODE/OPC_LSSCollider.h \ + OPCODE/OPC_PlanesCollider.h \ + OPCODE/OPC_Picking.h \ + OPCODE/OPC_BoxPruning.h \ + OPCODE/OPC_SweepAndPrune.h +ode/src/OPC_Picking.o: \ + OPCODE/OPC_Picking.cpp \ + OPCODE/Stdafx.h \ + OPCODE/Opcode.h \ + OPCODE/OPC_IceHook.h \ + OPCODE/Ice/IcePreprocessor.h \ + OPCODE/Ice/IceTypes.h \ + OPCODE/Ice/IceFPU.h \ + OPCODE/Ice/IceMemoryMacros.h \ + OPCODE/Ice/IceUtils.h \ + OPCODE/Ice/IceContainer.h \ + OPCODE/Ice/IcePairs.h \ + OPCODE/Ice/IceRevisitedRadix.h \ + OPCODE/Ice/IceRandom.h \ + OPCODE/Ice/IceAxes.h \ + OPCODE/Ice/IcePoint.h \ + OPCODE/Ice/IceHPoint.h \ + OPCODE/Ice/IceMatrix3x3.h \ + OPCODE/Ice/IceMatrix4x4.h \ + OPCODE/Ice/IcePlane.h \ + OPCODE/Ice/IceRay.h \ + OPCODE/Ice/IceIndexedTriangle.h \ + OPCODE/Ice/IceTriangle.h \ + OPCODE/Ice/IceTriList.h \ + OPCODE/Ice/IceAABB.h \ + OPCODE/Ice/IceOBB.h \ + OPCODE/Ice/IceBoundingSphere.h \ + OPCODE/Ice/IceSegment.h \ + OPCODE/Ice/IceLSS.h \ + OPCODE/OPC_Settings.h \ + OPCODE/OPC_Common.h \ + OPCODE/OPC_MeshInterface.h \ + OPCODE/OPC_TreeBuilders.h \ + OPCODE/OPC_AABBTree.h \ + OPCODE/OPC_OptimizedTree.h \ + OPCODE/OPC_BaseModel.h \ + OPCODE/OPC_Model.h \ + OPCODE/OPC_HybridModel.h \ + OPCODE/OPC_Collider.h \ + OPCODE/OPC_VolumeCollider.h \ + OPCODE/OPC_TreeCollider.h \ + OPCODE/OPC_RayCollider.h \ + OPCODE/OPC_SphereCollider.h \ + OPCODE/OPC_OBBCollider.h \ + OPCODE/OPC_AABBCollider.h \ + OPCODE/OPC_LSSCollider.h \ + OPCODE/OPC_PlanesCollider.h \ + OPCODE/OPC_Picking.h \ + OPCODE/OPC_BoxPruning.h \ + OPCODE/OPC_SweepAndPrune.h +ode/src/OPC_PlanesCollider.o: \ + OPCODE/OPC_PlanesCollider.cpp \ + OPCODE/Stdafx.h \ + OPCODE/Opcode.h \ + OPCODE/OPC_IceHook.h \ + OPCODE/Ice/IcePreprocessor.h \ + OPCODE/Ice/IceTypes.h \ + OPCODE/Ice/IceFPU.h \ + OPCODE/Ice/IceMemoryMacros.h \ + OPCODE/Ice/IceUtils.h \ + OPCODE/Ice/IceContainer.h \ + OPCODE/Ice/IcePairs.h \ + OPCODE/Ice/IceRevisitedRadix.h \ + OPCODE/Ice/IceRandom.h \ + OPCODE/Ice/IceAxes.h \ + OPCODE/Ice/IcePoint.h \ + OPCODE/Ice/IceHPoint.h \ + OPCODE/Ice/IceMatrix3x3.h \ + OPCODE/Ice/IceMatrix4x4.h \ + OPCODE/Ice/IcePlane.h \ + OPCODE/Ice/IceRay.h \ + OPCODE/Ice/IceIndexedTriangle.h \ + OPCODE/Ice/IceTriangle.h \ + OPCODE/Ice/IceTriList.h \ + OPCODE/Ice/IceAABB.h \ + OPCODE/Ice/IceOBB.h \ + OPCODE/Ice/IceBoundingSphere.h \ + OPCODE/Ice/IceSegment.h \ + OPCODE/Ice/IceLSS.h \ + OPCODE/OPC_Settings.h \ + OPCODE/OPC_Common.h \ + OPCODE/OPC_MeshInterface.h \ + OPCODE/OPC_TreeBuilders.h \ + OPCODE/OPC_AABBTree.h \ + OPCODE/OPC_OptimizedTree.h \ + OPCODE/OPC_BaseModel.h \ + OPCODE/OPC_Model.h \ + OPCODE/OPC_HybridModel.h \ + OPCODE/OPC_Collider.h \ + OPCODE/OPC_VolumeCollider.h \ + OPCODE/OPC_TreeCollider.h \ + OPCODE/OPC_RayCollider.h \ + OPCODE/OPC_SphereCollider.h \ + OPCODE/OPC_OBBCollider.h \ + OPCODE/OPC_AABBCollider.h \ + OPCODE/OPC_LSSCollider.h \ + OPCODE/OPC_PlanesCollider.h \ + OPCODE/OPC_Picking.h \ + OPCODE/OPC_BoxPruning.h \ + OPCODE/OPC_SweepAndPrune.h \ + OPCODE/OPC_PlanesAABBOverlap.h \ + OPCODE/OPC_PlanesTriOverlap.h +ode/src/OPC_RayCollider.o: \ + OPCODE/OPC_RayCollider.cpp \ + OPCODE/Stdafx.h \ + OPCODE/Opcode.h \ + OPCODE/OPC_IceHook.h \ + OPCODE/Ice/IcePreprocessor.h \ + OPCODE/Ice/IceTypes.h \ + OPCODE/Ice/IceFPU.h \ + OPCODE/Ice/IceMemoryMacros.h \ + OPCODE/Ice/IceUtils.h \ + OPCODE/Ice/IceContainer.h \ + OPCODE/Ice/IcePairs.h \ + OPCODE/Ice/IceRevisitedRadix.h \ + OPCODE/Ice/IceRandom.h \ + OPCODE/Ice/IceAxes.h \ + OPCODE/Ice/IcePoint.h \ + OPCODE/Ice/IceHPoint.h \ + OPCODE/Ice/IceMatrix3x3.h \ + OPCODE/Ice/IceMatrix4x4.h \ + OPCODE/Ice/IcePlane.h \ + OPCODE/Ice/IceRay.h \ + OPCODE/Ice/IceIndexedTriangle.h \ + OPCODE/Ice/IceTriangle.h \ + OPCODE/Ice/IceTriList.h \ + OPCODE/Ice/IceAABB.h \ + OPCODE/Ice/IceOBB.h \ + OPCODE/Ice/IceBoundingSphere.h \ + OPCODE/Ice/IceSegment.h \ + OPCODE/Ice/IceLSS.h \ + OPCODE/OPC_Settings.h \ + OPCODE/OPC_Common.h \ + OPCODE/OPC_MeshInterface.h \ + OPCODE/OPC_TreeBuilders.h \ + OPCODE/OPC_AABBTree.h \ + OPCODE/OPC_OptimizedTree.h \ + OPCODE/OPC_BaseModel.h \ + OPCODE/OPC_Model.h \ + OPCODE/OPC_HybridModel.h \ + OPCODE/OPC_Collider.h \ + OPCODE/OPC_VolumeCollider.h \ + OPCODE/OPC_TreeCollider.h \ + OPCODE/OPC_RayCollider.h \ + OPCODE/OPC_SphereCollider.h \ + OPCODE/OPC_OBBCollider.h \ + OPCODE/OPC_AABBCollider.h \ + OPCODE/OPC_LSSCollider.h \ + OPCODE/OPC_PlanesCollider.h \ + OPCODE/OPC_Picking.h \ + OPCODE/OPC_BoxPruning.h \ + OPCODE/OPC_SweepAndPrune.h \ + OPCODE/OPC_RayAABBOverlap.h \ + OPCODE/OPC_RayTriOverlap.h +ode/src/OPC_SphereCollider.o: \ + OPCODE/OPC_SphereCollider.cpp \ + OPCODE/Stdafx.h \ + OPCODE/Opcode.h \ + OPCODE/OPC_IceHook.h \ + OPCODE/Ice/IcePreprocessor.h \ + OPCODE/Ice/IceTypes.h \ + OPCODE/Ice/IceFPU.h \ + OPCODE/Ice/IceMemoryMacros.h \ + OPCODE/Ice/IceUtils.h \ + OPCODE/Ice/IceContainer.h \ + OPCODE/Ice/IcePairs.h \ + OPCODE/Ice/IceRevisitedRadix.h \ + OPCODE/Ice/IceRandom.h \ + OPCODE/Ice/IceAxes.h \ + OPCODE/Ice/IcePoint.h \ + OPCODE/Ice/IceHPoint.h \ + OPCODE/Ice/IceMatrix3x3.h \ + OPCODE/Ice/IceMatrix4x4.h \ + OPCODE/Ice/IcePlane.h \ + OPCODE/Ice/IceRay.h \ + OPCODE/Ice/IceIndexedTriangle.h \ + OPCODE/Ice/IceTriangle.h \ + OPCODE/Ice/IceTriList.h \ + OPCODE/Ice/IceAABB.h \ + OPCODE/Ice/IceOBB.h \ + OPCODE/Ice/IceBoundingSphere.h \ + OPCODE/Ice/IceSegment.h \ + OPCODE/Ice/IceLSS.h \ + OPCODE/OPC_Settings.h \ + OPCODE/OPC_Common.h \ + OPCODE/OPC_MeshInterface.h \ + OPCODE/OPC_TreeBuilders.h \ + OPCODE/OPC_AABBTree.h \ + OPCODE/OPC_OptimizedTree.h \ + OPCODE/OPC_BaseModel.h \ + OPCODE/OPC_Model.h \ + OPCODE/OPC_HybridModel.h \ + OPCODE/OPC_Collider.h \ + OPCODE/OPC_VolumeCollider.h \ + OPCODE/OPC_TreeCollider.h \ + OPCODE/OPC_RayCollider.h \ + OPCODE/OPC_SphereCollider.h \ + OPCODE/OPC_OBBCollider.h \ + OPCODE/OPC_AABBCollider.h \ + OPCODE/OPC_LSSCollider.h \ + OPCODE/OPC_PlanesCollider.h \ + OPCODE/OPC_Picking.h \ + OPCODE/OPC_BoxPruning.h \ + OPCODE/OPC_SweepAndPrune.h \ + OPCODE/OPC_SphereAABBOverlap.h \ + OPCODE/OPC_SphereTriOverlap.h +ode/src/OPC_SweepAndPrune.o: \ + OPCODE/OPC_SweepAndPrune.cpp \ + OPCODE/Stdafx.h \ + OPCODE/Opcode.h \ + OPCODE/OPC_IceHook.h \ + OPCODE/Ice/IcePreprocessor.h \ + OPCODE/Ice/IceTypes.h \ + OPCODE/Ice/IceFPU.h \ + OPCODE/Ice/IceMemoryMacros.h \ + OPCODE/Ice/IceUtils.h \ + OPCODE/Ice/IceContainer.h \ + OPCODE/Ice/IcePairs.h \ + OPCODE/Ice/IceRevisitedRadix.h \ + OPCODE/Ice/IceRandom.h \ + OPCODE/Ice/IceAxes.h \ + OPCODE/Ice/IcePoint.h \ + OPCODE/Ice/IceHPoint.h \ + OPCODE/Ice/IceMatrix3x3.h \ + OPCODE/Ice/IceMatrix4x4.h \ + OPCODE/Ice/IcePlane.h \ + OPCODE/Ice/IceRay.h \ + OPCODE/Ice/IceIndexedTriangle.h \ + OPCODE/Ice/IceTriangle.h \ + OPCODE/Ice/IceTriList.h \ + OPCODE/Ice/IceAABB.h \ + OPCODE/Ice/IceOBB.h \ + OPCODE/Ice/IceBoundingSphere.h \ + OPCODE/Ice/IceSegment.h \ + OPCODE/Ice/IceLSS.h \ + OPCODE/OPC_Settings.h \ + OPCODE/OPC_Common.h \ + OPCODE/OPC_MeshInterface.h \ + OPCODE/OPC_TreeBuilders.h \ + OPCODE/OPC_AABBTree.h \ + OPCODE/OPC_OptimizedTree.h \ + OPCODE/OPC_BaseModel.h \ + OPCODE/OPC_Model.h \ + OPCODE/OPC_HybridModel.h \ + OPCODE/OPC_Collider.h \ + OPCODE/OPC_VolumeCollider.h \ + OPCODE/OPC_TreeCollider.h \ + OPCODE/OPC_RayCollider.h \ + OPCODE/OPC_SphereCollider.h \ + OPCODE/OPC_OBBCollider.h \ + OPCODE/OPC_AABBCollider.h \ + OPCODE/OPC_LSSCollider.h \ + OPCODE/OPC_PlanesCollider.h \ + OPCODE/OPC_Picking.h \ + OPCODE/OPC_BoxPruning.h \ + OPCODE/OPC_SweepAndPrune.h +ode/src/OPC_TreeBuilders.o: \ + OPCODE/OPC_TreeBuilders.cpp \ + OPCODE/Stdafx.h \ + OPCODE/Opcode.h \ + OPCODE/OPC_IceHook.h \ + OPCODE/Ice/IcePreprocessor.h \ + OPCODE/Ice/IceTypes.h \ + OPCODE/Ice/IceFPU.h \ + OPCODE/Ice/IceMemoryMacros.h \ + OPCODE/Ice/IceUtils.h \ + OPCODE/Ice/IceContainer.h \ + OPCODE/Ice/IcePairs.h \ + OPCODE/Ice/IceRevisitedRadix.h \ + OPCODE/Ice/IceRandom.h \ + OPCODE/Ice/IceAxes.h \ + OPCODE/Ice/IcePoint.h \ + OPCODE/Ice/IceHPoint.h \ + OPCODE/Ice/IceMatrix3x3.h \ + OPCODE/Ice/IceMatrix4x4.h \ + OPCODE/Ice/IcePlane.h \ + OPCODE/Ice/IceRay.h \ + OPCODE/Ice/IceIndexedTriangle.h \ + OPCODE/Ice/IceTriangle.h \ + OPCODE/Ice/IceTriList.h \ + OPCODE/Ice/IceAABB.h \ + OPCODE/Ice/IceOBB.h \ + OPCODE/Ice/IceBoundingSphere.h \ + OPCODE/Ice/IceSegment.h \ + OPCODE/Ice/IceLSS.h \ + OPCODE/OPC_Settings.h \ + OPCODE/OPC_Common.h \ + OPCODE/OPC_MeshInterface.h \ + OPCODE/OPC_TreeBuilders.h \ + OPCODE/OPC_AABBTree.h \ + OPCODE/OPC_OptimizedTree.h \ + OPCODE/OPC_BaseModel.h \ + OPCODE/OPC_Model.h \ + OPCODE/OPC_HybridModel.h \ + OPCODE/OPC_Collider.h \ + OPCODE/OPC_VolumeCollider.h \ + OPCODE/OPC_TreeCollider.h \ + OPCODE/OPC_RayCollider.h \ + OPCODE/OPC_SphereCollider.h \ + OPCODE/OPC_OBBCollider.h \ + OPCODE/OPC_AABBCollider.h \ + OPCODE/OPC_LSSCollider.h \ + OPCODE/OPC_PlanesCollider.h \ + OPCODE/OPC_Picking.h \ + OPCODE/OPC_BoxPruning.h \ + OPCODE/OPC_SweepAndPrune.h +ode/src/OPC_TreeCollider.o: \ + OPCODE/OPC_TreeCollider.cpp \ + OPCODE/Stdafx.h \ + OPCODE/Opcode.h \ + OPCODE/OPC_IceHook.h \ + OPCODE/Ice/IcePreprocessor.h \ + OPCODE/Ice/IceTypes.h \ + OPCODE/Ice/IceFPU.h \ + OPCODE/Ice/IceMemoryMacros.h \ + OPCODE/Ice/IceUtils.h \ + OPCODE/Ice/IceContainer.h \ + OPCODE/Ice/IcePairs.h \ + OPCODE/Ice/IceRevisitedRadix.h \ + OPCODE/Ice/IceRandom.h \ + OPCODE/Ice/IceAxes.h \ + OPCODE/Ice/IcePoint.h \ + OPCODE/Ice/IceHPoint.h \ + OPCODE/Ice/IceMatrix3x3.h \ + OPCODE/Ice/IceMatrix4x4.h \ + OPCODE/Ice/IcePlane.h \ + OPCODE/Ice/IceRay.h \ + OPCODE/Ice/IceIndexedTriangle.h \ + OPCODE/Ice/IceTriangle.h \ + OPCODE/Ice/IceTriList.h \ + OPCODE/Ice/IceAABB.h \ + OPCODE/Ice/IceOBB.h \ + OPCODE/Ice/IceBoundingSphere.h \ + OPCODE/Ice/IceSegment.h \ + OPCODE/Ice/IceLSS.h \ + OPCODE/OPC_Settings.h \ + OPCODE/OPC_Common.h \ + OPCODE/OPC_MeshInterface.h \ + OPCODE/OPC_TreeBuilders.h \ + OPCODE/OPC_AABBTree.h \ + OPCODE/OPC_OptimizedTree.h \ + OPCODE/OPC_BaseModel.h \ + OPCODE/OPC_Model.h \ + OPCODE/OPC_HybridModel.h \ + OPCODE/OPC_Collider.h \ + OPCODE/OPC_VolumeCollider.h \ + OPCODE/OPC_TreeCollider.h \ + OPCODE/OPC_RayCollider.h \ + OPCODE/OPC_SphereCollider.h \ + OPCODE/OPC_OBBCollider.h \ + OPCODE/OPC_AABBCollider.h \ + OPCODE/OPC_LSSCollider.h \ + OPCODE/OPC_PlanesCollider.h \ + OPCODE/OPC_Picking.h \ + OPCODE/OPC_BoxPruning.h \ + OPCODE/OPC_SweepAndPrune.h \ + OPCODE/OPC_BoxBoxOverlap.h \ + OPCODE/OPC_TriBoxOverlap.h \ + OPCODE/OPC_TriTriOverlap.h +ode/src/OPC_VolumeCollider.o: \ + OPCODE/OPC_VolumeCollider.cpp \ + OPCODE/Stdafx.h \ + OPCODE/Opcode.h \ + OPCODE/OPC_IceHook.h \ + OPCODE/Ice/IcePreprocessor.h \ + OPCODE/Ice/IceTypes.h \ + OPCODE/Ice/IceFPU.h \ + OPCODE/Ice/IceMemoryMacros.h \ + OPCODE/Ice/IceUtils.h \ + OPCODE/Ice/IceContainer.h \ + OPCODE/Ice/IcePairs.h \ + OPCODE/Ice/IceRevisitedRadix.h \ + OPCODE/Ice/IceRandom.h \ + OPCODE/Ice/IceAxes.h \ + OPCODE/Ice/IcePoint.h \ + OPCODE/Ice/IceHPoint.h \ + OPCODE/Ice/IceMatrix3x3.h \ + OPCODE/Ice/IceMatrix4x4.h \ + OPCODE/Ice/IcePlane.h \ + OPCODE/Ice/IceRay.h \ + OPCODE/Ice/IceIndexedTriangle.h \ + OPCODE/Ice/IceTriangle.h \ + OPCODE/Ice/IceTriList.h \ + OPCODE/Ice/IceAABB.h \ + OPCODE/Ice/IceOBB.h \ + OPCODE/Ice/IceBoundingSphere.h \ + OPCODE/Ice/IceSegment.h \ + OPCODE/Ice/IceLSS.h \ + OPCODE/OPC_Settings.h \ + OPCODE/OPC_Common.h \ + OPCODE/OPC_MeshInterface.h \ + OPCODE/OPC_TreeBuilders.h \ + OPCODE/OPC_AABBTree.h \ + OPCODE/OPC_OptimizedTree.h \ + OPCODE/OPC_BaseModel.h \ + OPCODE/OPC_Model.h \ + OPCODE/OPC_HybridModel.h \ + OPCODE/OPC_Collider.h \ + OPCODE/OPC_VolumeCollider.h \ + OPCODE/OPC_TreeCollider.h \ + OPCODE/OPC_RayCollider.h \ + OPCODE/OPC_SphereCollider.h \ + OPCODE/OPC_OBBCollider.h \ + OPCODE/OPC_AABBCollider.h \ + OPCODE/OPC_LSSCollider.h \ + OPCODE/OPC_PlanesCollider.h \ + OPCODE/OPC_Picking.h \ + OPCODE/OPC_BoxPruning.h \ + OPCODE/OPC_SweepAndPrune.h +ode/src/fastldlt.o: \ + ode/src/fastldlt.c \ + include/ode/matrix.h \ + include/ode/common.h \ + include/ode/config.h \ + include/ode/error.h +ode/src/fastlsolve.o: \ + ode/src/fastlsolve.c \ + include/ode/matrix.h \ + include/ode/common.h \ + include/ode/config.h \ + include/ode/error.h +ode/src/fastltsolve.o: \ + ode/src/fastltsolve.c \ + include/ode/matrix.h \ + include/ode/common.h \ + include/ode/config.h \ + include/ode/error.h +ode/src/fastdot.o: \ + ode/src/fastdot.c \ + include/ode/matrix.h \ + include/ode/common.h \ + include/ode/config.h \ + include/ode/error.h +drawstuff/src/drawstuff.o: \ + drawstuff/src/drawstuff.cpp \ + include/ode/config.h \ + include/drawstuff/drawstuff.h \ + include/drawstuff/version.h \ + drawstuff/src/internal.h +drawstuff/src/x11.o: \ + drawstuff/src/x11.cpp \ + include/ode/config.h \ + include/drawstuff/drawstuff.h \ + include/drawstuff/version.h \ + drawstuff/src/internal.h +ode/test/test_ode.o: \ + ode/test/test_ode.cpp \ + include/ode/ode.h \ + include/ode/config.h \ + include/ode/compatibility.h \ + include/ode/common.h \ + include/ode/error.h \ + include/ode/contact.h \ + include/ode/memory.h \ + include/ode/odemath.h \ + include/ode/matrix.h \ + include/ode/timer.h \ + include/ode/rotation.h \ + include/ode/mass.h \ + include/ode/misc.h \ + include/ode/objects.h \ + include/ode/odecpp.h \ + include/ode/collision_space.h \ + include/ode/collision.h \ + include/ode/collision_trimesh.h \ + include/ode/odecpp_collision.h \ + include/ode/export-dif.h +ode/test/test_chain2.o: \ + ode/test/test_chain2.cpp \ + include/ode/ode.h \ + include/ode/config.h \ + include/ode/compatibility.h \ + include/ode/common.h \ + include/ode/error.h \ + include/ode/contact.h \ + include/ode/memory.h \ + include/ode/odemath.h \ + include/ode/matrix.h \ + include/ode/timer.h \ + include/ode/rotation.h \ + include/ode/mass.h \ + include/ode/misc.h \ + include/ode/objects.h \ + include/ode/odecpp.h \ + include/ode/collision_space.h \ + include/ode/collision.h \ + include/ode/collision_trimesh.h \ + include/ode/odecpp_collision.h \ + include/ode/export-dif.h \ + include/drawstuff/drawstuff.h \ + include/drawstuff/version.h +ode/test/test_hinge.o: \ + ode/test/test_hinge.cpp \ + include/ode/ode.h \ + include/ode/config.h \ + include/ode/compatibility.h \ + include/ode/common.h \ + include/ode/error.h \ + include/ode/contact.h \ + include/ode/memory.h \ + include/ode/odemath.h \ + include/ode/matrix.h \ + include/ode/timer.h \ + include/ode/rotation.h \ + include/ode/mass.h \ + include/ode/misc.h \ + include/ode/objects.h \ + include/ode/odecpp.h \ + include/ode/collision_space.h \ + include/ode/collision.h \ + include/ode/collision_trimesh.h \ + include/ode/odecpp_collision.h \ + include/ode/export-dif.h \ + include/drawstuff/drawstuff.h \ + include/drawstuff/version.h +ode/test/test_slider.o: \ + ode/test/test_slider.cpp \ + include/ode/ode.h \ + include/ode/config.h \ + include/ode/compatibility.h \ + include/ode/common.h \ + include/ode/error.h \ + include/ode/contact.h \ + include/ode/memory.h \ + include/ode/odemath.h \ + include/ode/matrix.h \ + include/ode/timer.h \ + include/ode/rotation.h \ + include/ode/mass.h \ + include/ode/misc.h \ + include/ode/objects.h \ + include/ode/odecpp.h \ + include/ode/collision_space.h \ + include/ode/collision.h \ + include/ode/collision_trimesh.h \ + include/ode/odecpp_collision.h \ + include/ode/export-dif.h \ + include/drawstuff/drawstuff.h \ + include/drawstuff/version.h +ode/test/test_collision.o: \ + ode/test/test_collision.cpp \ + include/ode/ode.h \ + include/ode/config.h \ + include/ode/compatibility.h \ + include/ode/common.h \ + include/ode/error.h \ + include/ode/contact.h \ + include/ode/memory.h \ + include/ode/odemath.h \ + include/ode/matrix.h \ + include/ode/timer.h \ + include/ode/rotation.h \ + include/ode/mass.h \ + include/ode/misc.h \ + include/ode/objects.h \ + include/ode/odecpp.h \ + include/ode/collision_space.h \ + include/ode/collision.h \ + include/ode/collision_trimesh.h \ + include/ode/odecpp_collision.h \ + include/ode/export-dif.h \ + include/drawstuff/drawstuff.h \ + include/drawstuff/version.h +ode/test/test_boxstack.o: \ + ode/test/test_boxstack.cpp \ + include/ode/ode.h \ + include/ode/config.h \ + include/ode/compatibility.h \ + include/ode/common.h \ + include/ode/error.h \ + include/ode/contact.h \ + include/ode/memory.h \ + include/ode/odemath.h \ + include/ode/matrix.h \ + include/ode/timer.h \ + include/ode/rotation.h \ + include/ode/mass.h \ + include/ode/misc.h \ + include/ode/objects.h \ + include/ode/odecpp.h \ + include/ode/collision_space.h \ + include/ode/collision.h \ + include/ode/collision_trimesh.h \ + include/ode/odecpp_collision.h \ + include/ode/export-dif.h \ + include/drawstuff/drawstuff.h \ + include/drawstuff/version.h +ode/test/test_buggy.o: \ + ode/test/test_buggy.cpp \ + include/ode/ode.h \ + include/ode/config.h \ + include/ode/compatibility.h \ + include/ode/common.h \ + include/ode/error.h \ + include/ode/contact.h \ + include/ode/memory.h \ + include/ode/odemath.h \ + include/ode/matrix.h \ + include/ode/timer.h \ + include/ode/rotation.h \ + include/ode/mass.h \ + include/ode/misc.h \ + include/ode/objects.h \ + include/ode/odecpp.h \ + include/ode/collision_space.h \ + include/ode/collision.h \ + include/ode/collision_trimesh.h \ + include/ode/odecpp_collision.h \ + include/ode/export-dif.h \ + include/drawstuff/drawstuff.h \ + include/drawstuff/version.h +ode/test/test_crash.o: \ + ode/test/test_crash.cpp \ + include/ode/ode.h \ + include/ode/config.h \ + include/ode/compatibility.h \ + include/ode/common.h \ + include/ode/error.h \ + include/ode/contact.h \ + include/ode/memory.h \ + include/ode/odemath.h \ + include/ode/matrix.h \ + include/ode/timer.h \ + include/ode/rotation.h \ + include/ode/mass.h \ + include/ode/misc.h \ + include/ode/objects.h \ + include/ode/odecpp.h \ + include/ode/collision_space.h \ + include/ode/collision.h \ + include/ode/collision_trimesh.h \ + include/ode/odecpp_collision.h \ + include/ode/export-dif.h \ + include/drawstuff/drawstuff.h \ + include/drawstuff/version.h +ode/test/test_joints.o: \ + ode/test/test_joints.cpp \ + include/ode/ode.h \ + include/ode/config.h \ + include/ode/compatibility.h \ + include/ode/common.h \ + include/ode/error.h \ + include/ode/contact.h \ + include/ode/memory.h \ + include/ode/odemath.h \ + include/ode/matrix.h \ + include/ode/timer.h \ + include/ode/rotation.h \ + include/ode/mass.h \ + include/ode/misc.h \ + include/ode/objects.h \ + include/ode/odecpp.h \ + include/ode/collision_space.h \ + include/ode/collision.h \ + include/ode/collision_trimesh.h \ + include/ode/odecpp_collision.h \ + include/ode/export-dif.h \ + include/drawstuff/drawstuff.h \ + include/drawstuff/version.h +ode/test/test_space.o: \ + ode/test/test_space.cpp \ + include/ode/ode.h \ + include/ode/config.h \ + include/ode/compatibility.h \ + include/ode/common.h \ + include/ode/error.h \ + include/ode/contact.h \ + include/ode/memory.h \ + include/ode/odemath.h \ + include/ode/matrix.h \ + include/ode/timer.h \ + include/ode/rotation.h \ + include/ode/mass.h \ + include/ode/misc.h \ + include/ode/objects.h \ + include/ode/odecpp.h \ + include/ode/collision_space.h \ + include/ode/collision.h \ + include/ode/collision_trimesh.h \ + include/ode/odecpp_collision.h \ + include/ode/export-dif.h \ + include/drawstuff/drawstuff.h \ + include/drawstuff/version.h +ode/test/test_I.o: \ + ode/test/test_I.cpp \ + include/ode/ode.h \ + include/ode/config.h \ + include/ode/compatibility.h \ + include/ode/common.h \ + include/ode/error.h \ + include/ode/contact.h \ + include/ode/memory.h \ + include/ode/odemath.h \ + include/ode/matrix.h \ + include/ode/timer.h \ + include/ode/rotation.h \ + include/ode/mass.h \ + include/ode/misc.h \ + include/ode/objects.h \ + include/ode/odecpp.h \ + include/ode/collision_space.h \ + include/ode/collision.h \ + include/ode/collision_trimesh.h \ + include/ode/odecpp_collision.h \ + include/ode/export-dif.h \ + include/drawstuff/drawstuff.h \ + include/drawstuff/version.h +ode/test/test_step.o: \ + ode/test/test_step.cpp \ + include/ode/ode.h \ + include/ode/config.h \ + include/ode/compatibility.h \ + include/ode/common.h \ + include/ode/error.h \ + include/ode/contact.h \ + include/ode/memory.h \ + include/ode/odemath.h \ + include/ode/matrix.h \ + include/ode/timer.h \ + include/ode/rotation.h \ + include/ode/mass.h \ + include/ode/misc.h \ + include/ode/objects.h \ + include/ode/odecpp.h \ + include/ode/collision_space.h \ + include/ode/collision.h \ + include/ode/collision_trimesh.h \ + include/ode/odecpp_collision.h \ + include/ode/export-dif.h \ + include/drawstuff/drawstuff.h \ + include/drawstuff/version.h +ode/test/test_friction.o: \ + ode/test/test_friction.cpp \ + include/ode/ode.h \ + include/ode/config.h \ + include/ode/compatibility.h \ + include/ode/common.h \ + include/ode/error.h \ + include/ode/contact.h \ + include/ode/memory.h \ + include/ode/odemath.h \ + include/ode/matrix.h \ + include/ode/timer.h \ + include/ode/rotation.h \ + include/ode/mass.h \ + include/ode/misc.h \ + include/ode/objects.h \ + include/ode/odecpp.h \ + include/ode/collision_space.h \ + include/ode/collision.h \ + include/ode/collision_trimesh.h \ + include/ode/odecpp_collision.h \ + include/ode/export-dif.h \ + include/drawstuff/drawstuff.h \ + include/drawstuff/version.h +ode/test/test_space_stress.o: \ + ode/test/test_space_stress.cpp \ + include/ode/ode.h \ + include/ode/config.h \ + include/ode/compatibility.h \ + include/ode/common.h \ + include/ode/error.h \ + include/ode/contact.h \ + include/ode/memory.h \ + include/ode/odemath.h \ + include/ode/matrix.h \ + include/ode/timer.h \ + include/ode/rotation.h \ + include/ode/mass.h \ + include/ode/misc.h \ + include/ode/objects.h \ + include/ode/odecpp.h \ + include/ode/collision_space.h \ + include/ode/collision.h \ + include/ode/collision_trimesh.h \ + include/ode/odecpp_collision.h \ + include/ode/export-dif.h \ + include/drawstuff/drawstuff.h \ + include/drawstuff/version.h +ode/test/test_trimesh.o: \ + ode/test/test_trimesh.cpp \ + include/ode/ode.h \ + include/ode/config.h \ + include/ode/compatibility.h \ + include/ode/common.h \ + include/ode/error.h \ + include/ode/contact.h \ + include/ode/memory.h \ + include/ode/odemath.h \ + include/ode/matrix.h \ + include/ode/timer.h \ + include/ode/rotation.h \ + include/ode/mass.h \ + include/ode/misc.h \ + include/ode/objects.h \ + include/ode/odecpp.h \ + include/ode/collision_space.h \ + include/ode/collision.h \ + include/ode/collision_trimesh.h \ + include/ode/odecpp_collision.h \ + include/ode/export-dif.h \ + include/drawstuff/drawstuff.h \ + include/drawstuff/version.h +ode/test/test_moving_trimesh.o: \ + ode/test/test_moving_trimesh.cpp \ + include/ode/ode.h \ + include/ode/config.h \ + include/ode/compatibility.h \ + include/ode/common.h \ + include/ode/error.h \ + include/ode/contact.h \ + include/ode/memory.h \ + include/ode/odemath.h \ + include/ode/matrix.h \ + include/ode/timer.h \ + include/ode/rotation.h \ + include/ode/mass.h \ + include/ode/misc.h \ + include/ode/objects.h \ + include/ode/odecpp.h \ + include/ode/collision_space.h \ + include/ode/collision.h \ + include/ode/collision_trimesh.h \ + include/ode/odecpp_collision.h \ + include/ode/export-dif.h \ + include/drawstuff/drawstuff.h \ + include/drawstuff/version.h +drawstuff/dstest/dstest.o: \ + drawstuff/dstest/dstest.cpp \ + include/drawstuff/drawstuff.h \ + include/drawstuff/version.h diff --git a/libraries/ode-0.9/Makefile.in b/libraries/ode-0.9/Makefile.in new file mode 100644 index 0000000000..5cf28d1a86 --- /dev/null +++ b/libraries/ode-0.9/Makefile.in @@ -0,0 +1,665 @@ +# Makefile.in generated by automake 1.10 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 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@ +target_triplet = @target@ +subdir = . +DIST_COMMON = $(am__configure_deps) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/ode-config.in \ + $(top_srcdir)/configure config.guess config.sub depcomp \ + install-sh missing +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) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/include/ode/config.h +CONFIG_CLEAN_FILES = ode-config +am__installdirs = "$(DESTDIR)$(bindir)" +binSCRIPT_INSTALL = $(INSTALL_SCRIPT) +SCRIPTS = $(bin_SCRIPTS) +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 = include ode tests drawstuff +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@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +ARCHFLAGS = @ARCHFLAGS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DRAWSTUFF = @DRAWSTUFF@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +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@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +ODE_AGE = @ODE_AGE@ +ODE_CURRENT = @ODE_CURRENT@ +ODE_RELEASE = @ODE_RELEASE@ +ODE_REVISION = @ODE_REVISION@ +ODE_SONAME = @ODE_SONAME@ +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@ +SET_MAKE = @SET_MAKE@ +SHARED_LDFLAGS = @SHARED_LDFLAGS@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TOPDIR = @TOPDIR@ +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_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +so_ext = @so_ext@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +LIBTOOL_DEPS = @LIBTOOL_DEPS@ +@ENABLE_DEMOS_FALSE@SUBDIRS = include ode tests +@ENABLE_DEMOS_TRUE@SUBDIRS = include drawstuff ode tests +bin_SCRIPTS = ode-config +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) +ode-config: $(top_builddir)/config.status $(srcdir)/ode-config.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +install-binSCRIPTS: $(bin_SCRIPTS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_SCRIPTS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f $$d$$p; then \ + f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ + echo " $(binSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(binSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(bindir)/$$f"; \ + else :; fi; \ + done + +uninstall-binSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(bin_SCRIPTS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done + +# 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; } \ + END { 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; } \ + END { 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=; \ + 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; } \ + END { 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-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 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.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) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(bindir)"; 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 mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -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-binSCRIPTS + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-exec-hook + +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 + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-binSCRIPTS + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ + install-exec-am install-strip + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am am--refresh check check-am clean clean-generic \ + ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ + dist-shar dist-tarZ dist-zip distcheck distclean \ + distclean-generic 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-exec-hook 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 pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am uninstall-binSCRIPTS + +libtool: $(LIBTOOL_DEPS) + $(SHELL) ./config.status --recheck + +# Utility rule for making a release +release: dist dist-bz2 dist-zip + @echo Created release packages for ${PACKAGE}-${VERSION}. + +# Rules for creating .tar.bz2 and .zip packages +dist-bz2: ${PACKAGE}-${VERSION}.tar.gz + gzip -dc ${PACKAGE}-${VERSION}.tar.gz | bzip2 > ${PACKAGE}-${VERSION}.tar.bz2 + +dist-zip: ${PACKAGE}-${VERSION}.tar.gz + tar -zxf ${PACKAGE}-${VERSION}.tar.gz && \ + zip -r ${PACKAGE}-${VERSION}.zip ${PACKAGE}-${VERSION} && \ + rm -rf ${PACKAGE}-${VERSION} + +@USE_SONAME_TRUE@install-exec-hook: +@USE_SONAME_TRUE@ ln -s $(libdir)/@ODE_SONAME@.@ODE_REVISION@.@ODE_AGE@ \ +@USE_SONAME_TRUE@ $(libdir)/libode.so +@USE_SONAME_TRUE@ ln -s $(libdir)/@ODE_SONAME@.@ODE_REVISION@.@ODE_AGE@ \ +@USE_SONAME_TRUE@ $(libdir)/@ODE_SONAME@ +@USE_SONAME_TRUE@ ln -s $(libdir)/@ODE_SONAME@.@ODE_REVISION@.@ODE_AGE@ \ +@USE_SONAME_TRUE@ $(libdir)/@ODE_SONAME@.@ODE_REVISION@ +@USE_SONAME_TRUE@ /sbin/ldconfig +@USE_SONAME_FALSE@install-exec-hook: +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libraries/ode-0.9/OPCODE/Ice/IceAABB.cpp b/libraries/ode-0.9/OPCODE/Ice/IceAABB.cpp new file mode 100644 index 0000000000..d62b0ed623 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceAABB.cpp @@ -0,0 +1,405 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains AABB-related code. + * \file IceAABB.cpp + * \author Pierre Terdiman + * \date January, 29, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * AABB class. + * \class AABB + * \author Pierre Terdiman + * \version 1.0 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceMaths; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the sum of two AABBs. + * \param aabb [in] the other AABB + * \return Self-Reference + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABB& AABB::Add(const AABB& aabb) +{ + // Compute new min & max values + Point Min; GetMin(Min); + Point Tmp; aabb.GetMin(Tmp); + Min.Min(Tmp); + + Point Max; GetMax(Max); + aabb.GetMax(Tmp); + Max.Max(Tmp); + + // Update this + SetMinMax(Min, Max); + return *this; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Makes a cube from the AABB. + * \param cube [out] the cube AABB + * \return cube edge length + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float AABB::MakeCube(AABB& cube) const +{ + Point Ext; GetExtents(Ext); + float Max = Ext.Max(); + + Point Cnt; GetCenter(Cnt); + cube.SetCenterExtents(Cnt, Point(Max, Max, Max)); + return Max; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Makes a sphere from the AABB. + * \param sphere [out] sphere containing the AABB + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABB::MakeSphere(Sphere& sphere) const +{ + GetExtents(sphere.mCenter); + sphere.mRadius = sphere.mCenter.Magnitude() * 1.00001f; // To make sure sphere::Contains(*this) succeeds + GetCenter(sphere.mCenter); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks a box is inside another box. + * \param box [in] the other AABB + * \return true if current box is inside input box + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool AABB::IsInside(const AABB& box) const +{ + if(box.GetMin(0)>GetMin(0)) return false; + if(box.GetMin(1)>GetMin(1)) return false; + if(box.GetMin(2)>GetMin(2)) return false; + if(box.GetMax(0) 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__ diff --git a/libraries/ode-0.9/OPCODE/Ice/IceAxes.h b/libraries/ode-0.9/OPCODE/Ice/IceAxes.h new file mode 100644 index 0000000000..8af57e1e7f --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceAxes.h @@ -0,0 +1,54 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains axes definition. + * \file IceAxes.h + * \author Pierre Terdiman + * \date January, 29, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEAXES_H__ +#define __ICEAXES_H__ + + enum PointComponent + { + X = 0, + Y = 1, + Z = 2, + W = 3, + + FORCE_DWORD = 0x7fffffff + }; + + enum AxisOrder + { + AXES_XYZ = (X)|(Y<<2)|(Z<<4), + AXES_XZY = (X)|(Z<<2)|(Y<<4), + AXES_YXZ = (Y)|(X<<2)|(Z<<4), + AXES_YZX = (Y)|(Z<<2)|(X<<4), + AXES_ZXY = (Z)|(X<<2)|(Y<<4), + AXES_ZYX = (Z)|(Y<<2)|(X<<4), + + AXES_FORCE_DWORD = 0x7fffffff + }; + + class ICEMATHS_API Axes + { + public: + + inline_ Axes(AxisOrder order) + { + mAxis0 = (order ) & 3; + mAxis1 = (order>>2) & 3; + mAxis2 = (order>>4) & 3; + } + inline_ ~Axes() {} + + udword mAxis0; + udword mAxis1; + udword mAxis2; + }; + +#endif // __ICEAXES_H__ diff --git a/libraries/ode-0.9/OPCODE/Ice/IceBoundingSphere.h b/libraries/ode-0.9/OPCODE/Ice/IceBoundingSphere.h new file mode 100644 index 0000000000..945d38cf89 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceBoundingSphere.h @@ -0,0 +1,142 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code to compute the minimal bounding sphere. + * \file IceBoundingSphere.h + * \author Pierre Terdiman + * \date January, 29, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEBOUNDINGSPHERE_H__ +#define __ICEBOUNDINGSPHERE_H__ + + enum BSphereMethod + { + BS_NONE, + BS_GEMS, + BS_MINIBALL, + + BS_FORCE_DWORD = 0x7fffffff + }; + + class ICEMATHS_API Sphere + { + public: + //! Constructor + inline_ Sphere() {} + //! Constructor + inline_ Sphere(const Point& center, float radius) : mCenter(center), mRadius(radius) {} + //! Constructor + Sphere(udword nb_verts, const Point* verts); + //! Copy constructor + inline_ Sphere(const Sphere& sphere) : mCenter(sphere.mCenter), mRadius(sphere.mRadius) {} + //! Destructor + inline_ ~Sphere() {} + + BSphereMethod Compute(udword nb_verts, const Point* verts); + bool FastCompute(udword nb_verts, const Point* verts); + + // Access methods + inline_ const Point& GetCenter() const { return mCenter; } + inline_ float GetRadius() const { return mRadius; } + + inline_ const Point& Center() const { return mCenter; } + inline_ float Radius() const { return mRadius; } + + inline_ Sphere& Set(const Point& center, float radius) { mCenter = center; mRadius = radius; return *this; } + inline_ Sphere& SetCenter(const Point& center) { mCenter = center; return *this; } + inline_ Sphere& SetRadius(float radius) { mRadius = radius; return *this; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Tests if a point is contained within the sphere. + * \param p [in] the point to test + * \return true if inside the sphere + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ bool Contains(const Point& p) const + { + return mCenter.SquareDistance(p) <= mRadius*mRadius; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Tests if a sphere is contained within the sphere. + * \param sphere [in] the sphere to test + * \return true if inside the sphere + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ bool Contains(const Sphere& sphere) const + { + // If our radius is the smallest, we can't possibly contain the other sphere + if(mRadius < sphere.mRadius) return false; + // So r is always positive or null now + float r = mRadius - sphere.mRadius; + return mCenter.SquareDistance(sphere.mCenter) <= r*r; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Tests if a box is contained within the sphere. + * \param aabb [in] the box to test + * \return true if inside the sphere + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL Contains(const AABB& aabb) const + { + // I assume if all 8 box vertices are inside the sphere, so does the whole box. + // Sounds ok but maybe there's a better way? + float R2 = mRadius * mRadius; +#ifdef USE_MIN_MAX + const Point& Max = ((ShadowAABB&)&aabb).mMax; + const Point& Min = ((ShadowAABB&)&aabb).mMin; +#else + Point Max; aabb.GetMax(Max); + Point Min; aabb.GetMin(Min); +#endif + Point p; + p.x=Max.x; p.y=Max.y; p.z=Max.z; if(mCenter.SquareDistance(p)>=R2) return FALSE; + p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE; + p.x=Max.x; p.y=Min.y; if(mCenter.SquareDistance(p)>=R2) return FALSE; + p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE; + p.x=Max.x; p.y=Max.y; p.z=Min.z; if(mCenter.SquareDistance(p)>=R2) return FALSE; + p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE; + p.x=Max.x; p.y=Min.y; if(mCenter.SquareDistance(p)>=R2) return FALSE; + p.x=Min.x; if(mCenter.SquareDistance(p)>=R2) return FALSE; + + return TRUE; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Tests if the sphere intersects another sphere + * \param sphere [in] the other sphere + * \return true if spheres overlap + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ bool Intersect(const Sphere& sphere) const + { + float r = mRadius + sphere.mRadius; + return mCenter.SquareDistance(sphere.mCenter) <= r*r; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks the sphere is valid. + * \return true if the box is valid + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL IsValid() const + { + // Consistency condition for spheres: Radius >= 0.0f + if(mRadius < 0.0f) return FALSE; + return TRUE; + } + public: + Point mCenter; //!< Sphere center + float mRadius; //!< Sphere radius + }; + +#endif // __ICEBOUNDINGSPHERE_H__ diff --git a/libraries/ode-0.9/OPCODE/Ice/IceContainer.cpp b/libraries/ode-0.9/OPCODE/Ice/IceContainer.cpp new file mode 100644 index 0000000000..8a4a570223 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceContainer.cpp @@ -0,0 +1,345 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * 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(mMaxNbEntriesmMaxNbEntries) 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>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) + { +#ifdef _MSC_VER + float Res; + _asm fld [a] + _asm fld [b] + FCOMI_ST1 + FCMOVB_ST1 + _asm fstp [Res] + _asm fcomp + return Res; +#else + return (a > b) ? a : b; +#endif + } + + //! A global function to find MIN(a,b) using FCOMI/FCMOV + inline_ float FCMin2(float a, float b) + { +#ifdef _MSC_VER + float Res; + _asm fld [a] + _asm fld [b] + FCOMI_ST1 + FCMOVNB_ST1 + _asm fstp [Res] + _asm fcomp + return Res; +#else + return (a < b) ? a : b; +#endif + } + + //! A global function to find MAX(a,b,c) using FCOMI/FCMOV + inline_ float FCMax3(float a, float b, float c) + { +#ifdef _MSC_VER + float Res; + _asm fld [a] + _asm fld [b] + _asm fld [c] + FCOMI_ST1 + FCMOVB_ST1 + FCOMI_ST2 + FCMOVB_ST2 + _asm fstp [Res] + _asm fcompp + return Res; +#else + return (a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c); +#endif + } + + //! A global function to find MIN(a,b,c) using FCOMI/FCMOV + inline_ float FCMin3(float a, float b, float c) + { +#ifdef _MSC_VER + float Res; + _asm fld [a] + _asm fld [b] + _asm fld [c] + FCOMI_ST1 + FCMOVNB_ST1 + FCOMI_ST2 + FCMOVNB_ST2 + _asm fstp [Res] + _asm fcompp + return Res; +#else + return (a < b) ? ((a < c) ? a : c) : ((b < c) ? b : c); +#endif + } + + 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__ diff --git a/libraries/ode-0.9/OPCODE/Ice/IceHPoint.cpp b/libraries/ode-0.9/OPCODE/Ice/IceHPoint.cpp new file mode 100644 index 0000000000..f806a0c9d6 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceHPoint.cpp @@ -0,0 +1,70 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for homogeneous points. + * \file IceHPoint.cpp + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Homogeneous point. + * + * Use it: + * - for clipping in homogeneous space (standard way) + * - to differentiate between points (w=1) and vectors (w=0). + * - in some cases you can also use it instead of Point for padding reasons. + * + * \class HPoint + * \author Pierre Terdiman + * \version 1.0 + * \warning No cross-product in 4D. + * \warning HPoint *= Matrix3x3 doesn't exist, the matrix is first casted to a 4x4 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceMaths; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Point Mul = HPoint * Matrix3x3; +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Point HPoint::operator*(const Matrix3x3& mat) const +{ + return Point( + x * mat.m[0][0] + y * mat.m[1][0] + z * mat.m[2][0], + x * mat.m[0][1] + y * mat.m[1][1] + z * mat.m[2][1], + x * mat.m[0][2] + y * mat.m[1][2] + z * mat.m[2][2] ); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// HPoint Mul = HPoint * Matrix4x4; +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HPoint HPoint::operator*(const Matrix4x4& mat) const +{ + return HPoint( + x * mat.m[0][0] + y * mat.m[1][0] + z * mat.m[2][0] + w * mat.m[3][0], + x * mat.m[0][1] + y * mat.m[1][1] + z * mat.m[2][1] + w * mat.m[3][1], + x * mat.m[0][2] + y * mat.m[1][2] + z * mat.m[2][2] + w * mat.m[3][2], + x * mat.m[0][3] + y * mat.m[1][3] + z * mat.m[2][3] + w * mat.m[3][3]); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// HPoint *= Matrix4x4 +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +HPoint& HPoint::operator*=(const Matrix4x4& mat) +{ + float xp = x * mat.m[0][0] + y * mat.m[1][0] + z * mat.m[2][0] + w * mat.m[3][0]; + float yp = x * mat.m[0][1] + y * mat.m[1][1] + z * mat.m[2][1] + w * mat.m[3][1]; + float zp = x * mat.m[0][2] + y * mat.m[1][2] + z * mat.m[2][2] + w * mat.m[3][2]; + float wp = x * mat.m[0][3] + y * mat.m[1][3] + z * mat.m[2][3] + w * mat.m[3][3]; + + x = xp; y = yp; z = zp; w = wp; + + return *this; +} + diff --git a/libraries/ode-0.9/OPCODE/Ice/IceHPoint.h b/libraries/ode-0.9/OPCODE/Ice/IceHPoint.h new file mode 100644 index 0000000000..a3770cd522 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceHPoint.h @@ -0,0 +1,160 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for homogeneous points. + * \file IceHPoint.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEHPOINT_H__ +#define __ICEHPOINT_H__ + + class ICEMATHS_API HPoint : public Point + { + public: + + //! Empty constructor + inline_ HPoint() {} + //! Constructor from floats + inline_ HPoint(float xx, float yy, float zz, float ww=0.0f) : Point(xx, yy, zz), w(ww) {} + //! Constructor from array + inline_ HPoint(const float f[4]) : Point(f), w(f[3]) {} + //! Constructor from a Point + inline_ HPoint(const Point& p, float ww=0.0f) : Point(p), w(ww) {} + //! Destructor + inline_ ~HPoint() {} + + //! Clear the point + inline_ HPoint& Zero() { x = y = z = w = 0.0f; return *this; } + + //! Assignment from values + inline_ HPoint& Set(float xx, float yy, float zz, float ww ) { x = xx; y = yy; z = zz; w = ww; return *this; } + //! Assignment from array + inline_ HPoint& Set(const float f[4]) { x = f[X]; y = f[Y]; z = f[Z]; w = f[W]; return *this; } + //! Assignment from another h-point + inline_ HPoint& Set(const HPoint& src) { x = src.x; y = src.y; z = src.z; w = src.w; return *this; } + + //! Add a vector + inline_ HPoint& Add(float xx, float yy, float zz, float ww ) { x += xx; y += yy; z += zz; w += ww; return *this; } + //! Add a vector + inline_ HPoint& Add(const float f[4]) { x += f[X]; y += f[Y]; z += f[Z]; w += f[W]; return *this; } + + //! Subtract a vector + inline_ HPoint& Sub(float xx, float yy, float zz, float ww ) { x -= xx; y -= yy; z -= zz; w -= ww; return *this; } + //! Subtract a vector + inline_ HPoint& Sub(const float f[4]) { x -= f[X]; y -= f[Y]; z -= f[Z]; w -= f[W]; return *this; } + + //! Multiplies by a scalar + inline_ HPoint& Mul(float s) { x *= s; y *= s; z *= s; w *= s; return *this; } + + //! Returns MIN(x, y, z, w); + float Min() const { return MIN(x, MIN(y, MIN(z, w))); } + //! Returns MAX(x, y, z, w); + float Max() const { return MAX(x, MAX(y, MAX(z, w))); } + //! Sets each element to be componentwise minimum + HPoint& Min(const HPoint& p) { x = MIN(x, p.x); y = MIN(y, p.y); z = MIN(z, p.z); w = MIN(w, p.w); return *this; } + //! Sets each element to be componentwise maximum + HPoint& Max(const HPoint& p) { x = MAX(x, p.x); y = MAX(y, p.y); z = MAX(z, p.z); w = MAX(w, p.w); return *this; } + + //! Computes square magnitude + inline_ float SquareMagnitude() const { return x*x + y*y + z*z + w*w; } + //! Computes magnitude + inline_ float Magnitude() const { return sqrtf(x*x + y*y + z*z + w*w); } + + //! Normalize the vector + inline_ HPoint& Normalize() + { + float M = Magnitude(); + if(M) + { + M = 1.0f / M; + x *= M; + y *= M; + z *= M; + w *= M; + } + return *this; + } + + // Arithmetic operators + //! Operator for HPoint Negate = - HPoint; + inline_ HPoint operator-() const { return HPoint(-x, -y, -z, -w); } + + //! Operator for HPoint Plus = HPoint + HPoint; + inline_ HPoint operator+(const HPoint& p) const { return HPoint(x + p.x, y + p.y, z + p.z, w + p.w); } + //! Operator for HPoint Minus = HPoint - HPoint; + inline_ HPoint operator-(const HPoint& p) const { return HPoint(x - p.x, y - p.y, z - p.z, w - p.w); } + + //! Operator for HPoint Mul = HPoint * HPoint; + inline_ HPoint operator*(const HPoint& p) const { return HPoint(x * p.x, y * p.y, z * p.z, w * p.w); } + //! Operator for HPoint Scale = HPoint * float; + inline_ HPoint operator*(float s) const { return HPoint(x * s, y * s, z * s, w * s); } + //! Operator for HPoint Scale = float * HPoint; + inline_ friend HPoint operator*(float s, const HPoint& p) { return HPoint(s * p.x, s * p.y, s * p.z, s * p.w); } + + //! Operator for HPoint Div = HPoint / HPoint; + inline_ HPoint operator/(const HPoint& p) const { return HPoint(x / p.x, y / p.y, z / p.z, w / p.w); } + //! Operator for HPoint Scale = HPoint / float; + inline_ HPoint operator/(float s) const { s = 1.0f / s; return HPoint(x * s, y * s, z * s, w * s); } + //! Operator for HPoint Scale = float / HPoint; + inline_ friend HPoint operator/(float s, const HPoint& p) { return HPoint(s / p.x, s / p.y, s / p.z, s / p.w); } + + //! Operator for float DotProd = HPoint | HPoint; + inline_ float operator|(const HPoint& p) const { return x*p.x + y*p.y + z*p.z + w*p.w; } + // No cross-product in 4D + + //! Operator for HPoint += HPoint; + inline_ HPoint& operator+=(const HPoint& p) { x += p.x; y += p.y; z += p.z; w += p.w; return *this; } + //! Operator for HPoint += float; + inline_ HPoint& operator+=(float s) { x += s; y += s; z += s; w += s; return *this; } + + //! Operator for HPoint -= HPoint; + inline_ HPoint& operator-=(const HPoint& p) { x -= p.x; y -= p.y; z -= p.z; w -= p.w; return *this; } + //! Operator for HPoint -= float; + inline_ HPoint& operator-=(float s) { x -= s; y -= s; z -= s; w -= s; return *this; } + + //! Operator for HPoint *= HPoint; + inline_ HPoint& operator*=(const HPoint& p) { x *= p.x; y *= p.y; z *= p.z; w *= p.w; return *this; } + //! Operator for HPoint *= float; + inline_ HPoint& operator*=(float s) { x*=s; y*=s; z*=s; w*=s; return *this; } + + //! Operator for HPoint /= HPoint; + inline_ HPoint& operator/=(const HPoint& p) { x /= p.x; y /= p.y; z /= p.z; w /= p.w; return *this; } + //! Operator for HPoint /= float; + inline_ HPoint& operator/=(float s) { s = 1.0f / s; x*=s; y*=s; z*=s; w*=s; return *this; } + + // Arithmetic operators + + //! Operator for Point Mul = HPoint * Matrix3x3; + Point operator*(const Matrix3x3& mat) const; + //! Operator for HPoint Mul = HPoint * Matrix4x4; + HPoint operator*(const Matrix4x4& mat) const; + + // HPoint *= Matrix3x3 doesn't exist, the matrix is first casted to a 4x4 + //! Operator for HPoint *= Matrix4x4 + HPoint& operator*=(const Matrix4x4& mat); + + // Logical operators + + //! Operator for "if(HPoint==HPoint)" + inline_ bool operator==(const HPoint& p) const { return ( (x==p.x)&&(y==p.y)&&(z==p.z)&&(w==p.w)); } + //! Operator for "if(HPoint!=HPoint)" + inline_ bool operator!=(const HPoint& p) const { return ( (x!=p.x)||(y!=p.y)||(z!=p.z)||(w!=p.w)); } + + // Cast operators + + //! Cast a HPoint to a Point. w is discarded. +#ifdef _MSC_VER + inline_ operator Point() const { return Point(x, y, z); } + // gcc complains that conversion to a base class will never use a type conversion operator +#endif + + public: + float w; + }; + +#endif // __ICEHPOINT_H__ + diff --git a/libraries/ode-0.9/OPCODE/Ice/IceIndexedTriangle.cpp b/libraries/ode-0.9/OPCODE/Ice/IceIndexedTriangle.cpp new file mode 100644 index 0000000000..db279c4587 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceIndexedTriangle.cpp @@ -0,0 +1,548 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a handy indexed triangle class. + * \file IceIndexedTriangle.cpp + * \author Pierre Terdiman + * \date January, 17, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceMaths; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains an indexed triangle class. + * + * \class Triangle + * \author Pierre Terdiman + * \version 1.0 + * \date 08.15.98 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Flips the winding order. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void IndexedTriangle::Flip() +{ + Swap(mVRef[1], mVRef[2]); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle area. + * \param verts [in] the list of indexed vertices + * \return the area + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float IndexedTriangle::Area(const Point* verts) const +{ + if(!verts) return 0.0f; + const Point& p0 = verts[0]; + const Point& p1 = verts[1]; + const Point& p2 = verts[2]; + return ((p0-p1)^(p0-p2)).Magnitude() * 0.5f; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle perimeter. + * \param verts [in] the list of indexed vertices + * \return the perimeter + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float IndexedTriangle::Perimeter(const Point* verts) const +{ + if(!verts) return 0.0f; + const Point& p0 = verts[0]; + const Point& p1 = verts[1]; + const Point& p2 = verts[2]; + return p0.Distance(p1) + + p0.Distance(p2) + + p1.Distance(p2); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle compacity. + * \param verts [in] the list of indexed vertices + * \return the compacity + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float IndexedTriangle::Compacity(const Point* verts) const +{ + if(!verts) return 0.0f; + float P = Perimeter(verts); + if(P==0.0f) return 0.0f; + return (4.0f*PI*Area(verts)/(P*P)); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle normal. + * \param verts [in] the list of indexed vertices + * \param normal [out] the computed normal + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void IndexedTriangle::Normal(const Point* verts, Point& normal) const +{ + if(!verts) return; + + const Point& p0 = verts[mVRef[0]]; + const Point& p1 = verts[mVRef[1]]; + const Point& p2 = verts[mVRef[2]]; + normal = ((p2-p1)^(p0-p1)).Normalize(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle denormalized normal. + * \param verts [in] the list of indexed vertices + * \param normal [out] the computed normal + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void IndexedTriangle::DenormalizedNormal(const Point* verts, Point& normal) const +{ + if(!verts) return; + + const Point& p0 = verts[mVRef[0]]; + const Point& p1 = verts[mVRef[1]]; + const Point& p2 = verts[mVRef[2]]; + normal = ((p2-p1)^(p0-p1)); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle center. + * \param verts [in] the list of indexed vertices + * \param center [out] the computed center + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void IndexedTriangle::Center(const Point* verts, Point& center) const +{ + if(!verts) return; + + const Point& p0 = verts[mVRef[0]]; + const Point& p1 = verts[mVRef[1]]; + const Point& p2 = verts[mVRef[2]]; + center = (p0+p1+p2)*INV3; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the centered normal + * \param verts [in] the list of indexed vertices + * \param normal [out] the computed centered normal + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void IndexedTriangle::CenteredNormal(const Point* verts, Point& normal) const +{ + if(!verts) return; + + const Point& p0 = verts[mVRef[0]]; + const Point& p1 = verts[mVRef[1]]; + const Point& p2 = verts[mVRef[2]]; + Point Center = (p0+p1+p2)*INV3; + normal = Center + ((p2-p1)^(p0-p1)).Normalize(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes a random point within the triangle. + * \param verts [in] the list of indexed vertices + * \param normal [out] the computed centered normal + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void IndexedTriangle::RandomPoint(const Point* verts, Point& random) const +{ + if(!verts) return; + + // Random barycentric coords + float Alpha = UnitRandomFloat(); + float Beta = UnitRandomFloat(); + float Gamma = UnitRandomFloat(); + float OneOverTotal = 1.0f / (Alpha + Beta + Gamma); + Alpha *= OneOverTotal; + Beta *= OneOverTotal; + Gamma *= OneOverTotal; + + const Point& p0 = verts[mVRef[0]]; + const Point& p1 = verts[mVRef[1]]; + const Point& p2 = verts[mVRef[2]]; + random = Alpha*p0 + Beta*p1 + Gamma*p2; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes backface culling. + * \param verts [in] the list of indexed vertices + * \param source [in] source point (in local space) from which culling must be computed + * \return true if the triangle is visible from the source point + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool IndexedTriangle::IsVisible(const Point* verts, const Point& source) const +{ + // Checkings + if(!verts) return false; + + const Point& p0 = verts[mVRef[0]]; + const Point& p1 = verts[mVRef[1]]; + const Point& p2 = verts[mVRef[2]]; + + // Compute denormalized normal + Point Normal = (p2 - p1)^(p0 - p1); + + // Backface culling + return (Normal | source) >= 0.0f; + +// Same as: +// Plane PL(verts[mVRef[0]], verts[mVRef[1]], verts[mVRef[2]]); +// return PL.Distance(source) > PL.d; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes backface culling. + * \param verts [in] the list of indexed vertices + * \param source [in] source point (in local space) from which culling must be computed + * \return true if the triangle is visible from the source point + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool IndexedTriangle::BackfaceCulling(const Point* verts, const Point& source) const +{ + // Checkings + if(!verts) return false; + + const Point& p0 = verts[mVRef[0]]; + const Point& p1 = verts[mVRef[1]]; + const Point& p2 = verts[mVRef[2]]; + + // Compute base +// Point Base = (p0 + p1 + p2)*INV3; + + // Compute denormalized normal + Point Normal = (p2 - p1)^(p0 - p1); + + // Backface culling +// return (Normal | (source - Base)) >= 0.0f; + return (Normal | (source - p0)) >= 0.0f; + +// Same as: (but a bit faster) +// Plane PL(verts[mVRef[0]], verts[mVRef[1]], verts[mVRef[2]]); +// return PL.Distance(source)>0.0f; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the occlusion potential of the triangle. + * \param verts [in] the list of indexed vertices + * \param source [in] source point (in local space) from which occlusion potential must be computed + * \return the occlusion potential + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float IndexedTriangle::ComputeOcclusionPotential(const Point* verts, const Point& view) const +{ + if(!verts) return 0.0f; + // Occlusion potential: -(A * (N|V) / d^2) + // A = polygon area + // N = polygon normal + // V = view vector + // d = distance viewpoint-center of polygon + + float A = Area(verts); + Point N; Normal(verts, N); + Point C; Center(verts, C); + float d = view.Distance(C); + return -(A*(N|view))/(d*d); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Replaces a vertex reference with another one. + * \param oldref [in] the vertex reference to replace + * \param newref [in] the new vertex reference + * \return true if success, else false if the input vertex reference doesn't belong to the triangle + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool IndexedTriangle::ReplaceVertex(udword oldref, udword 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(udword 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(udword ref, udword* 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(udword vref0, udword 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. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +udword IndexedTriangle::OppositeVertex(udword vref0, udword 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 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, udword& vref0, udword& vref1, udword& 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, udword* nearvtx) const +{ + // Checkings + if(!verts) return; + + // Get face in local or global space + const Point& p0 = verts[mVRef[0]]; + const Point& p1 = verts[mVRef[1]]; + const Point& p2 = verts[mVRef[2]]; + + // Compute point coordinates + pt = (1.0f - u - v)*p0 + u*p1 + v*p2; + + // Compute nearest vertex if needed + if(nearvtx) + { + // Compute distance vector + Point d(p0.SquareDistance(pt), // Distance^2 from vertex 0 to point on the face + p1.SquareDistance(pt), // Distance^2 from vertex 1 to point on the face + p2.SquareDistance(pt)); // Distance^2 from vertex 2 to point on the face + + // Get smallest distance + *nearvtx = mVRef[d.SmallestAxis()]; + } +} + + //************************************** + // Angle between two vectors (in radians) + // we use this formula + // uv = |u||v| cos(u,v) + // u ^ v = w + // |w| = |u||v| |sin(u,v)| + //************************************** + float Angle(const Point& u, const Point& v) + { + float NormU = u.Magnitude(); // |u| + float NormV = v.Magnitude(); // |v| + float Product = NormU*NormV; // |u||v| + if(Product==0.0f) return 0.0f; + float OneOverProduct = 1.0f / Product; + + // Cosinus + float Cosinus = (u|v) * OneOverProduct; + + // Sinus + Point w = u^v; + float NormW = w.Magnitude(); + + float AbsSinus = NormW * OneOverProduct; + + // Remove degeneracy + if(AbsSinus > 1.0f) AbsSinus = 1.0f; + if(AbsSinus < -1.0f) AbsSinus = -1.0f; + + if(Cosinus>=0.0f) return asinf(AbsSinus); + else return (PI-asinf(AbsSinus)); + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the angle between two triangles. + * \param tri [in] the other triangle + * \param verts [in] the list of indexed vertices + * \return the angle in radians + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float IndexedTriangle::Angle(const IndexedTriangle& tri, const Point* verts) const +{ + // Checkings + if(!verts) return 0.0f; + + // Compute face normals + Point n0, n1; + Normal(verts, n0); + tri.Normal(verts, n1); + + // Compute angle + float dp = n0|n1; + if(dp>1.0f) return 0.0f; + if(dp<-1.0f) return PI; + return acosf(dp); + +// return ::Angle(n0,n1); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks a triangle is the same as another one. + * \param tri [in] the other triangle + * \return true if same triangle + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool IndexedTriangle::Equal(const IndexedTriangle& tri) const +{ + // Test all vertex references + return (HasVertex(tri.mVRef[0]) && + HasVertex(tri.mVRef[1]) && + HasVertex(tri.mVRef[2])); +} diff --git a/libraries/ode-0.9/OPCODE/Ice/IceIndexedTriangle.h b/libraries/ode-0.9/OPCODE/Ice/IceIndexedTriangle.h new file mode 100644 index 0000000000..b34c485d68 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceIndexedTriangle.h @@ -0,0 +1,72 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a handy indexed triangle class. + * \file IceIndexedTriangle.h + * \author Pierre Terdiman + * \date January, 17, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// 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(udword r0, udword r1, udword 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 + udword 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(udword oldref, udword newref); + bool IsDegenerate() const; + bool HasVertex(udword ref) const; + bool HasVertex(udword ref, udword* index) const; + ubyte FindEdge(udword vref0, udword vref1) const; + udword OppositeVertex(udword vref0, udword vref1) const; + inline_ udword OppositeVertex(ubyte edgenb) const { return mVRef[2-edgenb]; } + void GetVRefs(ubyte edgenb, udword& vref0, udword& vref1, udword& 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, udword* nearvtx=null) const; + float Angle(const IndexedTriangle& tri, const Point* verts) const; + inline_ Plane PlaneEquation(const Point* verts) const { return Plane(verts[mVRef[0]], verts[mVRef[1]], verts[mVRef[2]]); } + bool Equal(const IndexedTriangle& tri) const; + CubeIndex ComputeCubeIndex(const Point* verts) const; + }; + +#endif // __ICEINDEXEDTRIANGLE_H__ diff --git a/libraries/ode-0.9/OPCODE/Ice/IceLSS.h b/libraries/ode-0.9/OPCODE/Ice/IceLSS.h new file mode 100644 index 0000000000..bd260c1e59 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceLSS.h @@ -0,0 +1,75 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for line-swept spheres. + * \file IceLSS.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICELSS_H__ +#define __ICELSS_H__ + + class ICEMATHS_API LSS : public Segment + { + public: + //! Constructor + inline_ LSS() {} + //! Constructor + inline_ LSS(const Segment& seg, float radius) : Segment(seg), mRadius(radius) {} + //! Destructor + inline_ ~LSS() {} + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes an OBB surrounding the LSS. + * \param box [out] the OBB + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void ComputeOBB(OBB& box); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Tests if a point is contained within the LSS. + * \param pt [in] the point to test + * \return true if inside the LSS + * \warning point and LSS must be in same space + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ bool Contains(const Point& pt) const { return SquareDistance(pt) <= mRadius*mRadius; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Tests if a sphere is contained within the LSS. + * \param sphere [in] the sphere to test + * \return true if inside the LSS + * \warning sphere and LSS must be in same space + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ bool Contains(const Sphere& sphere) + { + float d = mRadius - sphere.mRadius; + if(d>=0.0f) return SquareDistance(sphere.mCenter) <= d*d; + else return false; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Tests if an LSS is contained within the LSS. + * \param lss [in] the LSS to test + * \return true if inside the LSS + * \warning both LSS must be in same space + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ bool Contains(const LSS& lss) + { + // We check the LSS contains the two spheres at the start and end of the sweep + return Contains(Sphere(lss.mP0, lss.mRadius)) && Contains(Sphere(lss.mP0, lss.mRadius)); + } + + float mRadius; //!< Sphere radius + }; + +#endif // __ICELSS_H__ diff --git a/libraries/ode-0.9/OPCODE/Ice/IceMatrix3x3.cpp b/libraries/ode-0.9/OPCODE/Ice/IceMatrix3x3.cpp new file mode 100644 index 0000000000..af56d3e5c8 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceMatrix3x3.cpp @@ -0,0 +1,48 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for 3x3 matrices. + * \file IceMatrix3x3.cpp + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * 3x3 matrix. + * DirectX-compliant, ie row-column order, ie m[Row][Col]. + * Same as: + * m11 m12 m13 first row. + * m21 m22 m23 second row. + * m31 m32 m33 third row. + * Stored in memory as m11 m12 m13 m21... + * + * Multiplication rules: + * + * [x'y'z'] = [xyz][M] + * + * x' = x*m11 + y*m21 + z*m31 + * y' = x*m12 + y*m22 + z*m32 + * z' = x*m13 + y*m23 + z*m33 + * + * \class Matrix3x3 + * \author Pierre Terdiman + * \version 1.0 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceMaths; + +// Cast operator +Matrix3x3::operator Matrix4x4() const +{ + return Matrix4x4( + m[0][0], m[0][1], m[0][2], 0.0f, + m[1][0], m[1][1], m[1][2], 0.0f, + m[2][0], m[2][1], m[2][2], 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f); +} diff --git a/libraries/ode-0.9/OPCODE/Ice/IceMatrix3x3.h b/libraries/ode-0.9/OPCODE/Ice/IceMatrix3x3.h new file mode 100644 index 0000000000..a30680da6c --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceMatrix3x3.h @@ -0,0 +1,496 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * 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 sdword gIndex[3+2] = { 0, 1, 2, 0, 1 }; + return (m[gIndex[row+1]][gIndex[column+1]]*m[gIndex[row+2]][gIndex[column+2]] - m[gIndex[row+2]][gIndex[column+1]]*m[gIndex[row+1]][gIndex[column+2]]); + } +*/ + //! Invert the matrix. Determinant must be different from zero, else matrix can't be inverted. + Matrix3x3& Invert() + { + float Det = Determinant(); // Must be !=0 + float OneOverDet = 1.0f / Det; + + Matrix3x3 Temp; + Temp.m[0][0] = +(m[1][1] * m[2][2] - m[2][1] * m[1][2]) * OneOverDet; + Temp.m[1][0] = -(m[1][0] * m[2][2] - m[2][0] * m[1][2]) * OneOverDet; + Temp.m[2][0] = +(m[1][0] * m[2][1] - m[2][0] * m[1][1]) * OneOverDet; + Temp.m[0][1] = -(m[0][1] * m[2][2] - m[2][1] * m[0][2]) * OneOverDet; + Temp.m[1][1] = +(m[0][0] * m[2][2] - m[2][0] * m[0][2]) * OneOverDet; + Temp.m[2][1] = -(m[0][0] * m[2][1] - m[2][0] * m[0][1]) * OneOverDet; + Temp.m[0][2] = +(m[0][1] * m[1][2] - m[1][1] * m[0][2]) * OneOverDet; + Temp.m[1][2] = -(m[0][0] * m[1][2] - m[1][0] * m[0][2]) * OneOverDet; + Temp.m[2][2] = +(m[0][0] * m[1][1] - m[1][0] * m[0][1]) * OneOverDet; + + *this = Temp; + + return *this; + } + + Matrix3x3& Normalize(); + + //! this = exp(a) + Matrix3x3& Exp(const Matrix3x3& a); + +void FromQuat(const Quat &q); +void FromQuatL2(const Quat &q, float l2); + + // Arithmetic operators + //! Operator for Matrix3x3 Plus = Matrix3x3 + Matrix3x3; + inline_ Matrix3x3 operator+(const Matrix3x3& mat) const + { + return Matrix3x3( + m[0][0] + mat.m[0][0], m[0][1] + mat.m[0][1], m[0][2] + mat.m[0][2], + m[1][0] + mat.m[1][0], m[1][1] + mat.m[1][1], m[1][2] + mat.m[1][2], + m[2][0] + mat.m[2][0], m[2][1] + mat.m[2][1], m[2][2] + mat.m[2][2]); + } + + //! Operator for Matrix3x3 Minus = Matrix3x3 - Matrix3x3; + inline_ Matrix3x3 operator-(const Matrix3x3& mat) const + { + return Matrix3x3( + m[0][0] - mat.m[0][0], m[0][1] - mat.m[0][1], m[0][2] - mat.m[0][2], + m[1][0] - mat.m[1][0], m[1][1] - mat.m[1][1], m[1][2] - mat.m[1][2], + m[2][0] - mat.m[2][0], m[2][1] - mat.m[2][1], m[2][2] - mat.m[2][2]); + } + + //! Operator for Matrix3x3 Mul = Matrix3x3 * Matrix3x3; + inline_ Matrix3x3 operator*(const Matrix3x3& mat) const + { + return Matrix3x3( + m[0][0]*mat.m[0][0] + m[0][1]*mat.m[1][0] + m[0][2]*mat.m[2][0], + m[0][0]*mat.m[0][1] + m[0][1]*mat.m[1][1] + m[0][2]*mat.m[2][1], + m[0][0]*mat.m[0][2] + m[0][1]*mat.m[1][2] + m[0][2]*mat.m[2][2], + + m[1][0]*mat.m[0][0] + m[1][1]*mat.m[1][0] + m[1][2]*mat.m[2][0], + m[1][0]*mat.m[0][1] + m[1][1]*mat.m[1][1] + m[1][2]*mat.m[2][1], + m[1][0]*mat.m[0][2] + m[1][1]*mat.m[1][2] + m[1][2]*mat.m[2][2], + + m[2][0]*mat.m[0][0] + m[2][1]*mat.m[1][0] + m[2][2]*mat.m[2][0], + m[2][0]*mat.m[0][1] + m[2][1]*mat.m[1][1] + m[2][2]*mat.m[2][1], + m[2][0]*mat.m[0][2] + m[2][1]*mat.m[1][2] + m[2][2]*mat.m[2][2]); + } + + //! Operator for Point Mul = Matrix3x3 * Point; + inline_ Point operator*(const Point& v) const { return Point(GetRow(0)|v, GetRow(1)|v, GetRow(2)|v); } + + //! Operator for Matrix3x3 Mul = Matrix3x3 * float; + inline_ Matrix3x3 operator*(float s) const + { + return Matrix3x3( + m[0][0]*s, m[0][1]*s, m[0][2]*s, + m[1][0]*s, m[1][1]*s, m[1][2]*s, + m[2][0]*s, m[2][1]*s, m[2][2]*s); + } + + //! Operator for Matrix3x3 Mul = float * Matrix3x3; + inline_ friend Matrix3x3 operator*(float s, const Matrix3x3& mat) + { + return Matrix3x3( + s*mat.m[0][0], s*mat.m[0][1], s*mat.m[0][2], + s*mat.m[1][0], s*mat.m[1][1], s*mat.m[1][2], + s*mat.m[2][0], s*mat.m[2][1], s*mat.m[2][2]); + } + + //! Operator for Matrix3x3 Div = Matrix3x3 / float; + inline_ Matrix3x3 operator/(float s) const + { + if (s) s = 1.0f / s; + return Matrix3x3( + m[0][0]*s, m[0][1]*s, m[0][2]*s, + m[1][0]*s, m[1][1]*s, m[1][2]*s, + m[2][0]*s, m[2][1]*s, m[2][2]*s); + } + + //! Operator for Matrix3x3 Div = float / Matrix3x3; + inline_ friend Matrix3x3 operator/(float s, const Matrix3x3& mat) + { + return Matrix3x3( + s/mat.m[0][0], s/mat.m[0][1], s/mat.m[0][2], + s/mat.m[1][0], s/mat.m[1][1], s/mat.m[1][2], + s/mat.m[2][0], s/mat.m[2][1], s/mat.m[2][2]); + } + + //! Operator for Matrix3x3 += Matrix3x3 + inline_ Matrix3x3& operator+=(const Matrix3x3& mat) + { + m[0][0] += mat.m[0][0]; m[0][1] += mat.m[0][1]; m[0][2] += mat.m[0][2]; + m[1][0] += mat.m[1][0]; m[1][1] += mat.m[1][1]; m[1][2] += mat.m[1][2]; + m[2][0] += mat.m[2][0]; m[2][1] += mat.m[2][1]; m[2][2] += mat.m[2][2]; + return *this; + } + + //! Operator for Matrix3x3 -= Matrix3x3 + inline_ Matrix3x3& operator-=(const Matrix3x3& mat) + { + m[0][0] -= mat.m[0][0]; m[0][1] -= mat.m[0][1]; m[0][2] -= mat.m[0][2]; + m[1][0] -= mat.m[1][0]; m[1][1] -= mat.m[1][1]; m[1][2] -= mat.m[1][2]; + m[2][0] -= mat.m[2][0]; m[2][1] -= mat.m[2][1]; m[2][2] -= mat.m[2][2]; + return *this; + } + + //! Operator for Matrix3x3 *= Matrix3x3 + inline_ Matrix3x3& operator*=(const Matrix3x3& mat) + { + Point TempRow; + + GetRow(0, TempRow); + m[0][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0]; + m[0][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1]; + m[0][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2]; + + GetRow(1, TempRow); + m[1][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0]; + m[1][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1]; + m[1][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2]; + + GetRow(2, TempRow); + m[2][0] = TempRow.x*mat.m[0][0] + TempRow.y*mat.m[1][0] + TempRow.z*mat.m[2][0]; + m[2][1] = TempRow.x*mat.m[0][1] + TempRow.y*mat.m[1][1] + TempRow.z*mat.m[2][1]; + m[2][2] = TempRow.x*mat.m[0][2] + TempRow.y*mat.m[1][2] + TempRow.z*mat.m[2][2]; + return *this; + } + + //! Operator for Matrix3x3 *= float + inline_ Matrix3x3& operator*=(float s) + { + m[0][0] *= s; m[0][1] *= s; m[0][2] *= s; + m[1][0] *= s; m[1][1] *= s; m[1][2] *= s; + m[2][0] *= s; m[2][1] *= s; m[2][2] *= s; + return *this; + } + + //! Operator for Matrix3x3 /= float + inline_ Matrix3x3& operator/=(float s) + { + if (s) s = 1.0f / s; + m[0][0] *= s; m[0][1] *= s; m[0][2] *= s; + m[1][0] *= s; m[1][1] *= s; m[1][2] *= s; + m[2][0] *= s; m[2][1] *= s; m[2][2] *= s; + return *this; + } + + // Cast operators + //! Cast a Matrix3x3 to a Matrix4x4. + operator Matrix4x4() const; + //! Cast a Matrix3x3 to a Quat. + operator Quat() const; + + inline_ const Point& operator[](int row) const { return *(const Point*)&m[row][0]; } + inline_ Point& operator[](int row) { return *(Point*)&m[row][0]; } + + public: + + float m[3][3]; + }; + +#endif // __ICEMATRIX3X3_H__ + diff --git a/libraries/ode-0.9/OPCODE/Ice/IceMatrix4x4.cpp b/libraries/ode-0.9/OPCODE/Ice/IceMatrix4x4.cpp new file mode 100644 index 0000000000..0b258f0cdf --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceMatrix4x4.cpp @@ -0,0 +1,135 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for 4x4 matrices. + * \file IceMatrix4x4.cpp + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * 4x4 matrix. + * DirectX-compliant, ie row-column order, ie m[Row][Col]. + * Same as: + * m11 m12 m13 m14 first row. + * m21 m22 m23 m24 second row. + * m31 m32 m33 m34 third row. + * m41 m42 m43 m44 fourth row. + * Translation is (m41, m42, m43), (m14, m24, m34, m44) = (0, 0, 0, 1). + * Stored in memory as m11 m12 m13 m14 m21... + * + * Multiplication rules: + * + * [x'y'z'1] = [xyz1][M] + * + * x' = x*m11 + y*m21 + z*m31 + m41 + * y' = x*m12 + y*m22 + z*m32 + m42 + * z' = x*m13 + y*m23 + z*m33 + m43 + * 1' = 0 + 0 + 0 + m44 + * + * \class Matrix4x4 + * \author Pierre Terdiman + * \version 1.0 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceMaths; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Inverts a PR matrix. (which only contains a rotation and a translation) + * This is faster and less subject to FPU errors than the generic inversion code. + * + * \relates Matrix4x4 + * \fn InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src) + * \param dest [out] destination matrix + * \param src [in] source matrix + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +ICEMATHS_API void IceMaths::InvertPRMatrix(Matrix4x4& dest, const Matrix4x4& src) +{ + dest.m[0][0] = src.m[0][0]; + dest.m[1][0] = src.m[0][1]; + dest.m[2][0] = src.m[0][2]; + dest.m[3][0] = -(src.m[3][0]*src.m[0][0] + src.m[3][1]*src.m[0][1] + src.m[3][2]*src.m[0][2]); + + dest.m[0][1] = src.m[1][0]; + dest.m[1][1] = src.m[1][1]; + dest.m[2][1] = src.m[1][2]; + dest.m[3][1] = -(src.m[3][0]*src.m[1][0] + src.m[3][1]*src.m[1][1] + src.m[3][2]*src.m[1][2]); + + dest.m[0][2] = src.m[2][0]; + dest.m[1][2] = src.m[2][1]; + dest.m[2][2] = src.m[2][2]; + dest.m[3][2] = -(src.m[3][0]*src.m[2][0] + src.m[3][1]*src.m[2][1] + src.m[3][2]*src.m[2][2]); + + dest.m[0][3] = 0.0f; + dest.m[1][3] = 0.0f; + dest.m[2][3] = 0.0f; + dest.m[3][3] = 1.0f; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Compute the cofactor of the Matrix at a specified location +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Matrix4x4::CoFactor(udword row, udword col) const +{ + return (( m[(row+1)&3][(col+1)&3]*m[(row+2)&3][(col+2)&3]*m[(row+3)&3][(col+3)&3] + + m[(row+1)&3][(col+2)&3]*m[(row+2)&3][(col+3)&3]*m[(row+3)&3][(col+1)&3] + + m[(row+1)&3][(col+3)&3]*m[(row+2)&3][(col+1)&3]*m[(row+3)&3][(col+2)&3]) + - (m[(row+3)&3][(col+1)&3]*m[(row+2)&3][(col+2)&3]*m[(row+1)&3][(col+3)&3] + + m[(row+3)&3][(col+2)&3]*m[(row+2)&3][(col+3)&3]*m[(row+1)&3][(col+1)&3] + + m[(row+3)&3][(col+3)&3]*m[(row+2)&3][(col+1)&3]*m[(row+1)&3][(col+2)&3])) * ((row + col) & 1 ? -1.0f : +1.0f); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Compute the determinant of the Matrix +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Matrix4x4::Determinant() const +{ + return m[0][0] * CoFactor(0, 0) + + m[0][1] * CoFactor(0, 1) + + m[0][2] * CoFactor(0, 2) + + m[0][3] * CoFactor(0, 3); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Compute the inverse of the matrix +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Matrix4x4& Matrix4x4::Invert() +{ + float Det = Determinant(); + Matrix4x4 Temp; + + if(fabsf(Det) < MATRIX4X4_EPSILON) + return *this; // The matrix is not invertible! Singular case! + + float IDet = 1.0f / Det; + + Temp.m[0][0] = CoFactor(0,0) * IDet; + Temp.m[1][0] = CoFactor(0,1) * IDet; + Temp.m[2][0] = CoFactor(0,2) * IDet; + Temp.m[3][0] = CoFactor(0,3) * IDet; + Temp.m[0][1] = CoFactor(1,0) * IDet; + Temp.m[1][1] = CoFactor(1,1) * IDet; + Temp.m[2][1] = CoFactor(1,2) * IDet; + Temp.m[3][1] = CoFactor(1,3) * IDet; + Temp.m[0][2] = CoFactor(2,0) * IDet; + Temp.m[1][2] = CoFactor(2,1) * IDet; + Temp.m[2][2] = CoFactor(2,2) * IDet; + Temp.m[3][2] = CoFactor(2,3) * IDet; + Temp.m[0][3] = CoFactor(3,0) * IDet; + Temp.m[1][3] = CoFactor(3,1) * IDet; + Temp.m[2][3] = CoFactor(3,2) * IDet; + Temp.m[3][3] = CoFactor(3,3) * IDet; + + *this = Temp; + + return *this; +} + diff --git a/libraries/ode-0.9/OPCODE/Ice/IceMatrix4x4.h b/libraries/ode-0.9/OPCODE/Ice/IceMatrix4x4.h new file mode 100644 index 0000000000..45919be798 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceMatrix4x4.h @@ -0,0 +1,455 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * 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__ + diff --git a/libraries/ode-0.9/OPCODE/Ice/IceMemoryMacros.h b/libraries/ode-0.9/OPCODE/Ice/IceMemoryMacros.h new file mode 100644 index 0000000000..638633371d --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceMemoryMacros.h @@ -0,0 +1,109 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * 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) + { + // The asm code below **SHOULD** be equivalent to one of those C versions + // or the other if your compiled is good: (checked on VC++ 6.0) + // + // 1) while(nb--) *dest++ = value; + // + // 2) for(udword i=0;iRelease(); (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__ diff --git a/libraries/ode-0.9/OPCODE/Ice/IceOBB.cpp b/libraries/ode-0.9/OPCODE/Ice/IceOBB.cpp new file mode 100644 index 0000000000..0b1b6f74df --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceOBB.cpp @@ -0,0 +1,323 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * 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 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 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 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; + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Checks the OBB is inside another OBB. + * \param box [in] the other OBB + * \return TRUE if we're inside the other box + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +BOOL OBB::IsInside(const OBB& box) const +{ + // Make a 4x4 from the box & inverse it + Matrix4x4 M0Inv; + { + Matrix4x4 M0 = box.mRot; + M0.SetTrans(box.mCenter); + InvertPRMatrix(M0Inv, M0); + } + + // With our inversed 4x4, create box1 in space of box0 + OBB _1in0; + Rotate(M0Inv, _1in0); + + // This should cancel out box0's rotation, i.e. it's now an AABB. + // => Center(0,0,0), Rot(identity) + + // The two boxes are in the same space so now we can compare them. + + // Create the AABB of (box1 in space of box0) + const Matrix3x3& mtx = _1in0.mRot; + + float f = fabsf(mtx.m[0][0] * mExtents.x) + fabsf(mtx.m[1][0] * mExtents.y) + fabsf(mtx.m[2][0] * mExtents.z) - box.mExtents.x; + if(f > _1in0.mCenter.x) return FALSE; + if(-f < _1in0.mCenter.x) return FALSE; + + f = fabsf(mtx.m[0][1] * mExtents.x) + fabsf(mtx.m[1][1] * mExtents.y) + fabsf(mtx.m[2][1] * mExtents.z) - box.mExtents.y; + if(f > _1in0.mCenter.y) return FALSE; + if(-f < _1in0.mCenter.y) return FALSE; + + f = fabsf(mtx.m[0][2] * mExtents.x) + fabsf(mtx.m[1][2] * mExtents.y) + fabsf(mtx.m[2][2] * mExtents.z) - box.mExtents.z; + if(f > _1in0.mCenter.z) return FALSE; + if(-f < _1in0.mCenter.z) return FALSE; + + return TRUE; +} diff --git a/libraries/ode-0.9/OPCODE/Ice/IceOBB.h b/libraries/ode-0.9/OPCODE/Ice/IceOBB.h new file mode 100644 index 0000000000..d6cf43e061 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceOBB.h @@ -0,0 +1,177 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains OBB-related code. (oriented bounding box) + * \file IceOBB.h + * \author Pierre Terdiman + * \date January, 13, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEOBB_H__ +#define __ICEOBB_H__ + + // Forward declarations + class LSS; + + class ICEMATHS_API OBB + { + public: + //! Constructor + inline_ OBB() {} + //! Constructor + inline_ OBB(const Point& center, const Point& extents, const Matrix3x3& rot) : mCenter(center), mExtents(extents), mRot(rot) {} + //! Destructor + inline_ ~OBB() {} + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups an empty OBB. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void SetEmpty() + { + mCenter.Zero(); + mExtents.Set(MIN_FLOAT, MIN_FLOAT, MIN_FLOAT); + mRot.Identity(); + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Tests if a point is contained within the OBB. + * \param p [in] the world point to test + * \return true if inside the OBB + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool ContainsPoint(const Point& p) const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Builds an OBB from an AABB and a world transform. + * \param aabb [in] the aabb + * \param mat [in] the world transform + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void Create(const AABB& aabb, const Matrix4x4& mat); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Recomputes the OBB after an arbitrary transform by a 4x4 matrix. + * \param mtx [in] the transform matrix + * \param obb [out] the transformed OBB + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void Rotate(const Matrix4x4& mtx, OBB& obb) const + { + // The extents remain constant + obb.mExtents = mExtents; + // The center gets x-formed + obb.mCenter = mCenter * mtx; + // Combine rotations + obb.mRot = mRot * Matrix3x3(mtx); + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks the OBB is valid. + * \return true if the box is valid + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL IsValid() const + { + // Consistency condition for (Center, Extents) boxes: Extents >= 0.0f + if(mExtents.x < 0.0f) return FALSE; + if(mExtents.y < 0.0f) return FALSE; + if(mExtents.z < 0.0f) return FALSE; + return TRUE; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes the obb planes. + * \param planes [out] 6 box planes + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool ComputePlanes(Plane* planes) const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes the obb points. + * \param pts [out] 8 box points + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool ComputePoints(Point* pts) const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes vertex normals. + * \param pts [out] 8 box points + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool ComputeVertexNormals(Point* pts) const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Returns edges. + * \return 24 indices (12 edges) indexing the list returned by ComputePoints() + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + const udword* GetEdges() const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Returns local edge normals. + * \return edge normals in local space + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + const Point* GetLocalEdgeNormals() const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Returns world edge normal + * \param edge_index [in] 0 <= edge index < 12 + * \param world_normal [out] edge normal in world space + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void ComputeWorldEdgeNormal(udword edge_index, Point& world_normal) const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes an LSS surrounding the OBB. + * \param lss [out] the LSS + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + void ComputeLSS(LSS& lss) const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks the OBB is inside another OBB. + * \param box [in] the other OBB + * \return TRUE if we're inside the other box + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + BOOL IsInside(const OBB& box) const; + + inline_ const Point& GetCenter() const { return mCenter; } + inline_ const Point& GetExtents() const { return mExtents; } + inline_ const Matrix3x3& GetRot() const { return mRot; } + + inline_ void GetRotatedExtents(Matrix3x3& extents) const + { + extents = mRot; + extents.Scale(mExtents); + } + + Point mCenter; //!< B for Box + Point mExtents; //!< B for Bounding + Matrix3x3 mRot; //!< O for Oriented + + // Orientation is stored in row-major format, + // i.e. rows = eigen vectors of the covariance matrix + }; + +#endif // __ICEOBB_H__ diff --git a/libraries/ode-0.9/OPCODE/Ice/IcePairs.h b/libraries/ode-0.9/OPCODE/Ice/IcePairs.h new file mode 100644 index 0000000000..2c09b92975 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IcePairs.h @@ -0,0 +1,45 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a simple pair class. + * \file IcePairs.h + * \author Pierre Terdiman + * \date January, 13, 2003 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEPAIRS_H__ +#define __ICEPAIRS_H__ + + //! A generic couple structure + struct ICECORE_API Pair + { + inline_ Pair() {} + inline_ Pair(udword i0, udword i1) : id0(i0), id1(i1) {} + + udword id0; //!< First index of the pair + udword id1; //!< Second index of the pair + }; + + class ICECORE_API Pairs : private Container + { + public: + // Constructor / Destructor + Pairs() {} + ~Pairs() {} + + inline_ udword GetNbPairs() const { return GetNbEntries()>>1; } + inline_ const Pair* GetPairs() const { return (const Pair*)GetEntries(); } + inline_ const Pair* GetPair(udword i) const { return (const Pair*)&GetEntries()[i+i]; } + + inline_ BOOL HasPairs() const { return IsNotEmpty(); } + + inline_ void ResetPairs() { Reset(); } + inline_ void DeleteLastPair() { DeleteLastEntry(); DeleteLastEntry(); } + + inline_ void AddPair(const Pair& p) { Add(p.id0).Add(p.id1); } + inline_ void AddPair(udword id0, udword id1) { Add(id0).Add(id1); } + }; + +#endif // __ICEPAIRS_H__ diff --git a/libraries/ode-0.9/OPCODE/Ice/IcePlane.cpp b/libraries/ode-0.9/OPCODE/Ice/IcePlane.cpp new file mode 100644 index 0000000000..394b31bf82 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IcePlane.cpp @@ -0,0 +1,45 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for planes. + * \file IcePlane.cpp + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Plane class. + * \class Plane + * \author Pierre Terdiman + * \version 1.0 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceMaths; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the plane equation from 3 points. + * \param p0 [in] first point + * \param p1 [in] second point + * \param p2 [in] third point + * \return Self-reference + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Plane& Plane::Set(const Point& p0, const Point& p1, const Point& p2) +{ + Point Edge0 = p1 - p0; + Point Edge1 = p2 - p0; + + n = Edge0 ^ Edge1; + n.Normalize(); + + d = -(p0 | n); + + return *this; +} diff --git a/libraries/ode-0.9/OPCODE/Ice/IcePlane.h b/libraries/ode-0.9/OPCODE/Ice/IcePlane.h new file mode 100644 index 0000000000..4d47081415 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IcePlane.h @@ -0,0 +1,113 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for planes. + * \file IcePlane.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEPLANE_H__ +#define __ICEPLANE_H__ + + #define PLANE_EPSILON (1.0e-7f) + + class ICEMATHS_API Plane + { + public: + //! Constructor + inline_ Plane() { } + //! Constructor from a normal and a distance + inline_ Plane(float nx, float ny, float nz, float d) { Set(nx, ny, nz, d); } + //! Constructor from a point on the plane and a normal + inline_ Plane(const Point& p, const Point& n) { Set(p, n); } + //! Constructor from three points + inline_ Plane(const Point& p0, const Point& p1, const Point& p2) { Set(p0, p1, p2); } + //! Constructor from a normal and a distance + inline_ Plane(const Point& _n, float _d) { n = _n; d = _d; } + //! Copy constructor + inline_ Plane(const Plane& plane) : n(plane.n), d(plane.d) { } + //! Destructor + inline_ ~Plane() { } + + inline_ Plane& Zero() { n.Zero(); d = 0.0f; return *this; } + inline_ Plane& Set(float nx, float ny, float nz, float _d) { n.Set(nx, ny, nz); d = _d; return *this; } + inline_ Plane& Set(const Point& p, const Point& _n) { n = _n; d = - p | _n; return *this; } + Plane& Set(const Point& p0, const Point& p1, const Point& p2); + + inline_ float Distance(const Point& p) const { return (p | n) + d; } + inline_ bool Belongs(const Point& p) const { return fabsf(Distance(p)) < PLANE_EPSILON; } + + inline_ void Normalize() + { + float Denom = 1.0f / n.Magnitude(); + n.x *= Denom; + n.y *= Denom; + n.z *= Denom; + d *= Denom; + } + public: + // Members + Point n; //!< The normal to the plane + float d; //!< The distance from the origin + + // Cast operators + inline_ operator Point() const { return n; } + inline_ operator HPoint() const { return HPoint(n, d); } + + // Arithmetic operators + inline_ Plane operator*(const Matrix4x4& m) const + { + // Old code from Irion. Kept for reference. + Plane Ret(*this); + return Ret *= m; + } + + inline_ Plane& operator*=(const Matrix4x4& m) + { + // Old code from Irion. Kept for reference. + Point n2 = HPoint(n, 0.0f) * m; + d = -((Point) (HPoint( -d*n, 1.0f ) * m) | n2); + n = n2; + return *this; + } + }; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Transforms a plane by a 4x4 matrix. Same as Plane * Matrix4x4 operator, but faster. + * \param transformed [out] transformed plane + * \param plane [in] source plane + * \param transform [in] transform matrix + * \warning the plane normal must be unit-length + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void TransformPlane(Plane& transformed, const Plane& plane, const Matrix4x4& transform) + { + // Rotate the normal using the rotation part of the 4x4 matrix + transformed.n = plane.n * Matrix3x3(transform); + + // Compute new d + transformed.d = plane.d - (Point(transform.GetTrans())|transformed.n); + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Transforms a plane by a 4x4 matrix. Same as Plane * Matrix4x4 operator, but faster. + * \param plane [in/out] source plane (transformed on return) + * \param transform [in] transform matrix + * \warning the plane normal must be unit-length + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void TransformPlane(Plane& plane, const Matrix4x4& transform) + { + // Rotate the normal using the rotation part of the 4x4 matrix + plane.n *= Matrix3x3(transform); + + // Compute new d + plane.d -= Point(transform.GetTrans())|plane.n; + } + +#endif // __ICEPLANE_H__ diff --git a/libraries/ode-0.9/OPCODE/Ice/IcePoint.cpp b/libraries/ode-0.9/OPCODE/Ice/IcePoint.cpp new file mode 100644 index 0000000000..e715055b8a --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IcePoint.cpp @@ -0,0 +1,193 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * 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; +} diff --git a/libraries/ode-0.9/OPCODE/Ice/IcePoint.h b/libraries/ode-0.9/OPCODE/Ice/IcePoint.h new file mode 100644 index 0000000000..a97fbe6f9a --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IcePoint.h @@ -0,0 +1,528 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * 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__ diff --git a/libraries/ode-0.9/OPCODE/Ice/IcePreprocessor.h b/libraries/ode-0.9/OPCODE/Ice/IcePreprocessor.h new file mode 100644 index 0000000000..dbeca3820d --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IcePreprocessor.h @@ -0,0 +1,132 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains preprocessor stuff. This should be the first included header. + * \file IcePreprocessor.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICEPREPROCESSOR_H__ +#define __ICEPREPROCESSOR_H__ + + // Check platform + #if defined( _WIN32 ) || defined( WIN32 ) + // #pragma message("Compiling on Windows...") + #define PLATFORM_WINDOWS + #else + // don't issue pragmas on unknown platforms + // #pragma message("Compiling on unknown platform...") + #endif + + // Check compiler + #if defined(_MSC_VER) + // #pragma message("Compiling with VC++...") + #define COMPILER_VISUAL_CPP + #else + // don't issue pragmas on unknown platforms + // #pragma message("Compiling with unknown compiler...") + #endif + + // Check compiler options. If this file is included in user-apps, this + // shouldn't be needed, so that they can use what they like best. + #ifndef ICE_DONT_CHECK_COMPILER_OPTIONS + #ifdef COMPILER_VISUAL_CPP + #if defined(_CHAR_UNSIGNED) + #endif + + #if defined(_CPPRTTI) + #error Please disable RTTI... + #endif + + #if defined(_CPPUNWIND) + #error Please disable exceptions... + #endif + + #if defined(_MT) + // Multithreading + #endif + #endif + #endif + + // Check debug mode + #ifdef DEBUG // May be defined instead of _DEBUG. Let's fix it. + #ifndef _DEBUG + #define _DEBUG + #endif + #endif + + #ifdef _DEBUG + // Here you may define items for debug builds + #endif + + #ifndef THIS_FILE + #define THIS_FILE __FILE__ + #endif + + #ifndef ICE_NO_DLL + #ifdef ICECORE_EXPORTS + #define ICECORE_API __declspec(dllexport) + #else + #define ICECORE_API __declspec(dllimport) + #endif + #else + #define ICECORE_API + #endif + + // Don't override new/delete +// #define DEFAULT_NEWDELETE + #define DONT_TRACK_MEMORY_LEAKS + + #define FUNCTION extern "C" + + // Cosmetic stuff [mainly useful with multiple inheritance] + #define override(base_class) virtual + + // Our own inline keyword, so that: + // - we can switch to __forceinline to check it's really better or not + // - we can remove __forceinline if the compiler doesn't support it +// #define inline_ __forceinline +// #define inline_ inline + + // Contributed by Bruce Mitchener + #if defined(COMPILER_VISUAL_CPP) + #define inline_ __forceinline +// #define inline_ inline + #elif defined(__GNUC__) && __GNUC__ < 3 + #define inline_ inline + #elif defined(__GNUC__) + #define inline_ inline __attribute__ ((always_inline)) + #else + #define inline_ inline + #endif + + // Down the hatch +#ifdef _MSC_VER + #pragma inline_depth( 255 ) +#endif + + #ifdef COMPILER_VISUAL_CPP + #pragma intrinsic(memcmp) + #pragma intrinsic(memcpy) + #pragma intrinsic(memset) + #pragma intrinsic(strcat) + #pragma intrinsic(strcmp) + #pragma intrinsic(strcpy) + #pragma intrinsic(strlen) + #pragma intrinsic(abs) + #pragma intrinsic(labs) + #endif + + // ANSI compliance + #ifdef _DEBUG + // Remove painful warning in debug + inline_ bool __False__(){ return false; } + #define for if(__False__()){} else for + #else + #define for if(0){} else for + #endif + +#endif // __ICEPREPROCESSOR_H__ diff --git a/libraries/ode-0.9/OPCODE/Ice/IceRandom.cpp b/libraries/ode-0.9/OPCODE/Ice/IceRandom.cpp new file mode 100644 index 0000000000..cc63a042ca --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceRandom.cpp @@ -0,0 +1,35 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for random generators. + * \file IceRandom.cpp + * \author Pierre Terdiman + * \date August, 9, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceCore; + +void IceCore:: SRand(udword seed) +{ + srand(seed); +} + +udword IceCore::Rand() +{ + return rand(); +} + + +static BasicRandom gRandomGenerator(42); + +udword IceCore::GetRandomIndex(udword max_index) +{ + // We don't use rand() since it's limited to RAND_MAX + udword Index = gRandomGenerator.Randomize(); + return Index % max_index; +} + diff --git a/libraries/ode-0.9/OPCODE/Ice/IceRandom.h b/libraries/ode-0.9/OPCODE/Ice/IceRandom.h new file mode 100644 index 0000000000..3170b33de5 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceRandom.h @@ -0,0 +1,42 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for random generators. + * \file IceRandom.h + * \author Pierre Terdiman + * \date August, 9, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICERANDOM_H__ +#define __ICERANDOM_H__ + + FUNCTION ICECORE_API void SRand(udword seed); + FUNCTION ICECORE_API udword Rand(); + + //! Returns a unit random floating-point value + inline_ float UnitRandomFloat() { return float(Rand()) * ONE_OVER_RAND_MAX; } + + //! Returns a random index so that 0<= index < max_index + ICECORE_API udword GetRandomIndex(udword max_index); + + class ICECORE_API BasicRandom + { + public: + + //! Constructor + inline_ BasicRandom(udword seed=0) : mRnd(seed) {} + //! Destructor + inline_ ~BasicRandom() {} + + inline_ void SetSeed(udword seed) { mRnd = seed; } + inline_ udword GetCurrentValue() const { return mRnd; } + inline_ udword Randomize() { mRnd = mRnd * 2147001325 + 715136305; return mRnd; } + + private: + udword mRnd; + }; + +#endif // __ICERANDOM_H__ + diff --git a/libraries/ode-0.9/OPCODE/Ice/IceRay.cpp b/libraries/ode-0.9/OPCODE/Ice/IceRay.cpp new file mode 100644 index 0000000000..6cf0330bc5 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceRay.cpp @@ -0,0 +1,84 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for rays. + * \file IceRay.cpp + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Ray class. + * A ray is a half-line P(t) = mOrig + mDir * t, with 0 <= t <= +infinity + * \class Ray + * \author Pierre Terdiman + * \version 1.0 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/* + O = Origin = impact point + i = normalized vector along the x axis + j = normalized vector along the y axis = actually the normal vector in O + D = Direction vector, norm |D| = 1 + N = Projection of D on y axis, norm |N| = normal reaction + T = Projection of D on x axis, norm |T| = tangential reaction + R = Reflexion vector + + ^y + | + | + | + _ _ _| _ _ _ + * * *| + \ | / + \ |N / | + R\ | /D + \ | / | + \ | / + _________\|/______*_______>x + O T + + Let define theta = angle between D and N. Then cos(theta) = |N| / |D| = |N| since D is normalized. + + j|D = |j|*|D|*cos(theta) => |N| = j|D + + Then we simply have: + + D = N + T + + To compute tangential reaction : + + T = D - N + + To compute reflexion vector : + + R = N - T = N - (D-N) = 2*N - D +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceMaths; + +float Ray::SquareDistance(const Point& point, float* t) const +{ + Point Diff = point - mOrig; + float fT = Diff | mDir; + + if(fT<=0.0f) + { + fT = 0.0f; + } + else + { + fT /= mDir.SquareMagnitude(); + Diff -= fT*mDir; + } + + if(t) *t = fT; + + return Diff.SquareMagnitude(); +} diff --git a/libraries/ode-0.9/OPCODE/Ice/IceRay.h b/libraries/ode-0.9/OPCODE/Ice/IceRay.h new file mode 100644 index 0000000000..0268287672 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceRay.h @@ -0,0 +1,98 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for rays. + * \file IceRay.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICERAY_H__ +#define __ICERAY_H__ + + class ICEMATHS_API Ray + { + public: + //! Constructor + inline_ Ray() {} + //! Constructor + inline_ Ray(const Point& orig, const Point& dir) : mOrig(orig), mDir(dir) {} + //! Copy constructor + inline_ Ray(const Ray& ray) : mOrig(ray.mOrig), mDir(ray.mDir) {} + //! Destructor + inline_ ~Ray() {} + + float SquareDistance(const Point& point, float* t=null) const; + inline_ float Distance(const Point& point, float* t=null) const { return sqrtf(SquareDistance(point, t)); } + + Point mOrig; //!< Ray origin + Point mDir; //!< Normalized direction + }; + + inline_ void ComputeReflexionVector(Point& reflected, const Point& incoming_dir, const Point& outward_normal) + { + reflected = incoming_dir - outward_normal * 2.0f * (incoming_dir|outward_normal); + } + + inline_ void ComputeReflexionVector(Point& reflected, const Point& source, const Point& impact, const Point& normal) + { + Point V = impact - source; + reflected = V - normal * 2.0f * (V|normal); + } + + inline_ void DecomposeVector(Point& normal_compo, Point& tangent_compo, const Point& outward_dir, const Point& outward_normal) + { + normal_compo = outward_normal * (outward_dir|outward_normal); + tangent_compo = outward_dir - normal_compo; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Transforms a direction vector from world space to local space + * \param local_dir [out] direction vector in local space + * \param world_dir [in] direction vector in world space + * \param world [in] world transform + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void ComputeLocalDirection(Point& local_dir, const Point& world_dir, const Matrix4x4& world) + { + // Get world direction back in local space +// Matrix3x3 InvWorld = world; +// local_dir = InvWorld * world_dir; + local_dir = Matrix3x3(world) * world_dir; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Transforms a position vector from world space to local space + * \param local_pt [out] position vector in local space + * \param world_pt [in] position vector in world space + * \param world [in] world transform + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void ComputeLocalPoint(Point& local_pt, const Point& world_pt, const Matrix4x4& world) + { + // Get world vertex back in local space + Matrix4x4 InvWorld = world; + InvWorld.Invert(); + local_pt = world_pt * InvWorld; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Transforms a ray from world space to local space + * \param local_ray [out] ray in local space + * \param world_ray [in] ray in world space + * \param world [in] world transform + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void ComputeLocalRay(Ray& local_ray, const Ray& world_ray, const Matrix4x4& world) + { + // Get world ray back in local space + ComputeLocalDirection(local_ray.mDir, world_ray.mDir, world); + ComputeLocalPoint(local_ray.mOrig, world_ray.mOrig, world); + } + +#endif // __ICERAY_H__ diff --git a/libraries/ode-0.9/OPCODE/Ice/IceRevisitedRadix.cpp b/libraries/ode-0.9/OPCODE/Ice/IceRevisitedRadix.cpp new file mode 100644 index 0000000000..3e351da941 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceRevisitedRadix.cpp @@ -0,0 +1,520 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains source code from the article "Radix Sort Revisited". + * \file IceRevisitedRadix.cpp + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Revisited Radix Sort. + * This is my new radix routine: + * - it uses indices and doesn't recopy the values anymore, hence wasting less ram + * - it creates all the histograms in one run instead of four + * - it sorts words faster than dwords and bytes faster than words + * - it correctly sorts negative floating-point values by patching the offsets + * - it automatically takes advantage of temporal coherence + * - multiple keys support is a side effect of temporal coherence + * - it may be worth recoding in asm... (mainly to use FCOMI, FCMOV, etc) [it's probably memory-bound anyway] + * + * History: + * - 08.15.98: very first version + * - 04.04.00: recoded for the radix article + * - 12.xx.00: code lifting + * - 09.18.01: faster CHECK_PASS_VALIDITY thanks to Mark D. Shattuck (who provided other tips, not included here) + * - 10.11.01: added local ram support + * - 01.20.02: bugfix! In very particular cases the last pass was skipped in the float code-path, leading to incorrect sorting...... + * - 01.02.02: - "mIndices" renamed => "mRanks". That's a rank sorter after all. + * - ranks are not "reset" anymore, but implicit on first calls + * - 07.05.02: - offsets rewritten with one less indirection. + * - 11.03.02: - "bool" replaced with RadixHint enum + * + * \class RadixSort + * \author Pierre Terdiman + * \version 1.4 + * \date August, 15, 1998 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/* +To do: + - add an offset parameter between two input values (avoid some data recopy sometimes) + - unroll ? asm ? + - 11 bits trick & 3 passes as Michael did + - prefetch stuff the day I have a P3 + - make a version with 16-bits indices ? +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceCore; + +#define INVALIDATE_RANKS mCurrentSize|=0x80000000 +#define VALIDATE_RANKS mCurrentSize&=0x7fffffff +#define CURRENT_SIZE (mCurrentSize&0x7fffffff) +#define INVALID_RANKS (mCurrentSize&0x80000000) + +#define CHECK_RESIZE(n) \ + if(n!=mPreviousSize) \ + { \ + if(n>mCurrentSize) Resize(n); \ + else ResetRanks(); \ + mPreviousSize = n; \ + } + +#define CREATE_HISTOGRAMS(type, buffer) \ + /* Clear counters/histograms */ \ + ZeroMemory(mHistogram, 256*4*sizeof(udword)); \ + \ + /* Prepare to count */ \ + ubyte* p = (ubyte*)input; \ + ubyte* pe = &p[nb*4]; \ + udword* h0= &mHistogram[0]; /* Histogram for first pass (LSB) */ \ + udword* h1= &mHistogram[256]; /* Histogram for second pass */ \ + udword* h2= &mHistogram[512]; /* Histogram for third pass */ \ + udword* h3= &mHistogram[768]; /* Histogram for last pass (MSB) */ \ + \ + bool AlreadySorted = true; /* Optimism... */ \ + \ + if(INVALID_RANKS) \ + { \ + /* Prepare for temporal coherence */ \ + type* Running = (type*)buffer; \ + type PrevVal = *Running; \ + \ + while(p!=pe) \ + { \ + /* Read input buffer in previous sorted order */ \ + type Val = *Running++; \ + /* Check whether already sorted or not */ \ + if(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=SqrLen) + { + fT = 1.0f; + Diff -= Dir; + } + else + { + fT /= SqrLen; + Diff -= fT*Dir; + } + } + + if(t) *t = fT; + + return Diff.SquareMagnitude(); +} diff --git a/libraries/ode-0.9/OPCODE/Ice/IceSegment.h b/libraries/ode-0.9/OPCODE/Ice/IceSegment.h new file mode 100644 index 0000000000..8d66322689 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceSegment.h @@ -0,0 +1,55 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for segments. + * \file IceSegment.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICESEGMENT_H__ +#define __ICESEGMENT_H__ + + class ICEMATHS_API Segment + { + public: + //! Constructor + inline_ Segment() {} + //! Constructor + inline_ Segment(const Point& p0, const Point& p1) : mP0(p0), mP1(p1) {} + //! Copy constructor + inline_ Segment(const Segment& seg) : mP0(seg.mP0), mP1(seg.mP1) {} + //! Destructor + inline_ ~Segment() {} + + inline_ const Point& GetOrigin() const { return mP0; } + inline_ Point ComputeDirection() const { return mP1 - mP0; } + inline_ void ComputeDirection(Point& dir) const { dir = mP1 - mP0; } + inline_ float ComputeLength() const { return mP1.Distance(mP0); } + inline_ float ComputeSquareLength() const { return mP1.SquareDistance(mP0); } + + inline_ void SetOriginDirection(const Point& origin, const Point& direction) + { + mP0 = mP1 = origin; + mP1 += direction; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Computes a point on the segment + * \param pt [out] point on segment + * \param t [in] point's parameter [t=0 => pt = mP0, t=1 => pt = mP1] + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void ComputePoint(Point& pt, float t) const { pt = mP0 + t * (mP1 - mP0); } + + float SquareDistance(const Point& point, float* t=null) const; + inline_ float Distance(const Point& point, float* t=null) const { return sqrtf(SquareDistance(point, t)); } + + Point mP0; //!< Start of segment + Point mP1; //!< End of segment + }; + +#endif // __ICESEGMENT_H__ diff --git a/libraries/ode-0.9/OPCODE/Ice/IceTriList.h b/libraries/ode-0.9/OPCODE/Ice/IceTriList.h new file mode 100644 index 0000000000..b2b6ecf642 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceTriList.h @@ -0,0 +1,61 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a triangle container. + * \file IceTrilist.h + * \author Pierre Terdiman + * \date April, 4, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICETRILIST_H__ +#define __ICETRILIST_H__ + + class ICEMATHS_API TriList : public Container + { + public: + // Constructor / Destructor + TriList() {} + ~TriList() {} + + inline_ udword GetNbTriangles() const { return GetNbEntries()/9; } + inline_ Triangle* GetTriangles() const { return (Triangle*)GetEntries(); } + + void AddTri(const Triangle& tri) + { + Add(tri.mVerts[0].x).Add(tri.mVerts[0].y).Add(tri.mVerts[0].z); + Add(tri.mVerts[1].x).Add(tri.mVerts[1].y).Add(tri.mVerts[1].z); + Add(tri.mVerts[2].x).Add(tri.mVerts[2].y).Add(tri.mVerts[2].z); + } + + void AddTri(const Point& p0, const Point& p1, const Point& p2) + { + Add(p0.x).Add(p0.y).Add(p0.z); + Add(p1.x).Add(p1.y).Add(p1.z); + Add(p2.x).Add(p2.y).Add(p2.z); + } + }; + + class ICEMATHS_API TriangleList : public Container + { + public: + // Constructor / Destructor + TriangleList() {} + ~TriangleList() {} + + inline_ udword GetNbTriangles() const { return GetNbEntries()/3; } + inline_ IndexedTriangle* GetTriangles() const { return (IndexedTriangle*)GetEntries();} + + void AddTriangle(const IndexedTriangle& tri) + { + Add(tri.mVRef[0]).Add(tri.mVRef[1]).Add(tri.mVRef[2]); + } + + void AddTriangle(udword vref0, udword vref1, udword vref2) + { + Add(vref0).Add(vref1).Add(vref2); + } + }; + +#endif //__ICETRILIST_H__ diff --git a/libraries/ode-0.9/OPCODE/Ice/IceTriangle.cpp b/libraries/ode-0.9/OPCODE/Ice/IceTriangle.cpp new file mode 100644 index 0000000000..4268ff4a3e --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceTriangle.cpp @@ -0,0 +1,286 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a handy triangle class. + * \file IceTriangle.cpp + * \author Pierre Terdiman + * \date January, 17, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace IceMaths; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a triangle class. + * + * \class Tri + * \author Pierre Terdiman + * \version 1.0 + * \date 08.15.98 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +static sdword VPlaneSideEps(const Point& v, const Plane& plane, float epsilon) +{ + // Compute distance from current vertex to the plane + float Dist = plane.Distance(v); + // Compute side: + // 1 = the vertex is on the positive side of the plane + // -1 = the vertex is on the negative side of the plane + // 0 = the vertex is on the plane (within epsilon) + return Dist > epsilon ? 1 : Dist < -epsilon ? -1 : 0; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Flips the winding order. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void Triangle::Flip() +{ + Point Tmp = mVerts[1]; + mVerts[1] = mVerts[2]; + mVerts[2] = Tmp; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle area. + * \return the area + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Triangle::Area() const +{ + const Point& p0 = mVerts[0]; + const Point& p1 = mVerts[1]; + const Point& p2 = mVerts[2]; + return ((p0 - p1)^(p0 - p2)).Magnitude() * 0.5f; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle perimeter. + * \return the perimeter + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Triangle::Perimeter() const +{ + const Point& p0 = mVerts[0]; + const Point& p1 = mVerts[1]; + const Point& p2 = mVerts[2]; + return p0.Distance(p1) + + p0.Distance(p2) + + p1.Distance(p2); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle compacity. + * \return the compacity + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Triangle::Compacity() const +{ + float P = Perimeter(); + if(P==0.0f) return 0.0f; + return (4.0f*PI*Area()/(P*P)); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle normal. + * \param normal [out] the computed normal + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void Triangle::Normal(Point& normal) const +{ + const Point& p0 = mVerts[0]; + const Point& p1 = mVerts[1]; + const Point& p2 = mVerts[2]; + normal = ((p0 - p1)^(p0 - p2)).Normalize(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle denormalized normal. + * \param normal [out] the computed normal + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void Triangle::DenormalizedNormal(Point& normal) const +{ + const Point& p0 = mVerts[0]; + const Point& p1 = mVerts[1]; + const Point& p2 = mVerts[2]; + normal = ((p0 - p1)^(p0 - p2)); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle center. + * \param center [out] the computed center + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void Triangle::Center(Point& center) const +{ + const Point& p0 = mVerts[0]; + const Point& p1 = mVerts[1]; + const Point& p2 = mVerts[2]; + center = (p0 + p1 + p2)*INV3; +} + +PartVal Triangle::TestAgainstPlane(const Plane& plane, float epsilon) const +{ + bool Pos = false, Neg = false; + + // Loop through all vertices + for(udword i=0;i<3;i++) + { + // Compute side: + sdword Side = VPlaneSideEps(mVerts[i], plane, epsilon); + + if (Side < 0) Neg = true; + else if (Side > 0) Pos = true; + } + + if (!Pos && !Neg) return TRI_ON_PLANE; + else if (Pos && Neg) return TRI_INTERSECT; + else if (Pos && !Neg) return TRI_PLUS_SPACE; + else if (!Pos && Neg) return TRI_MINUS_SPACE; + + // What?! + return TRI_FORCEDWORD; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle moment. + * \param m [out] the moment + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* +void Triangle::ComputeMoment(Moment& m) +{ + // Compute the area of the triangle + m.mArea = Area(); + + // Compute the centroid + Center(m.mCentroid); + + // Second-order components. Handle zero-area faces. + Point& p = mVerts[0]; + Point& q = mVerts[1]; + Point& r = mVerts[2]; + if(m.mArea==0.0f) + { + // This triangle has zero area. The second order components would be eliminated with the usual formula, so, for the + // sake of robustness we use an alternative form. These are the centroid and second-order components of the triangle's vertices. + m.mCovariance.m[0][0] = (p.x*p.x + q.x*q.x + r.x*r.x); + m.mCovariance.m[0][1] = (p.x*p.y + q.x*q.y + r.x*r.y); + m.mCovariance.m[0][2] = (p.x*p.z + q.x*q.z + r.x*r.z); + m.mCovariance.m[1][1] = (p.y*p.y + q.y*q.y + r.y*r.y); + m.mCovariance.m[1][2] = (p.y*p.z + q.y*q.z + r.y*r.z); + m.mCovariance.m[2][2] = (p.z*p.z + q.z*q.z + r.z*r.z); + m.mCovariance.m[2][1] = m.mCovariance.m[1][2]; + m.mCovariance.m[1][0] = m.mCovariance.m[0][1]; + m.mCovariance.m[2][0] = m.mCovariance.m[0][2]; + } + else + { + const float OneOverTwelve = 1.0f / 12.0f; + m.mCovariance.m[0][0] = m.mArea * (9.0f * m.mCentroid.x*m.mCentroid.x + p.x*p.x + q.x*q.x + r.x*r.x) * OneOverTwelve; + m.mCovariance.m[0][1] = m.mArea * (9.0f * m.mCentroid.x*m.mCentroid.y + p.x*p.y + q.x*q.y + r.x*r.y) * OneOverTwelve; + m.mCovariance.m[1][1] = m.mArea * (9.0f * m.mCentroid.y*m.mCentroid.y + p.y*p.y + q.y*q.y + r.y*r.y) * OneOverTwelve; + m.mCovariance.m[0][2] = m.mArea * (9.0f * m.mCentroid.x*m.mCentroid.z + p.x*p.z + q.x*q.z + r.x*r.z) * OneOverTwelve; + m.mCovariance.m[1][2] = m.mArea * (9.0f * m.mCentroid.y*m.mCentroid.z + p.y*p.z + q.y*q.z + r.y*r.z) * OneOverTwelve; + m.mCovariance.m[2][2] = m.mArea * (9.0f * m.mCentroid.z*m.mCentroid.z + p.z*p.z + q.z*q.z + r.z*r.z) * OneOverTwelve; + m.mCovariance.m[2][1] = m.mCovariance.m[1][2]; + m.mCovariance.m[1][0] = m.mCovariance.m[0][1]; + m.mCovariance.m[2][0] = m.mCovariance.m[0][2]; + } +} +*/ + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle's smallest edge length. + * \return the smallest edge length + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Triangle::MinEdgeLength() const +{ + float Min = MAX_FLOAT; + float Length01 = mVerts[0].Distance(mVerts[1]); + float Length02 = mVerts[0].Distance(mVerts[2]); + float Length12 = mVerts[1].Distance(mVerts[2]); + if(Length01 < Min) Min = Length01; + if(Length02 < Min) Min = Length02; + if(Length12 < Min) Min = Length12; + return Min; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes the triangle's largest edge length. + * \return the largest edge length + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +float Triangle::MaxEdgeLength() const +{ + float Max = MIN_FLOAT; + float Length01 = mVerts[0].Distance(mVerts[1]); + float Length02 = mVerts[0].Distance(mVerts[2]); + float Length12 = mVerts[1].Distance(mVerts[2]); + if(Length01 > Max) Max = Length01; + if(Length02 > Max) Max = Length02; + if(Length12 > Max) Max = Length12; + return Max; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes a point on the triangle according to the stabbing information. + * \param u,v [in] point's barycentric coordinates + * \param pt [out] point on triangle + * \param nearvtx [out] index of nearest vertex + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void Triangle::ComputePoint(float u, float v, Point& pt, udword* nearvtx) const +{ + // Compute point coordinates + pt = (1.0f - u - v)*mVerts[0] + u*mVerts[1] + v*mVerts[2]; + + // Compute nearest vertex if needed + if(nearvtx) + { + // Compute distance vector + Point d(mVerts[0].SquareDistance(pt), // Distance^2 from vertex 0 to point on the face + mVerts[1].SquareDistance(pt), // Distance^2 from vertex 1 to point on the face + mVerts[2].SquareDistance(pt)); // Distance^2 from vertex 2 to point on the face + + // Get smallest distance + *nearvtx = d.SmallestAxis(); + } +} + +void Triangle::Inflate(float fat_coeff, bool constant_border) +{ + // Compute triangle center + Point TriangleCenter; + Center(TriangleCenter); + + // Don't normalize? + // Normalize => add a constant border, regardless of triangle size + // Don't => add more to big triangles + for(udword i=0;i<3;i++) + { + Point v = mVerts[i] - TriangleCenter; + + if(constant_border) v.Normalize(); + + mVerts[i] += v * fat_coeff; + } +} diff --git a/libraries/ode-0.9/OPCODE/Ice/IceTriangle.h b/libraries/ode-0.9/OPCODE/Ice/IceTriangle.h new file mode 100644 index 0000000000..a984db835a --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceTriangle.h @@ -0,0 +1,68 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a handy triangle class. + * \file IceTriangle.h + * \author Pierre Terdiman + * \date January, 17, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __ICETRIANGLE_H__ +#define __ICETRIANGLE_H__ + + // Forward declarations + class Moment; + + // Partitioning values + enum PartVal + { + TRI_MINUS_SPACE = 0, //!< Triangle is in the negative space + TRI_PLUS_SPACE = 1, //!< Triangle is in the positive space + TRI_INTERSECT = 2, //!< Triangle intersects plane + TRI_ON_PLANE = 3, //!< Triangle and plane are coplanar + + TRI_FORCEDWORD = 0x7fffffff + }; + + // A triangle class. + class ICEMATHS_API Triangle + { + public: + //! Constructor + inline_ Triangle() {} + //! Constructor + inline_ Triangle(const Point& p0, const Point& p1, const Point& p2) { mVerts[0]=p0; mVerts[1]=p1; mVerts[2]=p2; } + //! Copy constructor + inline_ Triangle(const Triangle& triangle) + { + mVerts[0] = triangle.mVerts[0]; + mVerts[1] = triangle.mVerts[1]; + mVerts[2] = triangle.mVerts[2]; + } + //! Destructor + inline_ ~Triangle() {} + //! Vertices + Point mVerts[3]; + + // Methods + void Flip(); + float Area() const; + float Perimeter() const; + float Compacity() const; + void Normal(Point& normal) const; + void DenormalizedNormal(Point& normal) const; + void Center(Point& center) const; + inline_ Plane PlaneEquation() const { return Plane(mVerts[0], mVerts[1], mVerts[2]); } + + PartVal TestAgainstPlane(const Plane& plane, float epsilon) const; +// float Distance(Point& cp, Point& cq, Tri& tri); + void ComputeMoment(Moment& m); + float MinEdgeLength() const; + float MaxEdgeLength() const; + void ComputePoint(float u, float v, Point& pt, udword* nearvtx=null) const; + void Inflate(float fat_coeff, bool constant_border); + }; + +#endif // __ICETRIANGLE_H__ diff --git a/libraries/ode-0.9/OPCODE/Ice/IceTypes.h b/libraries/ode-0.9/OPCODE/Ice/IceTypes.h new file mode 100644 index 0000000000..4ff71b51e3 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IceTypes.h @@ -0,0 +1,171 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * 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 + +#if defined(__MACOSX__) || defined(__APPLE__) +#undef bool +#define bool char +#undef true +#define true ((bool)-1) +#undef false +#define false ((bool)0) +#endif // mac stuff + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + #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(bool)==1); // ...otherwise things might fail with VC++ 4.2 ! + 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> 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__ diff --git a/libraries/ode-0.9/OPCODE/OPC_AABBCollider.cpp b/libraries/ode-0.9/OPCODE/OPC_AABBCollider.cpp new file mode 100644 index 0000000000..eaaadf1003 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_AABBCollider.cpp @@ -0,0 +1,696 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for an AABB collider. + * \file OPC_AABBCollider.cpp + * \author Pierre Terdiman + * \date January, 1st, 2002 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains an AABB-vs-tree collider. + * + * \class AABBCollider + * \author Pierre Terdiman + * \version 1.3 + * \date January, 1st, 2002 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +#include "OPC_BoxBoxOverlap.h" +#include "OPC_TriBoxOverlap.h" + +#define SET_CONTACT(prim_index, flag) \ + /* Set contact status */ \ + mFlags |= flag; \ + mTouchedPrimitives->Add(udword(prim_index)); + +//! AABB-triangle test +#define AABB_PRIM(prim_index, flag) \ + /* Request vertices from the app */ \ + VertexPointers VP; mIMesh->GetTriangle(VP, prim_index);\ + 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; +} diff --git a/libraries/ode-0.9/OPCODE/OPC_AABBCollider.h b/libraries/ode-0.9/OPCODE/OPC_AABBCollider.h new file mode 100644 index 0000000000..315d2d3366 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_AABBCollider.h @@ -0,0 +1,97 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for an AABB collider. + * \file OPC_AABBCollider.h + * \author Pierre Terdiman + * \date January, 1st, 2002 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_AABBCOLLIDER_H__ +#define __OPC_AABBCOLLIDER_H__ + + struct OPCODE_API AABBCache : VolumeCache + { + AABBCache() : FatCoeff(1.1f) + { + FatBox.mCenter.Zero(); + FatBox.mExtents.Zero(); + } + + // Cached faces signature + CollisionAABB FatBox; //!< Box used when performing the query resulting in cached faces + // User settings + float FatCoeff; //!< mRadius2 multiplier used to create a fat sphere + }; + + class OPCODE_API AABBCollider : public VolumeCollider + { + public: + // Constructor / Destructor + AABBCollider(); + virtual ~AABBCollider(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Generic collision query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - with GetNbTouchedPrimitives() + * - with GetTouchedPrimitives() + * + * \param cache [in/out] a box cache + * \param box [in] collision AABB in world space + * \param model [in] Opcode model to collide with + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool Collide(AABBCache& cache, const CollisionAABB& box, const Model& model); + // + bool Collide(AABBCache& cache, const CollisionAABB& box, const AABBTree* tree); + protected: + CollisionAABB mBox; //!< Query box in (center, extents) form + Point mMin; //!< Query box min point + Point mMax; //!< Query box max point + // Leaf description + Point mLeafVerts[3]; //!< Triangle vertices + // Internal methods + void _Collide(const AABBCollisionNode* node); + void _Collide(const AABBNoLeafNode* node); + void _Collide(const AABBQuantizedNode* node); + void _Collide(const AABBQuantizedNoLeafNode* node); + void _Collide(const AABBTreeNode* node); + void _CollideNoPrimitiveTest(const AABBCollisionNode* node); + void _CollideNoPrimitiveTest(const AABBNoLeafNode* node); + void _CollideNoPrimitiveTest(const AABBQuantizedNode* node); + void _CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node); + // Overlap tests + inline_ BOOL AABBContainsBox(const Point& bc, const Point& be); + inline_ BOOL AABBAABBOverlap(const Point& b, const Point& Pb); + inline_ BOOL TriBoxOverlap(); + // Init methods + BOOL InitQuery(AABBCache& cache, const CollisionAABB& box); + }; + + class OPCODE_API HybridAABBCollider : public AABBCollider + { + public: + // Constructor / Destructor + HybridAABBCollider(); + virtual ~HybridAABBCollider(); + + bool Collide(AABBCache& cache, const CollisionAABB& box, const HybridModel& model); + protected: + Container mTouchedBoxes; + }; + +#endif // __OPC_AABBCOLLIDER_H__ diff --git a/libraries/ode-0.9/OPCODE/OPC_AABBTree.cpp b/libraries/ode-0.9/OPCODE/OPC_AABBTree.cpp new file mode 100644 index 0000000000..32214f4152 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_AABBTree.cpp @@ -0,0 +1,573 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * 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 + mNbPrimitives (0), + mNodePrimitives (null) +{ +#ifdef OPC_USE_TREE_COHERENCE + mBitmask = 0; +#endif +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +AABBTreeNode::~AABBTreeNode() +{ + // Opcode 1.3: + const AABBTreeNode* Pos = GetPos(); + const AABBTreeNode* Neg = GetNeg(); +#ifndef OPC_NO_NEG_VANILLA_TREE + 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), mTotalNbNodes(0), mPool(null) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * 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 udword[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); +} diff --git a/libraries/ode-0.9/OPCODE/OPC_AABBTree.h b/libraries/ode-0.9/OPCODE/OPC_AABBTree.h new file mode 100644 index 0000000000..ee2533db66 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_AABBTree.h @@ -0,0 +1,137 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a versatile AABB tree. + * \file OPC_AABBTree.h + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_AABBTREE_H__ +#define __OPC_AABBTREE_H__ + +#ifdef OPC_NO_NEG_VANILLA_TREE + //! TO BE DOCUMENTED + #define IMPLEMENT_TREE(base_class, volume) \ + public: \ + /* Constructor / Destructor */ \ + base_class(); \ + ~base_class(); \ + /* Data access */ \ + inline_ const volume* Get##volume() const { return &mBV; } \ + /* Clear the last bit */ \ + inline_ const base_class* GetPos() const { return (const base_class*)(mPos&~1); } \ + inline_ const base_class* GetNeg() const { const base_class* P = GetPos(); return P ? P+1 : null;} \ + \ + /* We don't need to test both nodes since we can't have one without the other */ \ + inline_ bool IsLeaf() const { return !GetPos(); } \ + \ + /* Stats */ \ + inline_ udword GetNodeSize() const { return SIZEOFOBJECT; } \ + protected: \ + /* Tree-independent data */ \ + /* Following data always belong to the BV-tree, regardless of what the tree actually contains.*/ \ + /* Whatever happens we need the two children and the enclosing volume.*/ \ + volume mBV; /* Global bounding-volume enclosing all the node-related primitives */ \ + size_t mPos; /* "Positive" & "Negative" children */ +#else + //! TO BE DOCUMENTED + #define IMPLEMENT_TREE(base_class, volume) \ + public: \ + /* Constructor / Destructor */ \ + base_class(); \ + ~base_class(); \ + /* Data access */ \ + inline_ const volume* Get##volume() const { return &mBV; } \ + /* Clear the last bit */ \ + inline_ const base_class* GetPos() const { return (const base_class*)(mPos&~1); } \ + inline_ const base_class* GetNeg() const { return (const base_class*)(mNeg&~1); } \ + \ +/* inline_ bool IsLeaf() const { return (!GetPos() && !GetNeg()); } */ \ + /* We don't need to test both nodes since we can't have one without the other */ \ + inline_ bool IsLeaf() const { return !GetPos(); } \ + \ + /* Stats */ \ + inline_ udword GetNodeSize() const { return SIZEOFOBJECT; } \ + protected: \ + /* Tree-independent data */ \ + /* Following data always belong to the BV-tree, regardless of what the tree actually contains.*/ \ + /* Whatever happens we need the two children and the enclosing volume.*/ \ + volume mBV; /* Global bounding-volume enclosing all the node-related primitives */ \ + size_t mPos; /* "Positive" child */ \ + size_t mNeg; /* "Negative" child */ +#endif + + typedef void (*CullingCallback) (udword nb_primitives, udword* node_primitives, BOOL need_clipping, void* user_data); + + class OPCODE_API AABBTreeNode + { + IMPLEMENT_TREE(AABBTreeNode, AABB) + public: + // Data access + inline_ const udword* GetPrimitives() const { return mNodePrimitives; } + inline_ udword GetNbPrimitives() const { return mNbPrimitives; } + + protected: + // Tree-dependent data + udword* 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 udword* 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: + udword* mIndices; //!< Indices in the app list. Indices are reorganized during build (permutation). + AABBTreeNode* mPool; //!< Linear pool of nodes for complete trees. Null otherwise. [Opcode 1.3] + // Stats + udword mTotalNbNodes; //!< Number of nodes in the tree. + }; + +#endif // __OPC_AABBTREE_H__ diff --git a/libraries/ode-0.9/OPCODE/OPC_BaseModel.cpp b/libraries/ode-0.9/OPCODE/OPC_BaseModel.cpp new file mode 100644 index 0000000000..9520d9ef3f --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_BaseModel.cpp @@ -0,0 +1,138 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains base model interface. + * \file OPC_BaseModel.cpp + * \author Pierre Terdiman + * \date May, 18, 2003 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * The base class for collision models. + * + * \class BaseModel + * \author Pierre Terdiman + * \version 1.3 + * \date May, 18, 2003 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +OPCODECREATE::OPCODECREATE() +{ + mIMesh = null; + mSettings.mRules = SPLIT_SPLATTER_POINTS | SPLIT_GEOM_CENTER; + mSettings.mLimit = 1; // Mandatory for complete trees + mNoLeaf = true; + mQuantized = true; +#ifdef __MESHMERIZER_H__ + mCollisionHull = false; +#endif // __MESHMERIZER_H__ + mKeepOriginal = false; + mCanRemap = false; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +BaseModel::BaseModel() : mIMesh(null), mModelCode(0), mSource(null), mTree(null) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +BaseModel::~BaseModel() +{ + ReleaseBase(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Releases everything. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void BaseModel::ReleaseBase() +{ + DELETESINGLE(mSource); + DELETESINGLE(mTree); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Creates an optimized tree according to user-settings, and setups mModelCode. + * \param no_leaf [in] true for "no leaf" tree + * \param quantized [in] true for quantized tree + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool BaseModel::CreateTree(bool no_leaf, bool quantized) +{ + DELETESINGLE(mTree); + + // Setup model code + if(no_leaf) mModelCode |= OPC_NO_LEAF; + else mModelCode &= ~OPC_NO_LEAF; + + if(quantized) mModelCode |= OPC_QUANTIZED; + else mModelCode &= ~OPC_QUANTIZED; + + // Create the correct class + if(mModelCode & OPC_NO_LEAF) + { + if(mModelCode & OPC_QUANTIZED) mTree = new AABBQuantizedNoLeafTree; + else mTree = new AABBNoLeafTree; + } + else + { + if(mModelCode & OPC_QUANTIZED) mTree = new AABBQuantizedTree; + else mTree = new AABBCollisionTree; + } + CHECKALLOC(mTree); + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Refits the collision model. This can be used to handle dynamic meshes. Usage is: + * 1. modify your mesh vertices (keep the topology constant!) + * 2. refit the tree (call this method) + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool BaseModel::Refit() +{ + // Refit the optimized tree + return mTree->Refit(mIMesh); + +// Old code kept for reference : refit the source tree then rebuild ! +// if(!mSource) return false; +// // Ouch... +// mSource->Refit(&mTB); +// // Ouch... +// return mTree->Build(mSource); +} diff --git a/libraries/ode-0.9/OPCODE/OPC_BaseModel.h b/libraries/ode-0.9/OPCODE/OPC_BaseModel.h new file mode 100644 index 0000000000..c6072dbd5b --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_BaseModel.h @@ -0,0 +1,175 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * 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__ diff --git a/libraries/ode-0.9/OPCODE/OPC_BoxBoxOverlap.h b/libraries/ode-0.9/OPCODE/OPC_BoxBoxOverlap.h new file mode 100644 index 0000000000..757a17dd20 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_BoxBoxOverlap.h @@ -0,0 +1,122 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * OBB-OBB overlap test using the separating axis theorem. + * - original code by Gomez / Gamasutra (similar to Gottschalk's one in RAPID) + * - optimized for AABB trees by computing the rotation matrix once (SOLID-fashion) + * - the fabs matrix is precomputed as well and epsilon-tweaked (RAPID-style, we found this almost mandatory) + * - Class III axes can be disabled... (SOLID & Intel fashion) + * - ...or enabled to perform some profiling + * - CPU comparisons used when appropriate + * - lazy evaluation sometimes saves some work in case of early exits (unlike SOLID) + * + * \param ea [in] extents from box A + * \param ca [in] center from box A + * \param eb [in] extents from box B + * \param cb [in] center from box B + * \return true if boxes overlap + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL AABBTreeCollider::BoxBoxOverlap(const Point& ea, const Point& ca, const Point& eb, const Point& cb) +{ + // Stats + mNbBVBVTests++; + + float t,t2; + + // Class I : A's basis vectors + float Tx = (mR1to0.m[0][0]*cb.x + mR1to0.m[1][0]*cb.y + mR1to0.m[2][0]*cb.z) + mT1to0.x - ca.x; + t = ea.x + eb.x*mAR.m[0][0] + eb.y*mAR.m[1][0] + eb.z*mAR.m[2][0]; + if(GREATER(Tx, t)) return FALSE; + + float Ty = (mR1to0.m[0][1]*cb.x + mR1to0.m[1][1]*cb.y + mR1to0.m[2][1]*cb.z) + mT1to0.y - ca.y; + t = ea.y + eb.x*mAR.m[0][1] + eb.y*mAR.m[1][1] + eb.z*mAR.m[2][1]; + if(GREATER(Ty, t)) return FALSE; + + float Tz = (mR1to0.m[0][2]*cb.x + mR1to0.m[1][2]*cb.y + mR1to0.m[2][2]*cb.z) + mT1to0.z - ca.z; + t = ea.z + eb.x*mAR.m[0][2] + eb.y*mAR.m[1][2] + eb.z*mAR.m[2][2]; + if(GREATER(Tz, t)) return FALSE; + + // Class II : B's basis vectors + t = Tx*mR1to0.m[0][0] + Ty*mR1to0.m[0][1] + Tz*mR1to0.m[0][2]; t2 = ea.x*mAR.m[0][0] + ea.y*mAR.m[0][1] + ea.z*mAR.m[0][2] + eb.x; + if(GREATER(t, t2)) return FALSE; + + t = Tx*mR1to0.m[1][0] + Ty*mR1to0.m[1][1] + Tz*mR1to0.m[1][2]; t2 = ea.x*mAR.m[1][0] + ea.y*mAR.m[1][1] + ea.z*mAR.m[1][2] + eb.y; + if(GREATER(t, t2)) return FALSE; + + t = Tx*mR1to0.m[2][0] + Ty*mR1to0.m[2][1] + Tz*mR1to0.m[2][2]; t2 = ea.x*mAR.m[2][0] + ea.y*mAR.m[2][1] + ea.z*mAR.m[2][2] + eb.z; + if(GREATER(t, t2)) return FALSE; + + // Class III : 9 cross products + // Cool trick: always perform the full test for first level, regardless of settings. + // That way pathological cases (such as the pencils scene) are quickly rejected anyway ! + if(mFullBoxBoxTest || mNbBVBVTests==1) + { + t = Tz*mR1to0.m[0][1] - Ty*mR1to0.m[0][2]; t2 = ea.y*mAR.m[0][2] + ea.z*mAR.m[0][1] + eb.y*mAR.m[2][0] + eb.z*mAR.m[1][0]; if(GREATER(t, t2)) return FALSE; // L = A0 x B0 + t = Tz*mR1to0.m[1][1] - Ty*mR1to0.m[1][2]; t2 = ea.y*mAR.m[1][2] + ea.z*mAR.m[1][1] + eb.x*mAR.m[2][0] + eb.z*mAR.m[0][0]; if(GREATER(t, t2)) return FALSE; // L = A0 x B1 + t = Tz*mR1to0.m[2][1] - Ty*mR1to0.m[2][2]; t2 = ea.y*mAR.m[2][2] + ea.z*mAR.m[2][1] + eb.x*mAR.m[1][0] + eb.y*mAR.m[0][0]; if(GREATER(t, t2)) return FALSE; // L = A0 x B2 + t = Tx*mR1to0.m[0][2] - Tz*mR1to0.m[0][0]; t2 = ea.x*mAR.m[0][2] + ea.z*mAR.m[0][0] + eb.y*mAR.m[2][1] + eb.z*mAR.m[1][1]; if(GREATER(t, t2)) return FALSE; // L = A1 x B0 + t = Tx*mR1to0.m[1][2] - Tz*mR1to0.m[1][0]; t2 = ea.x*mAR.m[1][2] + ea.z*mAR.m[1][0] + eb.x*mAR.m[2][1] + eb.z*mAR.m[0][1]; if(GREATER(t, t2)) return FALSE; // L = A1 x B1 + t = Tx*mR1to0.m[2][2] - Tz*mR1to0.m[2][0]; t2 = ea.x*mAR.m[2][2] + ea.z*mAR.m[2][0] + eb.x*mAR.m[1][1] + eb.y*mAR.m[0][1]; if(GREATER(t, t2)) return FALSE; // L = A1 x B2 + t = Ty*mR1to0.m[0][0] - Tx*mR1to0.m[0][1]; t2 = ea.x*mAR.m[0][1] + ea.y*mAR.m[0][0] + eb.y*mAR.m[2][2] + eb.z*mAR.m[1][2]; if(GREATER(t, t2)) return FALSE; // L = A2 x B0 + t = Ty*mR1to0.m[1][0] - Tx*mR1to0.m[1][1]; t2 = ea.x*mAR.m[1][1] + ea.y*mAR.m[1][0] + eb.x*mAR.m[2][2] + eb.z*mAR.m[0][2]; if(GREATER(t, t2)) return FALSE; // L = A2 x B1 + t = Ty*mR1to0.m[2][0] - Tx*mR1to0.m[2][1]; t2 = ea.x*mAR.m[2][1] + ea.y*mAR.m[2][0] + eb.x*mAR.m[1][2] + eb.y*mAR.m[0][2]; if(GREATER(t, t2)) return FALSE; // L = A2 x B2 + } + return TRUE; +} + +//! A dedicated version when one box is constant +inline_ BOOL OBBCollider::BoxBoxOverlap(const Point& extents, const Point& center) +{ + // Stats + mNbVolumeBVTests++; + + float t,t2; + + // Class I : A's basis vectors + float Tx = mTBoxToModel.x - center.x; t = extents.x + mBBx1; if(GREATER(Tx, t)) return FALSE; + float Ty = mTBoxToModel.y - center.y; t = extents.y + mBBy1; if(GREATER(Ty, t)) return FALSE; + float Tz = mTBoxToModel.z - center.z; t = extents.z + mBBz1; if(GREATER(Tz, t)) return FALSE; + + // Class II : B's basis vectors + t = Tx*mRBoxToModel.m[0][0] + Ty*mRBoxToModel.m[0][1] + Tz*mRBoxToModel.m[0][2]; + t2 = extents.x*mAR.m[0][0] + extents.y*mAR.m[0][1] + extents.z*mAR.m[0][2] + mBoxExtents.x; + if(GREATER(t, t2)) return FALSE; + + t = Tx*mRBoxToModel.m[1][0] + Ty*mRBoxToModel.m[1][1] + Tz*mRBoxToModel.m[1][2]; + t2 = extents.x*mAR.m[1][0] + extents.y*mAR.m[1][1] + extents.z*mAR.m[1][2] + mBoxExtents.y; + if(GREATER(t, t2)) return FALSE; + + t = Tx*mRBoxToModel.m[2][0] + Ty*mRBoxToModel.m[2][1] + Tz*mRBoxToModel.m[2][2]; + t2 = extents.x*mAR.m[2][0] + extents.y*mAR.m[2][1] + extents.z*mAR.m[2][2] + mBoxExtents.z; + if(GREATER(t, t2)) return FALSE; + + // Class III : 9 cross products + // Cool trick: always perform the full test for first level, regardless of settings. + // That way pathological cases (such as the pencils scene) are quickly rejected anyway ! + if(mFullBoxBoxTest || mNbVolumeBVTests==1) + { + t = Tz*mRBoxToModel.m[0][1] - Ty*mRBoxToModel.m[0][2]; t2 = extents.y*mAR.m[0][2] + extents.z*mAR.m[0][1] + mBB_1; if(GREATER(t, t2)) return FALSE; // L = A0 x B0 + t = Tz*mRBoxToModel.m[1][1] - Ty*mRBoxToModel.m[1][2]; t2 = extents.y*mAR.m[1][2] + extents.z*mAR.m[1][1] + mBB_2; if(GREATER(t, t2)) return FALSE; // L = A0 x B1 + t = Tz*mRBoxToModel.m[2][1] - Ty*mRBoxToModel.m[2][2]; t2 = extents.y*mAR.m[2][2] + extents.z*mAR.m[2][1] + mBB_3; if(GREATER(t, t2)) return FALSE; // L = A0 x B2 + t = Tx*mRBoxToModel.m[0][2] - Tz*mRBoxToModel.m[0][0]; t2 = extents.x*mAR.m[0][2] + extents.z*mAR.m[0][0] + mBB_4; if(GREATER(t, t2)) return FALSE; // L = A1 x B0 + t = Tx*mRBoxToModel.m[1][2] - Tz*mRBoxToModel.m[1][0]; t2 = extents.x*mAR.m[1][2] + extents.z*mAR.m[1][0] + mBB_5; if(GREATER(t, t2)) return FALSE; // L = A1 x B1 + t = Tx*mRBoxToModel.m[2][2] - Tz*mRBoxToModel.m[2][0]; t2 = extents.x*mAR.m[2][2] + extents.z*mAR.m[2][0] + mBB_6; if(GREATER(t, t2)) return FALSE; // L = A1 x B2 + t = Ty*mRBoxToModel.m[0][0] - Tx*mRBoxToModel.m[0][1]; t2 = extents.x*mAR.m[0][1] + extents.y*mAR.m[0][0] + mBB_7; if(GREATER(t, t2)) return FALSE; // L = A2 x B0 + t = Ty*mRBoxToModel.m[1][0] - Tx*mRBoxToModel.m[1][1]; t2 = extents.x*mAR.m[1][1] + extents.y*mAR.m[1][0] + mBB_8; if(GREATER(t, t2)) return FALSE; // L = A2 x B1 + t = Ty*mRBoxToModel.m[2][0] - Tx*mRBoxToModel.m[2][1]; t2 = extents.x*mAR.m[2][1] + extents.y*mAR.m[2][0] + mBB_9; if(GREATER(t, t2)) return FALSE; // L = A2 x B2 + } + return TRUE; +} + +//! A special version for 2 axis-aligned boxes +inline_ BOOL AABBCollider::AABBAABBOverlap(const Point& extents, const Point& center) +{ + // Stats + mNbVolumeBVTests++; + + float tx = mBox.mCenter.x - center.x; float ex = extents.x + mBox.mExtents.x; if(GREATER(tx, ex)) return FALSE; + float ty = mBox.mCenter.y - center.y; float ey = extents.y + mBox.mExtents.y; if(GREATER(ty, ey)) return FALSE; + float tz = mBox.mCenter.z - center.z; float ez = extents.z + mBox.mExtents.z; if(GREATER(tz, ez)) return FALSE; + + return TRUE; +} diff --git a/libraries/ode-0.9/OPCODE/OPC_BoxPruning.cpp b/libraries/ode-0.9/OPCODE/OPC_BoxPruning.cpp new file mode 100644 index 0000000000..6906160773 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_BoxPruning.cpp @@ -0,0 +1,367 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for box pruning. + * \file IceBoxPruning.cpp + * \author Pierre Terdiman + * \date January, 29, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/* +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + You could use a complex sweep-and-prune as implemented in I-Collide. + You could use a complex hashing scheme as implemented in V-Clip or recently in ODE it seems. + You could use a "Recursive Dimensional Clustering" algorithm as implemented in GPG2. + + Or you could use this. + Faster ? I don't know. Probably not. It would be a shame. But who knows ? + Easier ? Definitely. Enjoy the sheer simplicity. +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +*/ + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + + inline_ void FindRunningIndex(udword& index, float* array, udword* sorted, int last, float max) + { + int First=index; + while(First<=last) + { + index = (First+last)>>1; + + if(max>array[sorted[index]]) First = index+1; + else last = index-1; + } + } +// ### could be log(n) ! +// and maybe use cmp integers + +// InsertionSort has better coherence, RadixSort is better for one-shot queries. +#define PRUNING_SORTER RadixSort +//#define PRUNING_SORTER InsertionSort + +// Static for coherence +static PRUNING_SORTER* gCompletePruningSorter = null; +static PRUNING_SORTER* gBipartitePruningSorter0 = null; +static PRUNING_SORTER* gBipartitePruningSorter1 = null; +inline_ PRUNING_SORTER* GetCompletePruningSorter() +{ + if(!gCompletePruningSorter) gCompletePruningSorter = new PRUNING_SORTER; + return gCompletePruningSorter; +} +inline_ PRUNING_SORTER* GetBipartitePruningSorter0() +{ + if(!gBipartitePruningSorter0) gBipartitePruningSorter0 = new PRUNING_SORTER; + return gBipartitePruningSorter0; +} +inline_ PRUNING_SORTER* GetBipartitePruningSorter1() +{ + if(!gBipartitePruningSorter1) gBipartitePruningSorter1 = new PRUNING_SORTER; + return gBipartitePruningSorter1; +} +void ReleasePruningSorters() +{ + DELETESINGLE(gBipartitePruningSorter1); + DELETESINGLE(gBipartitePruningSorter0); + DELETESINGLE(gCompletePruningSorter); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set. + * \param nb0 [in] number of boxes in the first set + * \param array0 [in] array of boxes for the first set + * \param nb1 [in] number of boxes in the second set + * \param array1 [in] array of boxes for the second set + * \param pairs [out] array of overlapping pairs + * \param axes [in] projection order (0,2,1 is often best) + * \return true if success. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool Opcode::BipartiteBoxPruning(udword nb0, const AABB** array0, udword nb1, const AABB** array1, Pairs& pairs, const Axes& axes) +{ + // Checkings + if(!nb0 || !array0 || !nb1 || !array1) return false; + + // Catch axes + udword Axis0 = axes.mAxis0; + udword Axis1 = axes.mAxis1; + udword Axis2 = axes.mAxis2; + + // Allocate some temporary data + float* MinPosList0 = new float[nb0]; + float* MinPosList1 = new float[nb1]; + + // 1) Build main lists using the primary axis + for(udword i=0;iGetMin(Axis0); + for(udword i=0;iGetMin(Axis0); + + // 2) Sort the lists + PRUNING_SORTER* RS0 = GetBipartitePruningSorter0(); + PRUNING_SORTER* RS1 = GetBipartitePruningSorter1(); + const udword* Sorted0 = RS0->Sort(MinPosList0, nb0).GetRanks(); + const udword* Sorted1 = RS1->Sort(MinPosList1, nb1).GetRanks(); + + // 3) Prune the lists + udword Index0, Index1; + + const udword* const LastSorted0 = &Sorted0[nb0]; + const udword* const LastSorted1 = &Sorted1[nb1]; + const udword* RunningAddress0 = Sorted0; + const udword* RunningAddress1 = Sorted1; + + while(RunningAddress1GetMax(Axis0)) + { + if(array0[Index0]->Intersect(*array1[Index1], Axis1)) + { + if(array0[Index0]->Intersect(*array1[Index1], Axis2)) + { + pairs.AddPair(Index0, Index1); + } + } + } + } + + //// + + while(RunningAddress0GetMax(Axis0)) + { + if(array0[Index1]->Intersect(*array1[Index0], Axis1)) + { + if(array0[Index1]->Intersect(*array1[Index0], Axis2)) + { + pairs.AddPair(Index1, Index0); + } + } + + } + } + + DELETEARRAY(MinPosList1); + DELETEARRAY(MinPosList0); + + return true; +} + +#define ORIGINAL_VERSION +//#define JOAKIM + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set. + * \param nb [in] number of boxes + * \param array [in] array of boxes + * \param pairs [out] array of overlapping pairs + * \param axes [in] projection order (0,2,1 is often best) + * \return true if success. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool Opcode::CompleteBoxPruning(udword nb, const AABB** array, Pairs& pairs, const Axes& axes) +{ + // Checkings + if(!nb || !array) return false; + + // Catch axes + udword Axis0 = axes.mAxis0; + udword Axis1 = axes.mAxis1; + udword Axis2 = axes.mAxis2; + +#ifdef ORIGINAL_VERSION + // Allocate some temporary data +// float* PosList = new float[nb]; + float* PosList = new float[nb+1]; + + // 1) Build main list using the primary axis + for(udword i=0;iGetMin(Axis0); +PosList[nb++] = MAX_FLOAT; + + // 2) Sort the list + PRUNING_SORTER* RS = GetCompletePruningSorter(); + const udword* Sorted = RS->Sort(PosList, nb).GetRanks(); + + // 3) Prune the list + const udword* const LastSorted = &Sorted[nb]; + const udword* RunningAddress = Sorted; + udword Index0, Index1; + while(RunningAddressGetMax(Axis0)) + while(PosList[Index1 = *RunningAddress2++]<=array[Index0]->GetMax(Axis0)) + { +// if(Index0!=Index1) +// { + if(array[Index0]->Intersect(*array[Index1], Axis1)) + { + if(array[Index0]->Intersect(*array[Index1], Axis2)) + { + pairs.AddPair(Index0, Index1); + } + } +// } + } + } + } + + DELETEARRAY(PosList); +#endif + +#ifdef JOAKIM + // Allocate some temporary data +// float* PosList = new float[nb]; + float* MinList = new float[nb+1]; + + // 1) Build main list using the primary axis + for(udword i=0;iGetMin(Axis0); + MinList[nb] = MAX_FLOAT; + + // 2) Sort the list + PRUNING_SORTER* RS = GetCompletePruningSorter(); + udword* Sorted = RS->Sort(MinList, nb+1).GetRanks(); + + // 3) Prune the list +// const udword* const LastSorted = &Sorted[nb]; +// const udword* const LastSorted = &Sorted[nb-1]; + const udword* RunningAddress = Sorted; + udword Index0, Index1; + +// while(RunningAddressGetMax(Axis0)) + +// float CurrentMin = array[Index0]->GetMin(Axis0); + float CurrentMax = array[Index0]->GetMax(Axis0); + + while(MinList[Index1 = *RunningAddress2] <= CurrentMax) +// while(PosList[Index1 = *RunningAddress] <= CurrentMax) + { +// if(Index0!=Index1) +// { + if(array[Index0]->Intersect(*array[Index1], Axis1)) + { + if(array[Index0]->Intersect(*array[Index1], Axis2)) + { + pairs.AddPair(Index0, Index1); + } + } +// } + + RunningAddress2++; +// RunningAddress++; + } + } + } + + DELETEARRAY(MinList); +#endif + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Brute-force versions are kept: +// - to check the optimized versions return the correct list of intersections +// - to check the speed of the optimized code against the brute-force one +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Brute-force bipartite box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to a different set. + * \param nb0 [in] number of boxes in the first set + * \param array0 [in] array of boxes for the first set + * \param nb1 [in] number of boxes in the second set + * \param array1 [in] array of boxes for the second set + * \param pairs [out] array of overlapping pairs + * \return true if success. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool Opcode::BruteForceBipartiteBoxTest(udword nb0, const AABB** array0, udword nb1, const AABB** array1, Pairs& pairs) +{ + // Checkings + if(!nb0 || !array0 || !nb1 || !array1) return false; + + // Brute-force nb0*nb1 overlap tests + for(udword i=0;iIntersect(*array1[j])) pairs.AddPair(i, j); + } + } + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Complete box pruning. Returns a list of overlapping pairs of boxes, each box of the pair belongs to the same set. + * \param nb [in] number of boxes + * \param array [in] array of boxes + * \param pairs [out] array of overlapping pairs + * \return true if success. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool Opcode::BruteForceCompleteBoxTest(udword nb, const AABB** array, Pairs& pairs) +{ + // Checkings + if(!nb || !array) return false; + + // Brute-force n(n-1)/2 overlap tests + for(udword i=0;iIntersect(*array[j])) pairs.AddPair(i, j); + } + } + return true; +} diff --git a/libraries/ode-0.9/OPCODE/OPC_BoxPruning.h b/libraries/ode-0.9/OPCODE/OPC_BoxPruning.h new file mode 100644 index 0000000000..2f77cd2dad --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_BoxPruning.h @@ -0,0 +1,31 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for box pruning. + * \file IceBoxPruning.h + * \author Pierre Terdiman + * \date January, 29, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_BOXPRUNING_H__ +#define __OPC_BOXPRUNING_H__ + + // Optimized versions + FUNCTION OPCODE_API bool CompleteBoxPruning(udword nb, const AABB** array, Pairs& pairs, const Axes& axes); + FUNCTION OPCODE_API bool BipartiteBoxPruning(udword nb0, const AABB** array0, udword nb1, const AABB** array1, Pairs& pairs, const Axes& axes); + + // Brute-force versions + FUNCTION OPCODE_API bool BruteForceCompleteBoxTest(udword nb, const AABB** array, Pairs& pairs); + FUNCTION OPCODE_API bool BruteForceBipartiteBoxTest(udword nb0, const AABB** array0, udword nb1, const AABB** array1, Pairs& pairs); + +#endif //__OPC_BOXPRUNING_H__ diff --git a/libraries/ode-0.9/OPCODE/OPC_Collider.cpp b/libraries/ode-0.9/OPCODE/OPC_Collider.cpp new file mode 100644 index 0000000000..f41fc362c9 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_Collider.cpp @@ -0,0 +1,54 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains base collider class. + * \file OPC_Collider.cpp + * \author Pierre Terdiman + * \date June, 2, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains the abstract class for colliders. + * + * \class Collider + * \author Pierre Terdiman + * \version 1.3 + * \date June, 2, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Collider::Collider() : + mFlags (0), + mCurrentModel (null), + mIMesh (null) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Collider::~Collider() +{ +} diff --git a/libraries/ode-0.9/OPCODE/OPC_Collider.h b/libraries/ode-0.9/OPCODE/OPC_Collider.h new file mode 100644 index 0000000000..d718e0298f --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_Collider.h @@ -0,0 +1,176 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains base collider class. + * \file OPC_Collider.h + * \author Pierre Terdiman + * \date June, 2, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_COLLIDER_H__ +#define __OPC_COLLIDER_H__ + + enum CollisionFlag + { + OPC_FIRST_CONTACT = (1<<0), //!< Report all contacts (false) or only first one (true) + OPC_TEMPORAL_COHERENCE = (1<<1), //!< Use temporal coherence or not + OPC_CONTACT = (1<<2), //!< Final contact status after a collision query + OPC_TEMPORAL_HIT = (1<<3), //!< There has been an early exit due to temporal coherence + OPC_NO_PRIMITIVE_TESTS = (1<<4), //!< Keep or discard primitive-bv tests in leaf nodes (volume-mesh queries) + + OPC_CONTACT_FOUND = OPC_FIRST_CONTACT | OPC_CONTACT, + OPC_TEMPORAL_CONTACT = OPC_TEMPORAL_HIT | OPC_CONTACT, + + OPC_FORCE_DWORD = 0x7fffffff + }; + + class OPCODE_API Collider + { + public: + // Constructor / Destructor + Collider(); + virtual ~Collider(); + + // Collision report + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the last collision status after a collision query. + * \return true if a collision occured + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL GetContactStatus() const { return mFlags & OPC_CONTACT; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the "first contact" mode. + * \return true if "first contact" mode is on + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL FirstContactEnabled() const { return mFlags & OPC_FIRST_CONTACT; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the temporal coherence mode. + * \return true if temporal coherence is on + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL TemporalCoherenceEnabled() const { return mFlags & OPC_TEMPORAL_COHERENCE; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks a first contact has already been found. + * \return true if a first contact has been found and we can stop a query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL ContactFound() const { return (mFlags&OPC_CONTACT_FOUND)==OPC_CONTACT_FOUND; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks there's been an early exit due to temporal coherence; + * \return true if a temporal hit has occured + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL TemporalHit() const { return mFlags & OPC_TEMPORAL_HIT; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks primitive tests are enabled; + * \return true if primitive tests must be skipped + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL SkipPrimitiveTests() const { return mFlags & OPC_NO_PRIMITIVE_TESTS; } + + // Settings + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Reports all contacts (false) or first contact only (true) + * \param flag [in] true for first contact, false for all contacts + * \see SetTemporalCoherence(bool flag) + * \see ValidateSettings() + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetFirstContact(bool flag) + { + if(flag) mFlags |= OPC_FIRST_CONTACT; + else mFlags &= ~OPC_FIRST_CONTACT; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Enable/disable temporal coherence. + * \param flag [in] true to enable temporal coherence, false to discard it + * \see SetFirstContact(bool flag) + * \see ValidateSettings() + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetTemporalCoherence(bool flag) + { + if(flag) mFlags |= OPC_TEMPORAL_COHERENCE; + else mFlags &= ~OPC_TEMPORAL_COHERENCE; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Enable/disable primitive tests. + * \param flag [in] true to enable primitive tests, false to discard them + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetPrimitiveTests(bool flag) + { + if(!flag) mFlags |= OPC_NO_PRIMITIVE_TESTS; + else mFlags &= ~OPC_NO_PRIMITIVE_TESTS; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Validates current settings. You should call this method after all the settings / callbacks have been defined for a collider. + * \return null if everything is ok, else a string describing the problem + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual const char* ValidateSettings() = 0; + + protected: + udword mFlags; //!< Bit flags + const BaseModel* mCurrentModel; //!< Current model for collision query (owner of touched faces) + // User mesh interface + const MeshInterface* mIMesh; //!< User-defined mesh interface + + // Internal methods + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups current collision model + * \param model [in] current collision model + * \return TRUE if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL Setup(const BaseModel* model) + { + // Keep track of current model + mCurrentModel = model; + if(!mCurrentModel) return FALSE; + + mIMesh = model->GetMeshInterface(); + return mIMesh!=null; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Initializes a query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual inline_ void InitQuery() { mFlags &= ~OPC_TEMPORAL_CONTACT; } + }; + +#endif // __OPC_COLLIDER_H__ diff --git a/libraries/ode-0.9/OPCODE/OPC_Common.cpp b/libraries/ode-0.9/OPCODE/OPC_Common.cpp new file mode 100644 index 0000000000..5b9a9c8021 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_Common.cpp @@ -0,0 +1,48 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains common classes & defs used in OPCODE. + * \file OPC_Common.cpp + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * An AABB dedicated to collision detection. + * We don't use the generic AABB class included in ICE, since it can be a Min/Max or a Center/Extents one (depends + * on compilation flags). Since the Center/Extents model is more efficient in collision detection, it was worth + * using an extra special class. + * + * \class CollisionAABB + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * A quantized AABB. + * Center/Extent model, using 16-bits integers. + * + * \class QuantizedAABB + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; diff --git a/libraries/ode-0.9/OPCODE/OPC_Common.h b/libraries/ode-0.9/OPCODE/OPC_Common.h new file mode 100644 index 0000000000..f13499030e --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_Common.h @@ -0,0 +1,101 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains common classes & defs used in OPCODE. + * \file OPC_Common.h + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_COMMON_H__ +#define __OPC_COMMON_H__ + +// [GOTTFRIED]: Just a small change for readability. +#ifdef OPC_CPU_COMPARE + #define GREATER(x, y) AIR(x) > IR(y) +#else + #define GREATER(x, y) fabsf(x) > (y) +#endif + + class OPCODE_API CollisionAABB + { + public: + //! Constructor + inline_ CollisionAABB() {} + //! Constructor + inline_ CollisionAABB(const AABB& b) { b.GetCenter(mCenter); b.GetExtents(mExtents); } + //! Destructor + inline_ ~CollisionAABB() {} + + //! Get min point of the box + inline_ void GetMin(Point& min) const { min = mCenter - mExtents; } + //! Get max point of the box + inline_ void GetMax(Point& max) const { max = mCenter + mExtents; } + + //! Get component of the box's min point along a given axis + inline_ float GetMin(udword axis) const { return mCenter[axis] - mExtents[axis]; } + //! Get component of the box's max point along a given axis + inline_ float GetMax(udword axis) const { return mCenter[axis] + mExtents[axis]; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Setups an AABB from min & max vectors. + * \param min [in] the min point + * \param max [in] the max point + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetMinMax(const Point& min, const Point& max) { mCenter = (max + min)*0.5f; mExtents = (max - min)*0.5f; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Checks a box is inside another box. + * \param box [in] the other box + * \return true if current box is inside input box + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ BOOL IsInside(const CollisionAABB& box) const + { + if(box.GetMin(0)>GetMin(0)) return FALSE; + if(box.GetMin(1)>GetMin(1)) return FALSE; + if(box.GetMin(2)>GetMin(2)) return FALSE; + if(box.GetMax(0)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; + 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++); + 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++); + 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++); + 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++); + ComputeMinMax(TmpMin, TmpMax, VP); + Min_.Min(TmpMin); + Max_.Max(TmpMax); + } + } + } + else + { + const CollisionAABB& CurrentBox = Current.GetNeg()->mAABB; + CurrentBox.GetMin(Min_); + CurrentBox.GetMax(Max_); + } +#ifdef OPC_USE_FCOMI + Min.x = FCMin2(Min.x, Min_.x); + Max.x = FCMax2(Max.x, Max_.x); + Min.y = FCMin2(Min.y, Min_.y); + Max.y = FCMax2(Max.y, Max_.y); + Min.z = FCMin2(Min.z, Min_.z); + Max.z = FCMax2(Max.z, Max_.z); +#else + Min.Min(Min_); + Max.Max(Max_); +#endif + Current.mAABB.SetMinMax(Min, Max); + } + return true; +} diff --git a/libraries/ode-0.9/OPCODE/OPC_HybridModel.h b/libraries/ode-0.9/OPCODE/OPC_HybridModel.h new file mode 100644 index 0000000000..c7eb59d4a0 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_HybridModel.h @@ -0,0 +1,106 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for hybrid models. + * \file OPC_HybridModel.h + * \author Pierre Terdiman + * \date May, 18, 2003 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_HYBRIDMODEL_H__ +#define __OPC_HYBRIDMODEL_H__ + + //! Leaf descriptor + struct LeafTriangles + { + udword Data; //!< Packed data + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets number of triangles in the leaf. + * \return number of triangles N, with 0 < N <= 16 + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbTriangles() const { return (Data & 15)+1; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets triangle index for this leaf. Indexed model's array of indices retrieved with HybridModel::GetIndices() + * \return triangle index + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetTriangleIndex() const { return Data>>4; } + inline_ void SetData(udword nb, udword index) { ASSERT(nb>0 && nb<=16); nb--; Data = (index<<4)|(nb&15); } + }; + + class OPCODE_API HybridModel : public BaseModel + { + public: + // Constructor/Destructor + HybridModel(); + virtual ~HybridModel(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Builds a collision model. + * \param create [in] model creation structure + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(BaseModel) bool Build(const OPCODECREATE& create); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the number of bytes used by the tree. + * \return amount of bytes used + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(BaseModel) udword GetUsedBytes() const; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Refits the collision model. This can be used to handle dynamic meshes. Usage is: + * 1. modify your mesh vertices (keep the topology constant!) + * 2. refit the tree (call this method) + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(BaseModel) bool Refit(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets array of triangles. + * \return array of triangles + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ const LeafTriangles* GetLeafTriangles() const { return mTriangles; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets array of indices. + * \return array of indices + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ const udword* GetIndices() const { return mIndices; } + + private: + udword mNbLeaves; //!< Number of leaf nodes in the model + LeafTriangles* mTriangles; //!< Array of mNbLeaves leaf descriptors + udword mNbPrimitives; //!< Number of primitives in the model + udword* mIndices; //!< Array of primitive indices + + // Internal methods + void Release(); + }; + +#endif // __OPC_HYBRIDMODEL_H__ diff --git a/libraries/ode-0.9/OPCODE/OPC_IceHook.h b/libraries/ode-0.9/OPCODE/OPC_IceHook.h new file mode 100644 index 0000000000..62343b8fe2 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_IceHook.h @@ -0,0 +1,70 @@ + +// 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; diff --git a/libraries/ode-0.9/OPCODE/OPC_LSSAABBOverlap.h b/libraries/ode-0.9/OPCODE/OPC_LSSAABBOverlap.h new file mode 100644 index 0000000000..5cc50b58da --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_LSSAABBOverlap.h @@ -0,0 +1,523 @@ + +// 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(s2Add(udword(prim_index)); + +//! LSS-triangle overlap test +#define LSS_PRIM(prim_index, flag) \ + /* Request vertices from the app */ \ + VertexPointers VP; mIMesh->GetTriangle(VP, prim_index); \ + \ + /* 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; +} diff --git a/libraries/ode-0.9/OPCODE/OPC_LSSCollider.h b/libraries/ode-0.9/OPCODE/OPC_LSSCollider.h new file mode 100644 index 0000000000..b4d0893edf --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_LSSCollider.h @@ -0,0 +1,99 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for an LSS collider. + * \file OPC_LSSCollider.h + * \author Pierre Terdiman + * \date December, 28, 2002 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_LSSCOLLIDER_H__ +#define __OPC_LSSCOLLIDER_H__ + + struct OPCODE_API LSSCache : VolumeCache + { + LSSCache() + { + Previous.mP0 = Point(0.0f, 0.0f, 0.0f); + Previous.mP1 = Point(0.0f, 0.0f, 0.0f); + Previous.mRadius = 0.0f; + FatCoeff = 1.1f; + } + + // Cached faces signature + LSS Previous; //!< LSS used when performing the query resulting in cached faces + // User settings + float FatCoeff; //!< mRadius2 multiplier used to create a fat LSS + }; + + class OPCODE_API LSSCollider : public VolumeCollider + { + public: + // Constructor / Destructor + LSSCollider(); + virtual ~LSSCollider(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Generic collision query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - with GetNbTouchedPrimitives() + * - with GetTouchedPrimitives() + * + * \param cache [in/out] an lss cache + * \param lss [in] collision lss in local space + * \param model [in] Opcode model to collide with + * \param worldl [in] lss world matrix, or null + * \param worldm [in] model's world matrix, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool Collide(LSSCache& cache, const LSS& lss, const Model& model, const Matrix4x4* worldl=null, const Matrix4x4* worldm=null); + // + bool Collide(LSSCache& cache, const LSS& lss, const AABBTree* tree); + protected: + // LSS in model space + Segment mSeg; //!< Segment + float mRadius2; //!< LSS radius squared + // Internal methods + void _Collide(const AABBCollisionNode* node); + void _Collide(const AABBNoLeafNode* node); + void _Collide(const AABBQuantizedNode* node); + void _Collide(const AABBQuantizedNoLeafNode* node); + void _Collide(const AABBTreeNode* node); + void _CollideNoPrimitiveTest(const AABBCollisionNode* node); + void _CollideNoPrimitiveTest(const AABBNoLeafNode* node); + void _CollideNoPrimitiveTest(const AABBQuantizedNode* node); + void _CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node); + // Overlap tests + inline_ BOOL LSSContainsBox(const Point& bc, const Point& be); + inline_ BOOL LSSAABBOverlap(const Point& center, const Point& extents); + inline_ BOOL LSSTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2); + // Init methods + BOOL InitQuery(LSSCache& cache, const LSS& lss, const Matrix4x4* worldl=null, const Matrix4x4* worldm=null); + }; + + class OPCODE_API HybridLSSCollider : public LSSCollider + { + public: + // Constructor / Destructor + HybridLSSCollider(); + virtual ~HybridLSSCollider(); + + bool Collide(LSSCache& cache, const LSS& lss, const HybridModel& model, const Matrix4x4* worldl=null, const Matrix4x4* worldm=null); + protected: + Container mTouchedBoxes; + }; + +#endif // __OPC_LSSCOLLIDER_H__ diff --git a/libraries/ode-0.9/OPCODE/OPC_LSSTriOverlap.h b/libraries/ode-0.9/OPCODE/OPC_LSSTriOverlap.h new file mode 100644 index 0000000000..f1d17e4ae5 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_LSSTriOverlap.h @@ -0,0 +1,679 @@ +// Following code from Magic-Software (http://www.magic-software.com/) +// A bit modified for Opcode + +static const float gs_fTolerance = 1e-05f; + +static float OPC_PointTriangleSqrDist(const Point& point, const Point& p0, const Point& p1, const Point& p2) +{ + // Hook + Point TriEdge0 = p1 - p0; + Point TriEdge1 = p2 - p0; + + Point kDiff = p0 - point; + float fA00 = TriEdge0.SquareMagnitude(); + float fA01 = TriEdge0 | TriEdge1; + float fA11 = TriEdge1.SquareMagnitude(); + float fB0 = kDiff | TriEdge0; + float fB1 = kDiff | TriEdge1; + float fC = kDiff.SquareMagnitude(); + float fDet = fabsf(fA00*fA11 - fA01*fA01); + float fS = fA01*fB1-fA11*fB0; + float fT = fA01*fB0-fA00*fB1; + float fSqrDist; + + if(fS + fT <= fDet) + { + if(fS < 0.0f) + { + if(fT < 0.0f) // region 4 + { + if(fB0 < 0.0f) + { + if(-fB0 >= fA00) fSqrDist = fA00+2.0f*fB0+fC; + else fSqrDist = fB0*(-fB0/fA00)+fC; + } + else + { + if(fB1 >= 0.0f) fSqrDist = fC; + else if(-fB1 >= fA11) fSqrDist = fA11+2.0f*fB1+fC; + else fSqrDist = fB1*(-fB1/fA11)+fC; + } + } + else // region 3 + { + if(fB1 >= 0.0f) fSqrDist = fC; + else if(-fB1 >= fA11) fSqrDist = fA11+2.0f*fB1+fC; + else fSqrDist = fB1*(-fB1/fA11)+fC; + } + } + else if(fT < 0.0f) // region 5 + { + if(fB0 >= 0.0f) fSqrDist = fC; + else if(-fB0 >= fA00) fSqrDist = fA00+2.0f*fB0+fC; + else fSqrDist = fB0*(-fB0/fA00)+fC; + } + else // region 0 + { + // minimum at interior point + if(fDet==0.0f) + { + fSqrDist = MAX_FLOAT; + } + else + { + float fInvDet = 1.0f/fDet; + fS *= fInvDet; + fT *= fInvDet; + fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; + } + } + } + else + { + float fTmp0, fTmp1, fNumer, fDenom; + + if(fS < 0.0f) // region 2 + { + fTmp0 = fA01 + fB0; + fTmp1 = fA11 + fB1; + if(fTmp1 > fTmp0) + { + fNumer = fTmp1 - fTmp0; + fDenom = fA00-2.0f*fA01+fA11; + if(fNumer >= fDenom) + { + fSqrDist = fA00+2.0f*fB0+fC; + } + else + { + fS = fNumer/fDenom; + fT = 1.0f - fS; + fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; + } + } + else + { + if(fTmp1 <= 0.0f) fSqrDist = fA11+2.0f*fB1+fC; + else if(fB1 >= 0.0f) fSqrDist = fC; + else fSqrDist = fB1*(-fB1/fA11)+fC; + } + } + else if(fT < 0.0f) // region 6 + { + fTmp0 = fA01 + fB1; + fTmp1 = fA00 + fB0; + if(fTmp1 > fTmp0) + { + fNumer = fTmp1 - fTmp0; + fDenom = fA00-2.0f*fA01+fA11; + if(fNumer >= fDenom) + { + fSqrDist = fA11+2.0f*fB1+fC; + } + else + { + fT = fNumer/fDenom; + fS = 1.0f - fT; + fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; + } + } + else + { + if(fTmp1 <= 0.0f) fSqrDist = fA00+2.0f*fB0+fC; + else if(fB0 >= 0.0f) fSqrDist = fC; + else fSqrDist = fB0*(-fB0/fA00)+fC; + } + } + else // region 1 + { + fNumer = fA11 + fB1 - fA01 - fB0; + if(fNumer <= 0.0f) + { + fSqrDist = fA11+2.0f*fB1+fC; + } + else + { + fDenom = fA00-2.0f*fA01+fA11; + if(fNumer >= fDenom) + { + fSqrDist = fA00+2.0f*fB0+fC; + } + else + { + fS = fNumer/fDenom; + fT = 1.0f - fS; + fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; + } + } + } + } + return fabsf(fSqrDist); +} + +static float OPC_SegmentSegmentSqrDist(const Segment& rkSeg0, const Segment& rkSeg1) +{ + // Hook + Point rkSeg0Direction = rkSeg0.ComputeDirection(); + Point rkSeg1Direction = rkSeg1.ComputeDirection(); + + Point kDiff = rkSeg0.mP0 - rkSeg1.mP0; + float fA00 = rkSeg0Direction.SquareMagnitude(); + float fA01 = -rkSeg0Direction.Dot(rkSeg1Direction); + float fA11 = rkSeg1Direction.SquareMagnitude(); + float fB0 = kDiff.Dot(rkSeg0Direction); + float fC = kDiff.SquareMagnitude(); + float fDet = fabsf(fA00*fA11-fA01*fA01); + + float fB1, fS, fT, fSqrDist, fTmp; + + if(fDet>=gs_fTolerance) + { + // line segments are not parallel + fB1 = -kDiff.Dot(rkSeg1Direction); + fS = fA01*fB1-fA11*fB0; + fT = fA01*fB0-fA00*fB1; + + if(fS >= 0.0f) + { + if(fS <= fDet) + { + if(fT >= 0.0f) + { + if(fT <= fDet) // region 0 (interior) + { + // minimum at two interior points of 3D lines + float fInvDet = 1.0f/fDet; + fS *= fInvDet; + fT *= fInvDet; + fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; + } + else // region 3 (side) + { + fTmp = fA01+fB0; + if(fTmp>=0.0f) fSqrDist = fA11+2.0f*fB1+fC; + else if(-fTmp>=fA00) fSqrDist = fA00+fA11+fC+2.0f*(fB1+fTmp); + else fSqrDist = fTmp*(-fTmp/fA00)+fA11+2.0f*fB1+fC; + } + } + else // region 7 (side) + { + if(fB0>=0.0f) fSqrDist = fC; + else if(-fB0>=fA00) fSqrDist = fA00+2.0f*fB0+fC; + else fSqrDist = fB0*(-fB0/fA00)+fC; + } + } + else + { + if ( fT >= 0.0 ) + { + if ( fT <= fDet ) // region 1 (side) + { + fTmp = fA01+fB1; + if(fTmp>=0.0f) fSqrDist = fA00+2.0f*fB0+fC; + else if(-fTmp>=fA11) fSqrDist = fA00+fA11+fC+2.0f*(fB0+fTmp); + else fSqrDist = fTmp*(-fTmp/fA11)+fA00+2.0f*fB0+fC; + } + else // region 2 (corner) + { + fTmp = fA01+fB0; + if ( -fTmp <= fA00 ) + { + if(fTmp>=0.0f) fSqrDist = fA11+2.0f*fB1+fC; + else fSqrDist = fTmp*(-fTmp/fA00)+fA11+2.0f*fB1+fC; + } + else + { + fTmp = fA01+fB1; + if(fTmp>=0.0f) fSqrDist = fA00+2.0f*fB0+fC; + else if(-fTmp>=fA11) fSqrDist = fA00+fA11+fC+2.0f*(fB0+fTmp); + else fSqrDist = fTmp*(-fTmp/fA11)+fA00+2.0f*fB0+fC; + } + } + } + else // region 8 (corner) + { + if ( -fB0 < fA00 ) + { + if(fB0>=0.0f) fSqrDist = fC; + else fSqrDist = fB0*(-fB0/fA00)+fC; + } + else + { + fTmp = fA01+fB1; + if(fTmp>=0.0f) fSqrDist = fA00+2.0f*fB0+fC; + else if(-fTmp>=fA11) fSqrDist = fA00+fA11+fC+2.0f*(fB0+fTmp); + else fSqrDist = fTmp*(-fTmp/fA11)+fA00+2.0f*fB0+fC; + } + } + } + } + else + { + if ( fT >= 0.0f ) + { + if ( fT <= fDet ) // region 5 (side) + { + if(fB1>=0.0f) fSqrDist = fC; + else if(-fB1>=fA11) fSqrDist = fA11+2.0f*fB1+fC; + else fSqrDist = fB1*(-fB1/fA11)+fC; + } + else // region 4 (corner) + { + fTmp = fA01+fB0; + if ( fTmp < 0.0f ) + { + if(-fTmp>=fA00) fSqrDist = fA00+fA11+fC+2.0f*(fB1+fTmp); + else fSqrDist = fTmp*(-fTmp/fA00)+fA11+2.0f*fB1+fC; + } + else + { + if(fB1>=0.0f) fSqrDist = fC; + else if(-fB1>=fA11) fSqrDist = fA11+2.0f*fB1+fC; + else fSqrDist = fB1*(-fB1/fA11)+fC; + } + } + } + else // region 6 (corner) + { + if ( fB0 < 0.0f ) + { + if(-fB0>=fA00) fSqrDist = fA00+2.0f*fB0+fC; + else fSqrDist = fB0*(-fB0/fA00)+fC; + } + else + { + if(fB1>=0.0f) fSqrDist = fC; + else if(-fB1>=fA11) fSqrDist = fA11+2.0f*fB1+fC; + else fSqrDist = fB1*(-fB1/fA11)+fC; + } + } + } + } + else + { + // line segments are parallel + if ( fA01 > 0.0f ) + { + // direction vectors form an obtuse angle + if ( fB0 >= 0.0f ) + { + fSqrDist = fC; + } + else if ( -fB0 <= fA00 ) + { + fSqrDist = fB0*(-fB0/fA00)+fC; + } + else + { + fB1 = -kDiff.Dot(rkSeg1Direction); + fTmp = fA00+fB0; + if ( -fTmp >= fA01 ) + { + fSqrDist = fA00+fA11+fC+2.0f*(fA01+fB0+fB1); + } + else + { + fT = -fTmp/fA01; + fSqrDist = fA00+2.0f*fB0+fC+fT*(fA11*fT+2.0f*(fA01+fB1)); + } + } + } + else + { + // direction vectors form an acute angle + if ( -fB0 >= fA00 ) + { + fSqrDist = fA00+2.0f*fB0+fC; + } + else if ( fB0 <= 0.0f ) + { + fSqrDist = fB0*(-fB0/fA00)+fC; + } + else + { + fB1 = -kDiff.Dot(rkSeg1Direction); + if ( fB0 >= -fA01 ) + { + fSqrDist = fA11+2.0f*fB1+fC; + } + else + { + fT = -fB0/fA01; + fSqrDist = fC+fT*(2.0f*fB1+fA11*fT); + } + } + } + } + return fabsf(fSqrDist); +} + +inline_ float OPC_SegmentRaySqrDist(const Segment& rkSeg0, const Ray& rkSeg1) +{ + return OPC_SegmentSegmentSqrDist(rkSeg0, Segment(rkSeg1.mOrig, rkSeg1.mOrig + rkSeg1.mDir)); +} + +static float OPC_SegmentTriangleSqrDist(const Segment& segment, const Point& p0, const Point& p1, const Point& p2) +{ + // Hook + const Point TriEdge0 = p1 - p0; + const Point TriEdge1 = p2 - p0; + + const Point& rkSegOrigin = segment.GetOrigin(); + Point rkSegDirection = segment.ComputeDirection(); + + Point kDiff = p0 - rkSegOrigin; + float fA00 = rkSegDirection.SquareMagnitude(); + float fA01 = -rkSegDirection.Dot(TriEdge0); + float fA02 = -rkSegDirection.Dot(TriEdge1); + float fA11 = TriEdge0.SquareMagnitude(); + float fA12 = TriEdge0.Dot(TriEdge1); + float fA22 = TriEdge1.Dot(TriEdge1); + float fB0 = -kDiff.Dot(rkSegDirection); + float fB1 = kDiff.Dot(TriEdge0); + float fB2 = kDiff.Dot(TriEdge1); + float fCof00 = fA11*fA22-fA12*fA12; + float fCof01 = fA02*fA12-fA01*fA22; + float fCof02 = fA01*fA12-fA02*fA11; + float fDet = fA00*fCof00+fA01*fCof01+fA02*fCof02; + + Ray kTriSeg; + Point kPt; + float fSqrDist, fSqrDist0; + + if(fabsf(fDet)>=gs_fTolerance) + { + float fCof11 = fA00*fA22-fA02*fA02; + float fCof12 = fA02*fA01-fA00*fA12; + float fCof22 = fA00*fA11-fA01*fA01; + float fInvDet = 1.0f/fDet; + float fRhs0 = -fB0*fInvDet; + float fRhs1 = -fB1*fInvDet; + float fRhs2 = -fB2*fInvDet; + + float fR = fCof00*fRhs0+fCof01*fRhs1+fCof02*fRhs2; + float fS = fCof01*fRhs0+fCof11*fRhs1+fCof12*fRhs2; + float fT = fCof02*fRhs0+fCof12*fRhs1+fCof22*fRhs2; + + if ( fR < 0.0f ) + { + if ( fS+fT <= 1.0f ) + { + if ( fS < 0.0f ) + { + if ( fT < 0.0f ) // region 4m + { + // min on face s=0 or t=0 or r=0 + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge1; + fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); + kTriSeg.mOrig = p0; + kTriSeg.mDir = TriEdge0; + fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); + if(fSqrDist0 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(fSqrDist0GetTriangle(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; + +Point MeshInterface::VertexCache[3]; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +MeshInterface::MeshInterface() : +#ifdef OPC_USE_CALLBACKS + mUserData (null), + mObjCallback (null), +#else + mTris (null), + mVerts (null), + #ifdef OPC_USE_STRIDE + mTriStride (sizeof(IndexedTriangle)), + mVertexStride (sizeof(Point)), + #endif +#endif + mNbTris (0), + mNbVerts (0), + + Single(true) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * 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; + + // Using callbacks, we don't have access to vertex indices. Nevertheless we still can check for + // redundant vertex pointers, which cover all possibilities (callbacks/pointers/strides). + for(udword i=0;i= 0.0f; + } + }; + +#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; } + #endif +#endif + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Fetches a triangle given a triangle index. + * \param vp [out] required triangle's vertex pointers + * \param index [in] triangle index + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void GetTriangle(VertexPointers& vp, udword index) const + { +#ifdef OPC_USE_CALLBACKS + (mObjCallback)(index, vp, mUserData); +#else + #ifdef OPC_USE_STRIDE + const IndexedTriangle* T = (const IndexedTriangle*)(((ubyte*)mTris) + index * mTriStride); + + if (Single){ + vp.Vertex[0] = (const Point*)(((ubyte*)mVerts) + T->mVRef[0] * mVertexStride); + vp.Vertex[1] = (const Point*)(((ubyte*)mVerts) + T->mVRef[1] * mVertexStride); + vp.Vertex[2] = (const Point*)(((ubyte*)mVerts) + T->mVRef[2] * mVertexStride); + } + else{ + for (int i = 0; i < 3; i++){ + const double* v = (const double*)(((ubyte*)mVerts) + T->mVRef[i] * mVertexStride); + + VertexCache[i].x = (float)v[0]; + VertexCache[i].y = (float)v[1]; + VertexCache[i].z = (float)v[2]; + vp.Vertex[i] = &VertexCache[i]; + } + } + #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 + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * 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 udword* 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 + const IndexedTriangle* mTris; //!< Array of indexed triangles + const Point* mVerts; //!< Array of vertices + #ifdef OPC_USE_STRIDE + udword mTriStride; //!< Possible triangle stride in bytes [Opcode 1.3] + udword mVertexStride; //!< Possible vertex stride in bytes [Opcode 1.3] + #endif + public: + bool Single; //!< Use single or double precision vertices + private: + static Point VertexCache[3]; +#endif + }; + +#endif //__OPC_MESHINTERFACE_H__ diff --git a/libraries/ode-0.9/OPCODE/OPC_Model.cpp b/libraries/ode-0.9/OPCODE/OPC_Model.cpp new file mode 100644 index 0000000000..8b71fb18e2 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_Model.cpp @@ -0,0 +1,222 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for OPCODE models. + * \file OPC_Model.cpp + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * The main collision wrapper, for all trees. Supported trees are: + * - Normal trees (2*N-1 nodes, full size) + * - No-leaf trees (N-1 nodes, full size) + * - Quantized trees (2*N-1 nodes, half size) + * - Quantized no-leaf trees (N-1 nodes, half size) + * + * Usage: + * + * 1) Create a static mesh interface using callbacks or pointers. (see OPC_MeshInterface.cpp). + * Keep it around in your app, since a pointer to this interface is saved internally and + * used until you release the collision structures. + * + * 2) Build a Model using a creation structure: + * + * \code + * Model Sample; + * + * OPCODECREATE OPCC; + * OPCC.IMesh = ...; + * OPCC.Rules = ...; + * OPCC.NoLeaf = ...; + * OPCC.Quantized = ...; + * OPCC.KeepOriginal = ...; + * bool Status = Sample.Build(OPCC); + * \endcode + * + * 3) Create a tree collider and set it up: + * + * \code + * AABBTreeCollider TC; + * TC.SetFirstContact(...); + * TC.SetFullBoxBoxTest(...); + * TC.SetFullPrimBoxTest(...); + * TC.SetTemporalCoherence(...); + * \endcode + * + * 4) Perform a collision query + * + * \code + * // Setup cache + * static BVTCache ColCache; + * ColCache.Model0 = &Model0; + * ColCache.Model1 = &Model1; + * + * // Collision query + * bool IsOk = TC.Collide(ColCache, World0, World1); + * + * // Get collision status => if true, objects overlap + * BOOL Status = TC.GetContactStatus(); + * + * // Number of colliding pairs and list of pairs + * udword NbPairs = TC.GetNbPairs(); + * const Pair* p = TC.GetPairs() + * \endcode + * + * 5) Stats + * + * \code + * Model0.GetUsedBytes() = number of bytes used for this collision tree + * TC.GetNbBVBVTests() = number of BV-BV overlap tests performed during last query + * TC.GetNbPrimPrimTests() = number of Triangle-Triangle overlap tests performed during last query + * TC.GetNbBVPrimTests() = number of Triangle-BV overlap tests performed during last query + * \endcode + * + * \class Model + * \author Pierre Terdiman + * \version 1.3 + * \date March, 20, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Model::Model() +{ +#ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE ! + mHull = null; +#endif // __MESHMERIZER_H__ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +Model::~Model() +{ + Release(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Releases the model. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void Model::Release() +{ + ReleaseBase(); +#ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE ! + DELETESINGLE(mHull); +#endif // __MESHMERIZER_H__ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Builds a collision model. + * \param create [in] model creation structure + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool Model::Build(const OPCODECREATE& create) +{ + // 1) Checkings + if(!create.mIMesh || !create.mIMesh->IsValid()) return false; + + // For this model, we only support complete trees + if(create.mSettings.mLimit!=1) return SetIceError("OPCODE WARNING: supports complete trees only! Use mLimit = 1.\n", null); + + // Look for degenerate faces. + udword NbDegenerate = create.mIMesh->CheckTopology(); + if(NbDegenerate) Log("OPCODE WARNING: found %d degenerate faces in model! Collision might report wrong results!\n", NbDegenerate); + // We continue nonetheless.... + + Release(); // Make sure previous tree has been discarded [Opcode 1.3, thanks Adam] + + // 1-1) Setup mesh interface automatically [Opcode 1.3] + SetMeshInterface(create.mIMesh); + + // Special case for 1-triangle meshes [Opcode 1.3] + udword NbTris = create.mIMesh->GetNbTriangles(); + if(NbTris==1) + { + // We don't need to actually create a tree here, since we'll only have a single triangle to deal with anyway. + // It's a waste to use a "model" for this but at least it will work. + mModelCode |= OPC_SINGLE_NODE; + return true; + } + + // 2) Build a generic AABB Tree. + mSource = new AABBTree; + CHECKALLOC(mSource); + + // 2-1) Setup a builder. Our primitives here are triangles from input mesh, + // so we use an AABBTreeOfTrianglesBuilder..... + { + AABBTreeOfTrianglesBuilder TB; + TB.mIMesh = create.mIMesh; + TB.mSettings = create.mSettings; + TB.mNbPrimitives = NbTris; + if(!mSource->Build(&TB)) return false; + } + + // 3) Create an optimized tree according to user-settings + if(!CreateTree(create.mNoLeaf, create.mQuantized)) return false; + + // 3-2) Create optimized tree + if(!mTree->Build(mSource)) return false; + + // 3-3) Delete generic tree if needed + if(!create.mKeepOriginal) DELETESINGLE(mSource); + +#ifdef __MESHMERIZER_H__ + // 4) Convex hull + if(create.mCollisionHull) + { + // Create hull + mHull = new CollisionHull; + CHECKALLOC(mHull); + + CONVEXHULLCREATE CHC; + // ### doesn't work with strides + CHC.NbVerts = create.mIMesh->GetNbVertices(); + CHC.Vertices = create.mIMesh->GetVerts(); + CHC.UnifyNormals = true; + CHC.ReduceVertices = true; + CHC.WordFaces = false; + mHull->Compute(CHC); + } +#endif // __MESHMERIZER_H__ + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Gets the number of bytes used by the tree. + * \return amount of bytes used + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +udword Model::GetUsedBytes() const +{ + if(!mTree) return 0; + return mTree->GetUsedBytes(); +} diff --git a/libraries/ode-0.9/OPCODE/OPC_Model.h b/libraries/ode-0.9/OPCODE/OPC_Model.h new file mode 100644 index 0000000000..98dee560c3 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_Model.h @@ -0,0 +1,65 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for OPCODE models. + * \file OPC_Model.h + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_MODEL_H__ +#define __OPC_MODEL_H__ + + class OPCODE_API Model : public BaseModel + { + public: + // Constructor/Destructor + Model(); + virtual ~Model(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Builds a collision model. + * \param create [in] model creation structure + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(BaseModel) bool Build(const OPCODECREATE& create); + +#ifdef __MESHMERIZER_H__ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the collision hull. + * \return the collision hull if it exists + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ const CollisionHull* GetHull() const { return mHull; } +#endif // __MESHMERIZER_H__ + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the number of bytes used by the tree. + * \return amount of bytes used + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(BaseModel) udword GetUsedBytes() const; + + private: +#ifdef __MESHMERIZER_H__ + CollisionHull* mHull; //!< Possible convex hull +#endif // __MESHMERIZER_H__ + // Internal methods + void Release(); + }; + +#endif //__OPC_MODEL_H__ diff --git a/libraries/ode-0.9/OPCODE/OPC_OBBCollider.cpp b/libraries/ode-0.9/OPCODE/OPC_OBBCollider.cpp new file mode 100644 index 0000000000..028d00018a --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_OBBCollider.cpp @@ -0,0 +1,767 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for an OBB collider. + * \file OPC_OBBCollider.cpp + * \author Pierre Terdiman + * \date January, 1st, 2002 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains an OBB-vs-tree collider. + * + * \class OBBCollider + * \author Pierre Terdiman + * \version 1.3 + * \date January, 1st, 2002 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +#include "OPC_BoxBoxOverlap.h" +#include "OPC_TriBoxOverlap.h" + +#define SET_CONTACT(prim_index, flag) \ + /* Set contact status */ \ + mFlags |= flag; \ + mTouchedPrimitives->Add(udword(prim_index)); + +//! OBB-triangle test +#define OBB_PRIM(prim_index, flag) \ + /* Request vertices from the app */ \ + VertexPointers VP; mIMesh->GetTriangle(VP, prim_index); \ + /* 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; +} diff --git a/libraries/ode-0.9/OPCODE/OPC_OBBCollider.h b/libraries/ode-0.9/OPCODE/OPC_OBBCollider.h new file mode 100644 index 0000000000..a05011806b --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_OBBCollider.h @@ -0,0 +1,142 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for an OBB collider. + * \file OPC_OBBCollider.h + * \author Pierre Terdiman + * \date January, 1st, 2002 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_OBBCOLLIDER_H__ +#define __OPC_OBBCOLLIDER_H__ + + struct OPCODE_API OBBCache : VolumeCache + { + OBBCache() : FatCoeff(1.1f) + { + FatBox.mCenter.Zero(); + FatBox.mExtents.Zero(); + FatBox.mRot.Identity(); + } + + // Cached faces signature + OBB FatBox; //!< Box used when performing the query resulting in cached faces + // User settings + float FatCoeff; //!< extents multiplier used to create a fat box + }; + + class OPCODE_API OBBCollider : public VolumeCollider + { + public: + // Constructor / Destructor + OBBCollider(); + virtual ~OBBCollider(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Generic collision query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - with GetNbTouchedPrimitives() + * - with GetTouchedPrimitives() + * + * \param cache [in/out] a box cache + * \param box [in] collision OBB in local space + * \param model [in] Opcode model to collide with + * \param worldb [in] OBB's world matrix, or null + * \param worldm [in] model's world matrix, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool Collide(OBBCache& cache, const OBB& box, const Model& model, const Matrix4x4* worldb=null, const Matrix4x4* worldm=null); + + // Settings + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Settings: select between full box-box tests or "SAT-lite" tests (where Class III axes are discarded) + * \param flag [in] true for full tests, false for coarse tests + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetFullBoxBoxTest(bool flag) { mFullBoxBoxTest = flag; } + + // Settings + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Validates current settings. You should call this method after all the settings and callbacks have been defined for a collider. + * \return null if everything is ok, else a string describing the problem + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(Collider) const char* ValidateSettings(); + + protected: + // Precomputed data + Matrix3x3 mAR; //!< Absolute rotation matrix + Matrix3x3 mRModelToBox; //!< Rotation from model space to obb space + Matrix3x3 mRBoxToModel; //!< Rotation from obb space to model space + Point mTModelToBox; //!< Translation from model space to obb space + Point mTBoxToModel; //!< Translation from obb space to model space + + Point mBoxExtents; + Point mB0; //!< - mTModelToBox + mBoxExtents + Point mB1; //!< - mTModelToBox - mBoxExtents + + float mBBx1; + float mBBy1; + float mBBz1; + + float mBB_1; + float mBB_2; + float mBB_3; + float mBB_4; + float mBB_5; + float mBB_6; + float mBB_7; + float mBB_8; + float mBB_9; + + // Leaf description + Point mLeafVerts[3]; //!< Triangle vertices + // Settings + bool mFullBoxBoxTest; //!< Perform full BV-BV tests (true) or SAT-lite tests (false) + // Internal methods + void _Collide(const AABBCollisionNode* node); + void _Collide(const AABBNoLeafNode* node); + void _Collide(const AABBQuantizedNode* node); + void _Collide(const AABBQuantizedNoLeafNode* node); + void _CollideNoPrimitiveTest(const AABBCollisionNode* node); + void _CollideNoPrimitiveTest(const AABBNoLeafNode* node); + void _CollideNoPrimitiveTest(const AABBQuantizedNode* node); + void _CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node); + // Overlap tests + inline_ BOOL OBBContainsBox(const Point& bc, const Point& be); + inline_ BOOL BoxBoxOverlap(const Point& extents, const Point& center); + inline_ BOOL TriBoxOverlap(); + // Init methods + BOOL InitQuery(OBBCache& cache, const OBB& box, const Matrix4x4* worldb=null, const Matrix4x4* worldm=null); + }; + + class OPCODE_API HybridOBBCollider : public OBBCollider + { + public: + // Constructor / Destructor + HybridOBBCollider(); + virtual ~HybridOBBCollider(); + + bool Collide(OBBCache& cache, const OBB& box, const HybridModel& model, const Matrix4x4* worldb=null, const Matrix4x4* worldm=null); + protected: + Container mTouchedBoxes; + }; + +#endif // __OPC_OBBCOLLIDER_H__ diff --git a/libraries/ode-0.9/OPCODE/OPC_OptimizedTree.cpp b/libraries/ode-0.9/OPCODE/OPC_OptimizedTree.cpp new file mode 100644 index 0000000000..11b92f9313 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_OptimizedTree.cpp @@ -0,0 +1,782 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * 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 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; + Point Min,Max; + Point Min_,Max_; + udword Index = mNbNodes; + while(Index--) + { + AABBNoLeafNode& Current = mNodes[Index]; + + if(Current.HasPosLeaf()) + { + mesh_interface->GetTriangle(VP, Current.GetPosPrimitive()); + 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()); + 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; +} diff --git a/libraries/ode-0.9/OPCODE/OPC_OptimizedTree.h b/libraries/ode-0.9/OPCODE/OPC_OptimizedTree.h new file mode 100644 index 0000000000..36aea07181 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_OptimizedTree.h @@ -0,0 +1,206 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for optimized trees. + * \file OPC_OptimizedTree.h + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_OPTIMIZEDTREE_H__ +#define __OPC_OPTIMIZEDTREE_H__ + + //! Common interface for a node of an implicit tree + #define IMPLEMENT_IMPLICIT_NODE(base_class, volume) \ + public: \ + /* Constructor / Destructor */ \ + inline_ base_class() : mData(0) {} \ + inline_ ~base_class() {} \ + /* Leaf test */ \ + inline_ BOOL IsLeaf() const { return (mData&1)!=0; } \ + /* Data access */ \ + inline_ const base_class* GetPos() const { return (base_class*)mData; } \ + inline_ const base_class* GetNeg() const { return ((base_class*)mData)+1; } \ + inline_ size_t GetPrimitive() const { return (mData>>1); } \ + /* Stats */ \ + inline_ udword GetNodeSize() const { return SIZEOFOBJECT; } \ + \ + volume mAABB; \ + size_t mData; + + //! Common interface for a node of a no-leaf tree + #define IMPLEMENT_NOLEAF_NODE(base_class, volume) \ + public: \ + /* Constructor / Destructor */ \ + inline_ base_class() : mPosData(0), mNegData(0) {} \ + inline_ ~base_class() {} \ + /* Leaf tests */ \ + inline_ BOOL HasPosLeaf() const { return (mPosData&1)!=0; } \ + inline_ BOOL HasNegLeaf() const { return (mNegData&1)!=0; } \ + /* Data access */ \ + inline_ const base_class* GetPos() const { return (base_class*)mPosData; } \ + inline_ const base_class* GetNeg() const { return (base_class*)mNegData; } \ + inline_ size_t GetPosPrimitive() const { return (mPosData>>1); } \ + inline_ size_t GetNegPrimitive() const { return (mNegData>>1); } \ + /* Stats */ \ + inline_ udword GetNodeSize() const { return SIZEOFOBJECT; } \ + \ + volume mAABB; \ + size_t mPosData; \ + size_t mNegData; + + class OPCODE_API AABBCollisionNode + { + IMPLEMENT_IMPLICIT_NODE(AABBCollisionNode, CollisionAABB) + + inline_ float GetVolume() const { return mAABB.mExtents.x * mAABB.mExtents.y * mAABB.mExtents.z; } + inline_ float GetSize() const { return mAABB.mExtents.SquareMagnitude(); } + inline_ udword GetRadius() const + { + udword* Bits = (udword*)&mAABB.mExtents.x; + udword Max = Bits[0]; + if(Bits[1]>Max) Max = Bits[1]; + if(Bits[2]>Max) Max = Bits[2]; + return Max; + } + + // NB: using the square-magnitude or the true volume of the box, seems to yield better results + // (assuming UNC-like informed traversal methods). I borrowed this idea from PQP. The usual "size" + // otherwise, is the largest box extent. In SOLID that extent is computed on-the-fly each time it's + // needed (the best approach IMHO). In RAPID the rotation matrix is permuted so that Extent[0] is + // always the greatest, which saves looking for it at runtime. On the other hand, it yields matrices + // whose determinant is not 1, i.e. you can't encode them anymore as unit quaternions. Not a very + // good strategy. + }; + + class OPCODE_API AABBQuantizedNode + { + IMPLEMENT_IMPLICIT_NODE(AABBQuantizedNode, QuantizedAABB) + + inline_ uword GetSize() const + { + const uword* Bits = mAABB.mExtents; + uword Max = Bits[0]; + if(Bits[1]>Max) Max = Bits[1]; + if(Bits[2]>Max) Max = Bits[2]; + return Max; + } + // NB: for quantized nodes I don't feel like computing a square-magnitude with integers all + // over the place.......! + }; + + class OPCODE_API AABBNoLeafNode + { + IMPLEMENT_NOLEAF_NODE(AABBNoLeafNode, CollisionAABB) + }; + + class OPCODE_API AABBQuantizedNoLeafNode + { + IMPLEMENT_NOLEAF_NODE(AABBQuantizedNoLeafNode, QuantizedAABB) + }; + + //! Common interface for a collision tree + #define IMPLEMENT_COLLISION_TREE(base_class, node) \ + public: \ + /* Constructor / Destructor */ \ + base_class(); \ + virtual ~base_class(); \ + /* Builds from a standard tree */ \ + override(AABBOptimizedTree) bool Build(AABBTree* tree); \ + /* Refits the tree */ \ + override(AABBOptimizedTree) bool Refit(const MeshInterface* mesh_interface); \ + /* Walks the tree */ \ + override(AABBOptimizedTree) bool Walk(GenericWalkingCallback callback, void* user_data) const; \ + /* Data access */ \ + inline_ const node* GetNodes() const { return mNodes; } \ + /* Stats */ \ + override(AABBOptimizedTree) udword GetUsedBytes() const { return mNbNodes*sizeof(node); } \ + private: \ + node* mNodes; + + typedef bool (*GenericWalkingCallback) (const void* current, void* user_data); + + class OPCODE_API AABBOptimizedTree + { + public: + // Constructor / Destructor + AABBOptimizedTree() : + mNbNodes (0) + {} + virtual ~AABBOptimizedTree() {} + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Builds the collision tree from a generic AABB tree. + * \param tree [in] generic AABB tree + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual bool Build(AABBTree* tree) = 0; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Refits the collision tree after vertices have been modified. + * \param mesh_interface [in] mesh interface for current model + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual bool Refit(const MeshInterface* mesh_interface) = 0; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Walks the tree and call the user back for each node. + * \param callback [in] walking callback + * \param user_data [in] callback's user data + * \return true if success + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + virtual bool Walk(GenericWalkingCallback callback, void* user_data) const = 0; + + // Data access + virtual udword GetUsedBytes() const = 0; + inline_ udword GetNbNodes() const { return mNbNodes; } + + protected: + udword mNbNodes; + }; + + class OPCODE_API AABBCollisionTree : public AABBOptimizedTree + { + IMPLEMENT_COLLISION_TREE(AABBCollisionTree, AABBCollisionNode) + }; + + class OPCODE_API AABBNoLeafTree : public AABBOptimizedTree + { + IMPLEMENT_COLLISION_TREE(AABBNoLeafTree, AABBNoLeafNode) + }; + + class OPCODE_API AABBQuantizedTree : public AABBOptimizedTree + { + IMPLEMENT_COLLISION_TREE(AABBQuantizedTree, AABBQuantizedNode) + + public: + Point mCenterCoeff; + Point mExtentsCoeff; + }; + + class OPCODE_API AABBQuantizedNoLeafTree : public AABBOptimizedTree + { + IMPLEMENT_COLLISION_TREE(AABBQuantizedNoLeafTree, AABBQuantizedNoLeafNode) + + public: + Point mCenterCoeff; + Point mExtentsCoeff; + }; + +#endif // __OPC_OPTIMIZEDTREE_H__ diff --git a/libraries/ode-0.9/OPCODE/OPC_Picking.cpp b/libraries/ode-0.9/OPCODE/OPC_Picking.cpp new file mode 100644 index 0000000000..3b53774133 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_Picking.cpp @@ -0,0 +1,182 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * 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; + Data->IMesh->GetTriangle(VP, StabbedFaceIndex); + if(VP.BackfaceCulling(Data->ViewPoint)) + { + if(CM==CULLMODE_CW) KeepIt = false; + } + else + { + if(CM==CULLMODE_CCW) KeepIt = false; + } + } + + if(KeepIt) *Data->Closest = hit; + } + }; + + RayCollider RC; + RC.SetMaxDist(max_dist); + RC.SetTemporalCoherence(false); + RC.SetCulling(false); // We need all faces since some of them can be double-sided + RC.SetFirstContact(false); + RC.SetHitCallback(Local::RenderCullingCallback); + + picked_face.mFaceID = INVALID_ID; + picked_face.mDistance = MAX_FLOAT; + picked_face.mU = 0.0f; + picked_face.mV = 0.0f; + + Local::CullData Data; + Data.Closest = &picked_face; + Data.MinLimit = min_dist; + Data.Callback = callback; + Data.UserData = user_data; + Data.ViewPoint = view_point; + Data.IMesh = model.GetMeshInterface(); + + if(world) + { + // Get matrices + Matrix4x4 InvWorld; + InvertPRMatrix(InvWorld, *world); + + // Compute camera position in mesh space + Data.ViewPoint *= InvWorld; + } + + RC.SetUserData(&Data); + if(RC.Collide(world_ray, model, world)) + { + return picked_face.mFaceID!=INVALID_ID; + } + return false; +} + +#endif diff --git a/libraries/ode-0.9/OPCODE/OPC_Picking.h b/libraries/ode-0.9/OPCODE/OPC_Picking.h new file mode 100644 index 0000000000..d22fa38ac8 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_Picking.h @@ -0,0 +1,45 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code to perform "picking". + * \file OPC_Picking.h + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_PICKING_H__ +#define __OPC_PICKING_H__ + +#ifdef OPC_RAYHIT_CALLBACK + + enum CullMode + { + CULLMODE_NONE = 0, + CULLMODE_CW = 1, + CULLMODE_CCW = 2 + }; + + typedef CullMode (*CullModeCallback)(udword triangle_index, void* user_data); + + OPCODE_API bool SetupAllHits (RayCollider& collider, CollisionFaces& contacts); + OPCODE_API bool SetupClosestHit (RayCollider& collider, CollisionFace& closest_contact); + OPCODE_API bool SetupShadowFeeler (RayCollider& collider); + OPCODE_API bool SetupInOutTest (RayCollider& collider); + + OPCODE_API bool Picking( + CollisionFace& picked_face, + const Ray& world_ray, const Model& model, const Matrix4x4* world, + float min_dist, float max_dist, const Point& view_point, CullModeCallback callback, void* user_data); +#endif + +#endif //__OPC_PICKING_H__ diff --git a/libraries/ode-0.9/OPCODE/OPC_PlanesAABBOverlap.h b/libraries/ode-0.9/OPCODE/OPC_PlanesAABBOverlap.h new file mode 100644 index 0000000000..5d7576e50a --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_PlanesAABBOverlap.h @@ -0,0 +1,50 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Planes-AABB overlap test. + * - original code by Ville Miettinen, from Umbra/dPVS (released on the GD-Algorithms mailing list) + * - almost used "as-is", I even left the comments (hence the frustum-related notes) + * + * \param center [in] box center + * \param extents [in] box extents + * \param out_clip_mask [out] bitmask for active planes + * \param in_clip_mask [in] bitmask for active planes + * \return TRUE if boxes overlap planes + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL PlanesCollider::PlanesAABBOverlap(const Point& center, const Point& extents, udword& out_clip_mask, udword in_clip_mask) +{ + // Stats + mNbVolumeBVTests++; + + const Plane* p = mPlanes; + + // Evaluate through all active frustum planes. We determine the relation + // between the AABB and a plane by using the concept of "near" and "far" + // vertices originally described by Zhang (and later by Möller). Our + // variant here uses 3 fabs ops, 6 muls, 7 adds and two floating point + // comparisons per plane. The routine early-exits if the AABB is found + // to be outside any of the planes. The loop also constructs a new output + // clip mask. Most FPUs have a native single-cycle fabsf() operation. + + udword Mask = 1; // current mask index (1,2,4,8,..) + udword TmpOutClipMask = 0; // initialize output clip mask into empty. + + while(Mask<=in_clip_mask) // keep looping while we have active planes left... + { + if(in_clip_mask & Mask) // if clip plane is active, process it.. + { + float NP = extents.x*fabsf(p->n.x) + extents.y*fabsf(p->n.y) + extents.z*fabsf(p->n.z); // ### fabsf could be precomputed + float MP = center.x*p->n.x + center.y*p->n.y + center.z*p->n.z + p->d; + + if(NP < MP) // near vertex behind the clip plane... + return FALSE; // .. so there is no intersection.. + if((-NP) < MP) // near and far vertices on different sides of plane.. + TmpOutClipMask |= Mask; // .. so update the clip mask... + } + Mask+=Mask; // mk = (1<Add(udword(prim_index)); + +//! Planes-triangle test +#define PLANES_PRIM(prim_index, flag) \ + /* Request vertices from the app */ \ + mIMesh->GetTriangle(mVP, prim_index); \ + /* Perform triangle-box overlap test */ \ + if(PlanesTriOverlap(clip_mask)) \ + { \ + SET_CONTACT(prim_index, flag) \ + } + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +PlanesCollider::PlanesCollider() : + mPlanes (null), + mNbPlanes (0) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * 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<Distance(*mVP.Vertex[0]); + float d1 = p->Distance(*mVP.Vertex[1]); + float d2 = p->Distance(*mVP.Vertex[2]); + if(d0>0.0f && d1>0.0f && d2>0.0f) return FALSE; +// if(!(IR(d0)&SIGN_BITMASK) && !(IR(d1)&SIGN_BITMASK) && !(IR(d2)&SIGN_BITMASK)) return FALSE; + } + Mask+=Mask; + p++; + } +/* + for(udword i=0;i<6;i++) + { + float d0 = p[i].Distance(mLeafVerts[0]); + float d1 = p[i].Distance(mLeafVerts[1]); + float d2 = p[i].Distance(mLeafVerts[2]); + if(d0>0.0f && d1>0.0f && d2>0.0f) return false; + } +*/ + return TRUE; +} diff --git a/libraries/ode-0.9/OPCODE/OPC_RayAABBOverlap.h b/libraries/ode-0.9/OPCODE/OPC_RayAABBOverlap.h new file mode 100644 index 0000000000..a8162bf033 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_RayAABBOverlap.h @@ -0,0 +1,63 @@ +// Opcode 1.1: ray-AABB overlap tests based on Woo's code +// Opcode 1.2: ray-AABB overlap tests based on the separating axis theorem +// +// The point of intersection is not computed anymore. The distance to impact is not needed anymore +// since we now have two different queries for segments or rays. + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes a segment-AABB overlap test using the separating axis theorem. Segment is cached within the class. + * \param center [in] AABB center + * \param extents [in] AABB extents + * \return true on overlap + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL RayCollider::SegmentAABBOverlap(const Point& center, const Point& extents) +{ + // Stats + mNbRayBVTests++; + + float Dx = mData2.x - center.x; if(fabsf(Dx) > extents.x + mFDir.x) return FALSE; + float Dy = mData2.y - center.y; if(fabsf(Dy) > extents.y + mFDir.y) return FALSE; + float Dz = mData2.z - center.z; if(fabsf(Dz) > extents.z + mFDir.z) return FALSE; + + float f; + f = mData.y * Dz - mData.z * Dy; if(fabsf(f) > extents.y*mFDir.z + extents.z*mFDir.y) return FALSE; + f = mData.z * Dx - mData.x * Dz; if(fabsf(f) > extents.x*mFDir.z + extents.z*mFDir.x) return FALSE; + f = mData.x * Dy - mData.y * Dx; if(fabsf(f) > extents.x*mFDir.y + extents.y*mFDir.x) return FALSE; + + return TRUE; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes a ray-AABB overlap test using the separating axis theorem. Ray is cached within the class. + * \param center [in] AABB center + * \param extents [in] AABB extents + * \return true on overlap + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL RayCollider::RayAABBOverlap(const Point& center, const Point& extents) +{ + // Stats + mNbRayBVTests++; + +// float Dx = mOrigin.x - center.x; if(fabsf(Dx) > extents.x && Dx*mDir.x>=0.0f) return FALSE; +// float Dy = mOrigin.y - center.y; if(fabsf(Dy) > extents.y && Dy*mDir.y>=0.0f) return FALSE; +// float Dz = mOrigin.z - center.z; if(fabsf(Dz) > extents.z && Dz*mDir.z>=0.0f) return FALSE; + + float Dx = mOrigin.x - center.x; if(GREATER(Dx, extents.x) && Dx*mDir.x>=0.0f) return FALSE; + float Dy = mOrigin.y - center.y; if(GREATER(Dy, extents.y) && Dy*mDir.y>=0.0f) return FALSE; + float Dz = mOrigin.z - center.z; if(GREATER(Dz, extents.z) && Dz*mDir.z>=0.0f) return FALSE; + +// float Dx = mOrigin.x - center.x; if(GREATER(Dx, extents.x) && ((SIR(Dx)-1)^SIR(mDir.x))>=0.0f) return FALSE; +// float Dy = mOrigin.y - center.y; if(GREATER(Dy, extents.y) && ((SIR(Dy)-1)^SIR(mDir.y))>=0.0f) return FALSE; +// float Dz = mOrigin.z - center.z; if(GREATER(Dz, extents.z) && ((SIR(Dz)-1)^SIR(mDir.z))>=0.0f) return FALSE; + + float f; + f = mDir.y * Dz - mDir.z * Dy; if(fabsf(f) > extents.y*mFDir.z + extents.z*mFDir.y) return FALSE; + f = mDir.z * Dx - mDir.x * Dz; if(fabsf(f) > extents.x*mFDir.z + extents.z*mFDir.x) return FALSE; + f = mDir.x * Dy - mDir.y * Dx; if(fabsf(f) > extents.x*mFDir.y + extents.y*mFDir.x) return FALSE; + + return TRUE; +} diff --git a/libraries/ode-0.9/OPCODE/OPC_RayCollider.cpp b/libraries/ode-0.9/OPCODE/OPC_RayCollider.cpp new file mode 100644 index 0000000000..5828ce4336 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_RayCollider.cpp @@ -0,0 +1,762 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * 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; mIMesh->GetTriangle(VP, prim_index); \ + \ + /* 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); \ + \ + /* 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() : + mNbRayBVTests (0), + mNbRayPrimTests (0), + mNbIntersections (0), + mCulling (true), +#ifdef OPC_RAYHIT_CALLBACK + mHitCallback (null), + mUserData (0), +#else + mClosestHit (false), + mStabbedFaces (null), +#endif + mMaxDist (MAX_FLOAT) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * 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; + mIMesh->GetTriangle(VP, *face_id); + // 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); + } +} diff --git a/libraries/ode-0.9/OPCODE/OPC_RayCollider.h b/libraries/ode-0.9/OPCODE/OPC_RayCollider.h new file mode 100644 index 0000000000..3fd8381a67 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_RayCollider.h @@ -0,0 +1,225 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * 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 +#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 +#ifndef OPC_RAYHIT_CALLBACK + bool mClosestHit; //!< Report closest hit only +#endif + bool mCulling; //!< Stab culled faces or not + // Internal methods + void _SegmentStab(const AABBCollisionNode* node); + void _SegmentStab(const AABBNoLeafNode* node); + void _SegmentStab(const AABBQuantizedNode* node); + void _SegmentStab(const AABBQuantizedNoLeafNode* node); + void _SegmentStab(const AABBTreeNode* node, Container& box_indices); + void _RayStab(const AABBCollisionNode* node); + void _RayStab(const AABBNoLeafNode* node); + void _RayStab(const AABBQuantizedNode* node); + void _RayStab(const AABBQuantizedNoLeafNode* node); + void _RayStab(const AABBTreeNode* node, Container& box_indices); + // Overlap tests + inline_ BOOL RayAABBOverlap(const Point& center, const Point& extents); + inline_ BOOL SegmentAABBOverlap(const Point& center, const Point& extents); + inline_ BOOL RayTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2); + // Init methods + BOOL InitQuery(const Ray& world_ray, const Matrix4x4* world=null, udword* face_id=null); + }; + +#endif // __OPC_RAYCOLLIDER_H__ diff --git a/libraries/ode-0.9/OPCODE/OPC_RayTriOverlap.h b/libraries/ode-0.9/OPCODE/OPC_RayTriOverlap.h new file mode 100644 index 0000000000..7fe37c9856 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_RayTriOverlap.h @@ -0,0 +1,89 @@ +#define LOCAL_EPSILON 0.000001f + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Computes a ray-triangle intersection test. + * Original code from Tomas Möller's "Fast Minimum Storage Ray-Triangle Intersection". + * It's been optimized a bit with integer code, and modified to return a non-intersection if distance from + * ray origin to triangle is negative. + * + * \param vert0 [in] triangle vertex + * \param vert1 [in] triangle vertex + * \param vert2 [in] triangle vertex + * \return true on overlap. mStabbedFace is filled with relevant info. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL RayCollider::RayTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2) +{ + // Stats + mNbRayPrimTests++; + + // Find vectors for two edges sharing vert0 + Point edge1 = vert1 - vert0; + Point edge2 = vert2 - vert0; + + // Begin calculating determinant - also used to calculate U parameter + Point pvec = mDir^edge2; + + // If determinant is near zero, ray lies in plane of triangle + float det = edge1|pvec; + + if(mCulling) + { + if(det 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; +} diff --git a/libraries/ode-0.9/OPCODE/OPC_Settings.h b/libraries/ode-0.9/OPCODE/OPC_Settings.h new file mode 100644 index 0000000000..1841a2bcf5 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_Settings.h @@ -0,0 +1,49 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains compilation flags. + * \file OPC_Settings.h + * \author Pierre Terdiman + * \date May, 12, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_SETTINGS_H__ +#define __OPC_SETTINGS_H__ + + //! Use CPU comparisons (comment that line to use standard FPU compares) + #define OPC_CPU_COMPARE + + //! Use FCOMI / FCMOV on Pentium-Pro based processors (comment that line to use plain C++) + #define OPC_USE_FCOMI + + //! Use epsilon value in tri-tri overlap test + #define OPC_TRITRI_EPSILON_TEST + + //! Use tree-coherence or not [not implemented yet] +// #define OPC_USE_TREE_COHERENCE + + //! Use callbacks or direct pointers. Using callbacks might be a bit slower (but probably not much) +// #define OPC_USE_CALLBACKS + + //! Support triangle and vertex strides or not. Using strides might be a bit slower (but probably not much) + #define OPC_USE_STRIDE + + //! Discard negative pointer in vanilla trees + #define OPC_NO_NEG_VANILLA_TREE + + //! Use a callback in the ray collider + //#define OPC_RAYHIT_CALLBACK + + // NB: no compilation flag to enable/disable stats since they're actually needed in the box/box overlap test + +#endif //__OPC_SETTINGS_H__ diff --git a/libraries/ode-0.9/OPCODE/OPC_SphereAABBOverlap.h b/libraries/ode-0.9/OPCODE/OPC_SphereAABBOverlap.h new file mode 100644 index 0000000000..2278bc01f9 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_SphereAABBOverlap.h @@ -0,0 +1,128 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Sphere-AABB overlap test, based on Jim Arvo's code. + * \param center [in] box center + * \param extents [in] box extents + * \return TRUE on overlap + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL SphereCollider::SphereAABBOverlap(const Point& center, const Point& extents) +{ + // Stats + mNbVolumeBVTests++; + + float d = 0.0f; + + //find the square of the distance + //from the sphere to the box +#ifdef OLDIES + for(udword i=0;i<3;i++) + { + float tmp = mCenter[i] - center[i]; + float s = tmp + extents[i]; + + if(s<0.0f) d += s*s; + else + { + s = tmp - extents[i]; + if(s>0.0f) d += s*s; + } + } +#endif + +//#ifdef NEW_TEST + +// float tmp = mCenter.x - center.x; +// float s = tmp + extents.x; + + float tmp,s; + + tmp = mCenter.x - center.x; + s = tmp + extents.x; + + if(s<0.0f) + { + d += s*s; + if(d>mRadius2) return FALSE; + } + else + { + s = tmp - extents.x; + if(s>0.0f) + { + d += s*s; + if(d>mRadius2) return FALSE; + } + } + + tmp = mCenter.y - center.y; + s = tmp + extents.y; + + if(s<0.0f) + { + d += s*s; + if(d>mRadius2) return FALSE; + } + else + { + s = tmp - extents.y; + if(s>0.0f) + { + d += s*s; + if(d>mRadius2) return FALSE; + } + } + + tmp = mCenter.z - center.z; + s = tmp + extents.z; + + if(s<0.0f) + { + d += s*s; + if(d>mRadius2) return FALSE; + } + else + { + s = tmp - extents.z; + if(s>0.0f) + { + d += s*s; + if(d>mRadius2) return FALSE; + } + } +//#endif + +#ifdef OLDIES +// Point Min = center - extents; +// Point Max = center + extents; + + float d = 0.0f; + + //find the square of the distance + //from the sphere to the box + for(udword i=0;i<3;i++) + { +float Min = center[i] - extents[i]; + +// if(mCenter[i]Max[i]) + if(mCenter[i]>Max) + { + float s = mCenter[i] - Max; + d += s*s; + } + } + } +#endif + return d <= mRadius2; +} diff --git a/libraries/ode-0.9/OPCODE/OPC_SphereCollider.cpp b/libraries/ode-0.9/OPCODE/OPC_SphereCollider.cpp new file mode 100644 index 0000000000..65350b714f --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_SphereCollider.cpp @@ -0,0 +1,739 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a sphere collider. + * \file OPC_SphereCollider.cpp + * \author Pierre Terdiman + * \date June, 2, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains a sphere-vs-tree collider. + * This class performs a collision test between a sphere and an AABB tree. You can use this to do a standard player vs world collision, + * in a Nettle/Telemachos way. It doesn't suffer from all reported bugs in those two classic codes - the "new" one by Paul Nettle is a + * debuggued version I think. Collision response can be driven by reported collision data - it works extremely well for me. In sake of + * efficiency, all meshes (that is, all AABB trees) should of course also be kept in an extra hierarchical structure (octree, whatever). + * + * \class SphereCollider + * \author Pierre Terdiman + * \version 1.3 + * \date June, 2, 2001 +*/ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +#include "OPC_SphereAABBOverlap.h" +#include "OPC_SphereTriOverlap.h" + +#define SET_CONTACT(prim_index, flag) \ + /* Set contact status */ \ + mFlags |= flag; \ + mTouchedPrimitives->Add(udword(prim_index)); + +//! Sphere-triangle overlap test +#define SPHERE_PRIM(prim_index, flag) \ + /* Request vertices from the app */ \ + VertexPointers VP; mIMesh->GetTriangle(VP, prim_index); \ + \ + /* 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; +} diff --git a/libraries/ode-0.9/OPCODE/OPC_SphereCollider.h b/libraries/ode-0.9/OPCODE/OPC_SphereCollider.h new file mode 100644 index 0000000000..ac6495ef9f --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_SphereCollider.h @@ -0,0 +1,96 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a sphere collider. + * \file OPC_SphereCollider.h + * \author Pierre Terdiman + * \date June, 2, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_SPHERECOLLIDER_H__ +#define __OPC_SPHERECOLLIDER_H__ + + struct OPCODE_API SphereCache : VolumeCache + { + SphereCache() : Center(0.0f,0.0f,0.0f), FatRadius2(0.0f), FatCoeff(1.1f) {} + ~SphereCache() {} + + // Cached faces signature + Point Center; //!< Sphere used when performing the query resulting in cached faces + float FatRadius2; //!< Sphere used when performing the query resulting in cached faces + // User settings + float FatCoeff; //!< mRadius2 multiplier used to create a fat sphere + }; + + class OPCODE_API SphereCollider : public VolumeCollider + { + public: + // Constructor / Destructor + SphereCollider(); + virtual ~SphereCollider(); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Generic collision query for generic OPCODE models. After the call, access the results: + * - with GetContactStatus() + * - with GetNbTouchedPrimitives() + * - with GetTouchedPrimitives() + * + * \param cache [in/out] a sphere cache + * \param sphere [in] collision sphere in local space + * \param model [in] Opcode model to collide with + * \param worlds [in] sphere's world matrix, or null + * \param worldm [in] model's world matrix, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool Collide(SphereCache& cache, const Sphere& sphere, const Model& model, const Matrix4x4* worlds=null, const Matrix4x4* worldm=null); + + // + bool Collide(SphereCache& cache, const Sphere& sphere, const AABBTree* tree); + protected: + // Sphere in model space + Point mCenter; //!< Sphere center + float mRadius2; //!< Sphere radius squared + // Internal methods + void _Collide(const AABBCollisionNode* node); + void _Collide(const AABBNoLeafNode* node); + void _Collide(const AABBQuantizedNode* node); + void _Collide(const AABBQuantizedNoLeafNode* node); + void _Collide(const AABBTreeNode* node); + void _CollideNoPrimitiveTest(const AABBCollisionNode* node); + void _CollideNoPrimitiveTest(const AABBNoLeafNode* node); + void _CollideNoPrimitiveTest(const AABBQuantizedNode* node); + void _CollideNoPrimitiveTest(const AABBQuantizedNoLeafNode* node); + // Overlap tests + inline_ BOOL SphereContainsBox(const Point& bc, const Point& be); + inline_ BOOL SphereAABBOverlap(const Point& center, const Point& extents); + BOOL SphereTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2); + // Init methods + BOOL InitQuery(SphereCache& cache, const Sphere& sphere, const Matrix4x4* worlds=null, const Matrix4x4* worldm=null); + }; + + class OPCODE_API HybridSphereCollider : public SphereCollider + { + public: + // Constructor / Destructor + HybridSphereCollider(); + virtual ~HybridSphereCollider(); + + bool Collide(SphereCache& cache, const Sphere& sphere, const HybridModel& model, const Matrix4x4* worlds=null, const Matrix4x4* worldm=null); + protected: + Container mTouchedBoxes; + }; + +#endif // __OPC_SPHERECOLLIDER_H__ diff --git a/libraries/ode-0.9/OPCODE/OPC_SphereTriOverlap.h b/libraries/ode-0.9/OPCODE/OPC_SphereTriOverlap.h new file mode 100644 index 0000000000..77e59f371d --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_SphereTriOverlap.h @@ -0,0 +1,187 @@ + +// This is collision detection. If you do another distance test for collision *response*, +// if might be useful to simply *skip* the test below completely, and report a collision. +// - if sphere-triangle overlap, result is ok +// - if they don't, we'll discard them during collision response with a similar test anyway +// Overall this approach should run faster. + +// Original code by David Eberly in Magic. +BOOL SphereCollider::SphereTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2) +{ + // Stats + mNbVolumePrimTests++; + + // Early exit if one of the vertices is inside the sphere + Point kDiff = vert2 - mCenter; + float fC = kDiff.SquareMagnitude(); + if(fC <= mRadius2) return TRUE; + + kDiff = vert1 - mCenter; + fC = kDiff.SquareMagnitude(); + if(fC <= mRadius2) return TRUE; + + kDiff = vert0 - mCenter; + fC = kDiff.SquareMagnitude(); + if(fC <= mRadius2) return TRUE; + + // Else do the full distance test + Point TriEdge0 = vert1 - vert0; + Point TriEdge1 = vert2 - vert0; + +//Point kDiff = vert0 - mCenter; + float fA00 = TriEdge0.SquareMagnitude(); + float fA01 = TriEdge0 | TriEdge1; + float fA11 = TriEdge1.SquareMagnitude(); + float fB0 = kDiff | TriEdge0; + float fB1 = kDiff | TriEdge1; +//float fC = kDiff.SquareMagnitude(); + float fDet = fabsf(fA00*fA11 - fA01*fA01); + float u = fA01*fB1-fA11*fB0; + float v = fA01*fB0-fA00*fB1; + float SqrDist; + + if(u + v <= fDet) + { + if(u < 0.0f) + { + if(v < 0.0f) // region 4 + { + if(fB0 < 0.0f) + { +// v = 0.0f; + if(-fB0>=fA00) { /*u = 1.0f;*/ SqrDist = fA00+2.0f*fB0+fC; } + else { u = -fB0/fA00; SqrDist = fB0*u+fC; } + } + else + { +// u = 0.0f; + if(fB1>=0.0f) { /*v = 0.0f;*/ SqrDist = fC; } + else if(-fB1>=fA11) { /*v = 1.0f;*/ SqrDist = fA11+2.0f*fB1+fC; } + else { v = -fB1/fA11; SqrDist = fB1*v+fC; } + } + } + else // region 3 + { +// u = 0.0f; + if(fB1>=0.0f) { /*v = 0.0f;*/ SqrDist = fC; } + else if(-fB1>=fA11) { /*v = 1.0f;*/ SqrDist = fA11+2.0f*fB1+fC; } + else { v = -fB1/fA11; SqrDist = fB1*v+fC; } + } + } + else if(v < 0.0f) // region 5 + { +// v = 0.0f; + if(fB0>=0.0f) { /*u = 0.0f;*/ SqrDist = fC; } + else if(-fB0>=fA00) { /*u = 1.0f;*/ SqrDist = fA00+2.0f*fB0+fC; } + else { u = -fB0/fA00; SqrDist = fB0*u+fC; } + } + else // region 0 + { + // minimum at interior point + if(fDet==0.0f) + { +// u = 0.0f; +// v = 0.0f; + SqrDist = MAX_FLOAT; + } + else + { + float fInvDet = 1.0f/fDet; + u *= fInvDet; + v *= fInvDet; + SqrDist = u*(fA00*u+fA01*v+2.0f*fB0) + v*(fA01*u+fA11*v+2.0f*fB1)+fC; + } + } + } + else + { + float fTmp0, fTmp1, fNumer, fDenom; + + if(u < 0.0f) // region 2 + { + fTmp0 = fA01 + fB0; + fTmp1 = fA11 + fB1; + if(fTmp1 > fTmp0) + { + fNumer = fTmp1 - fTmp0; + fDenom = fA00-2.0f*fA01+fA11; + if(fNumer >= fDenom) + { +// u = 1.0f; +// v = 0.0f; + SqrDist = fA00+2.0f*fB0+fC; + } + else + { + u = fNumer/fDenom; + v = 1.0f - u; + SqrDist = u*(fA00*u+fA01*v+2.0f*fB0) + v*(fA01*u+fA11*v+2.0f*fB1)+fC; + } + } + else + { +// u = 0.0f; + if(fTmp1 <= 0.0f) { /*v = 1.0f;*/ SqrDist = fA11+2.0f*fB1+fC; } + else if(fB1 >= 0.0f) { /*v = 0.0f;*/ SqrDist = fC; } + else { v = -fB1/fA11; SqrDist = fB1*v+fC; } + } + } + else if(v < 0.0f) // region 6 + { + fTmp0 = fA01 + fB1; + fTmp1 = fA00 + fB0; + if(fTmp1 > fTmp0) + { + fNumer = fTmp1 - fTmp0; + fDenom = fA00-2.0f*fA01+fA11; + if(fNumer >= fDenom) + { +// v = 1.0f; +// u = 0.0f; + SqrDist = fA11+2.0f*fB1+fC; + } + else + { + v = fNumer/fDenom; + u = 1.0f - v; + SqrDist = u*(fA00*u+fA01*v+2.0f*fB0) + v*(fA01*u+fA11*v+2.0f*fB1)+fC; + } + } + else + { +// v = 0.0f; + if(fTmp1 <= 0.0f) { /*u = 1.0f;*/ SqrDist = fA00+2.0f*fB0+fC; } + else if(fB0 >= 0.0f) { /*u = 0.0f;*/ SqrDist = fC; } + else { u = -fB0/fA00; SqrDist = fB0*u+fC; } + } + } + else // region 1 + { + fNumer = fA11 + fB1 - fA01 - fB0; + if(fNumer <= 0.0f) + { +// u = 0.0f; +// v = 1.0f; + SqrDist = fA11+2.0f*fB1+fC; + } + else + { + fDenom = fA00-2.0f*fA01+fA11; + if(fNumer >= fDenom) + { +// u = 1.0f; +// v = 0.0f; + SqrDist = fA00+2.0f*fB0+fC; + } + else + { + u = fNumer/fDenom; + v = 1.0f - u; + SqrDist = u*(fA00*u+fA01*v+2.0f*fB0) + v*(fA01*u+fA11*v+2.0f*fB1)+fC; + } + } + } + } + + return fabsf(SqrDist) < mRadius2; +} diff --git a/libraries/ode-0.9/OPCODE/OPC_SweepAndPrune.cpp b/libraries/ode-0.9/OPCODE/OPC_SweepAndPrune.cpp new file mode 100644 index 0000000000..7f1a8f317a --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_SweepAndPrune.cpp @@ -0,0 +1,664 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains an implementation of the sweep-and-prune algorithm (moved from Z-Collide) + * \file OPC_SweepAndPrune.cpp + * \author Pierre Terdiman + * \date January, 29, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Precompiled Header +#include "Stdafx.h" + +using namespace Opcode; + +inline_ void Sort(udword& id0, udword& id1) +{ + if(id0>id1) Swap(id0, id1); +} + + class Opcode::SAP_Element + { + public: + inline_ SAP_Element() {} + inline_ SAP_Element(udword id, SAP_Element* next) : mID(id), mNext(next) {} + inline_ ~SAP_Element() {} + + udword mID; + SAP_Element* mNext; + }; + + class Opcode::SAP_Box + { + public: + SAP_EndPoint* Min[3]; + SAP_EndPoint* Max[3]; + }; + + class Opcode::SAP_EndPoint + { + public: + float Value; // Min or Max value + SAP_EndPoint* Previous; // Previous EndPoint whose Value is smaller than ours (or null) + SAP_EndPoint* Next; // Next EndPoint whose Value is greater than ours (or null) + udword Data; // Parent box ID *2 | MinMax flag + + inline_ void SetData(udword box_id, BOOL is_max) { Data = (box_id<<1)|is_max; } + inline_ BOOL IsMax() const { return Data & 1; } + inline_ udword GetBoxID() const { return Data>>1; } + + inline_ void InsertAfter(SAP_EndPoint* element) + { + if(this!=element && this!=element->Next) + { + // Remove + if(Previous) Previous->Next = Next; + if(Next) Next->Previous = Previous; + + // Insert + Next = element->Next; + if(Next) Next->Previous = this; + + element->Next = this; + Previous = element; + } + } + + inline_ void InsertBefore(SAP_EndPoint* element) + { + if(this!=element && this!=element->Previous) + { + // Remove + if(Previous) Previous->Next = Next; + if(Next) Next->Previous = Previous; + + // Insert + Previous = element->Previous; + element->Previous = this; + + Next = element; + if(Previous) Previous->Next = this; + } + } + }; + + + + + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +SAP_PairData::SAP_PairData() : + mNbElements (0), + mNbUsedElements (0), + mElementPool (null), + mFirstFree (null), + mNbObjects (0), + mArray (null) +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +SAP_PairData::~SAP_PairData() +{ + Release(); +} + +void SAP_PairData::Release() +{ + mNbElements = 0; + mNbUsedElements = 0; + mNbObjects = 0; + DELETEARRAY(mElementPool); + DELETEARRAY(mArray); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Initializes. + * \param nb_objects [in] + * \return true if success + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool SAP_PairData::Init(udword nb_objects) +{ + // Make sure everything has been released + Release(); + if(!nb_objects) return false; + + mArray = new SAP_Element*[nb_objects]; + CHECKALLOC(mArray); + ZeroMemory(mArray, nb_objects*sizeof(SAP_Element*)); + mNbObjects = nb_objects; + + return true; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Remaps a pointer when pool gets resized. + * \param element [in/out] remapped element + * \param delta [in] offset in bytes + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ void Remap(SAP_Element*& element, size_t delta) +{ + if(element) element = (SAP_Element*)(size_t(element) + delta); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Gets a free element in the pool. + * \param id [in] element id + * \param next [in] next element + * \param remap [out] possible remapping offset + * \return the new element + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +SAP_Element* SAP_PairData::GetFreeElem(udword id, SAP_Element* next, udword* remap) +{ + if(remap) *remap = 0; + + SAP_Element* FreeElem; + if(mFirstFree) + { + // Recycle + FreeElem = mFirstFree; + mFirstFree = mFirstFree->mNext; // First free = next free (or null) + } + else + { + if(mNbUsedElements==mNbElements) + { + // Resize + mNbElements = mNbElements ? (mNbElements<<1) : 2; + + SAP_Element* NewElems = new SAP_Element[mNbElements]; + + if(mNbUsedElements) CopyMemory(NewElems, mElementPool, mNbUsedElements*sizeof(SAP_Element)); + + // Remap everything + { + size_t Delta = size_t(NewElems) - size_t(mElementPool); + + for(udword i=0;imID = id; + FreeElem->mNext = next; + + return FreeElem; +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Frees an element of the pool. + * \param elem [in] element to free/recycle + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ void SAP_PairData::FreeElem(SAP_Element* elem) +{ + elem->mNext = mFirstFree; // Next free + mFirstFree = elem; +} + +// Add a pair to the set. +void SAP_PairData::AddPair(udword id1, udword id2) +{ + // Order the ids + Sort(id1, id2); + + ASSERT(id1=mNbObjects) return; + + // Select the right list from "mArray". + SAP_Element* Current = mArray[id1]; + + if(!Current) + { + // Empty slot => create new element + mArray[id1] = GetFreeElem(id2, null); + } + else if(Current->mID>id2) + { + // The list is not empty but all elements are greater than id2 => insert id2 in the front. + mArray[id1] = GetFreeElem(id2, mArray[id1]); + } + else + { + // Else find the correct location in the sorted list (ascending order) and insert id2 there. + while(Current->mNext) + { + if(Current->mNext->mID > id2) break; + + Current = Current->mNext; + } + + if(Current->mID==id2) return; // The pair already exists + +// Current->mNext = GetFreeElem(id2, Current->mNext); + udword Delta; + SAP_Element* E = GetFreeElem(id2, Current->mNext, &Delta); + if(Delta) Remap(Current, Delta); + Current->mNext = E; + } +} + +// Delete a pair from the set. +void SAP_PairData::RemovePair(udword id1, udword id2) +{ + // Order the ids. + Sort(id1, id2); + + // Exit if the pair doesn't exist in the set + if(id1>=mNbObjects) return; + + // Otherwise, select the correct list. + SAP_Element* Current = mArray[id1]; + + // If this list is empty, the pair doesn't exist. + if(!Current) return; + + // Otherwise, if id2 is the first element, delete it. + if(Current->mID==id2) + { + mArray[id1] = Current->mNext; + FreeElem(Current); + } + else + { + // If id2 is not the first element, start traversing the sorted list. + while(Current->mNext) + { + // If we have moved too far away without hitting id2, then the pair doesn't exist + if(Current->mNext->mID > id2) return; + + // Otherwise, delete id2. + if(Current->mNext->mID == id2) + { + SAP_Element* Temp = Current->mNext; + Current->mNext = Temp->mNext; + FreeElem(Temp); + return; + } + Current = Current->mNext; + } + } +} + +void SAP_PairData::DumpPairs(Pairs& pairs) const +{ + // ### Ugly and slow + for(udword i=0;imIDmID); + Current = Current->mNext; + } + } +} + +void SAP_PairData::DumpPairs(PairCallback callback, void* user_data) const +{ + if(!callback) return; + + // ### Ugly and slow + for(udword i=0;imIDmID, user_data)) return; + Current = Current->mNext; + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Constructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +SweepAndPrune::SweepAndPrune() +{ +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Destructor. + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +SweepAndPrune::~SweepAndPrune() +{ +} + +void SweepAndPrune::GetPairs(Pairs& pairs) const +{ + mPairs.DumpPairs(pairs); +} + +void SweepAndPrune::GetPairs(PairCallback callback, void* user_data) const +{ + mPairs.DumpPairs(callback, user_data); +} + +bool SweepAndPrune::Init(udword nb_objects, const AABB** boxes) +{ + // 1) Create sorted lists + mNbObjects = nb_objects; + + mBoxes = new SAP_Box[nb_objects]; +// for(udword i=0;iGetMin(Axis); + Data[i*2+1] = boxes[i]->GetMax(Axis); + } + RadixSort RS; + const udword* Sorted = RS.Sort(Data, nb_objects*2).GetRanks(); + + SAP_EndPoint* PreviousEndPoint = null; + + for(udword i=0;i>1; + + ASSERT(BoxIndexValue = SortedCoord; +// CurrentEndPoint->IsMax = SortedIndex&1; // ### could be implicit ? +// CurrentEndPoint->ID = BoxIndex; // ### could be implicit ? + CurrentEndPoint->SetData(BoxIndex, SortedIndex&1); // ### could be implicit ? + CurrentEndPoint->Previous = PreviousEndPoint; + CurrentEndPoint->Next = null; + if(PreviousEndPoint) PreviousEndPoint->Next = CurrentEndPoint; + + if(CurrentEndPoint->IsMax()) mBoxes[BoxIndex].Max[Axis] = CurrentEndPoint; + else mBoxes[BoxIndex].Min[Axis] = CurrentEndPoint; + + PreviousEndPoint = CurrentEndPoint; + } + } + + DELETEARRAY(Data); + + CheckListsIntegrity(); + + // 2) Quickly find starting pairs + + mPairs.Init(nb_objects); + + { + Pairs P; + CompleteBoxPruning(nb_objects, boxes, P, Axes(AXES_XZY)); + for(udword i=0;iid0; + udword id1 = PP->id1; + + if(id0!=id1 && boxes[id0]->Intersect(*boxes[id1])) + { + mPairs.AddPair(id0, id1); + } + else ASSERT(0); + } + } + + return true; +} + +bool SweepAndPrune::CheckListsIntegrity() +{ + for(udword Axis=0;Axis<3;Axis++) + { + // Find list head + SAP_EndPoint* Current = mList[Axis]; + while(Current->Previous) Current = Current->Previous; + + udword Nb = 0; + + SAP_EndPoint* Previous = null; + while(Current) + { + Nb++; + + if(Previous) + { + ASSERT(Previous->Value <= Current->Value); + if(Previous->Value > Current->Value) return false; + } + + ASSERT(Current->Previous==Previous); + if(Current->Previous!=Previous) return false; + + Previous = Current; + Current = Current->Next; + } + + ASSERT(Nb==mNbObjects*2); + } + return true; +} + +inline_ BOOL Intersect(const AABB& a, const SAP_Box& b) +{ + if(b.Max[0]->Value < a.GetMin(0) || a.GetMax(0) < b.Min[0]->Value + || b.Max[1]->Value < a.GetMin(1) || a.GetMax(1) < b.Min[1]->Value + || b.Max[2]->Value < a.GetMin(2) || a.GetMax(2) < b.Min[2]->Value) return FALSE; + + return TRUE; +} + + + +bool SweepAndPrune::UpdateObject(udword i, const AABB& box) +{ + for(udword Axis=0;Axis<3;Axis++) + { +// udword Base = (udword)&mList[Axis][0]; + + // Update min + { + SAP_EndPoint* const CurrentMin = mBoxes[i].Min[Axis]; + ASSERT(!CurrentMin->IsMax()); + + const float Limit = box.GetMin(Axis); + if(Limit == CurrentMin->Value) + { + } + else if(Limit < CurrentMin->Value) + { + CurrentMin->Value = Limit; + + // Min is moving left: + SAP_EndPoint* NewPos = CurrentMin; + ASSERT(NewPos); + + SAP_EndPoint* tmp; + while((tmp = NewPos->Previous) && tmp->Value > Limit) + { + NewPos = tmp; + + if(NewPos->IsMax()) + { + // Our min passed a max => start overlap + //udword SortedIndex = (udword(CurrentMin) - Base)/sizeof(NS_EndPoint); + const udword id0 = CurrentMin->GetBoxID(); + const udword id1 = NewPos->GetBoxID(); + + if(id0!=id1 && Intersect(box, mBoxes[id1])) mPairs.AddPair(id0, id1); + } + } + + CurrentMin->InsertBefore(NewPos); + } + else// if(Limit > CurrentMin->Value) + { + CurrentMin->Value = Limit; + + // Min is moving right: + SAP_EndPoint* NewPos = CurrentMin; + ASSERT(NewPos); + + SAP_EndPoint* tmp; + while((tmp = NewPos->Next) && tmp->Value < Limit) + { + NewPos = tmp; + + if(NewPos->IsMax()) + { + // Our min passed a max => stop overlap + const udword id0 = CurrentMin->GetBoxID(); + const udword id1 = NewPos->GetBoxID(); + + if(id0!=id1) mPairs.RemovePair(id0, id1); + } + } + + CurrentMin->InsertAfter(NewPos); + } + } + + // Update max + { + SAP_EndPoint* const CurrentMax = mBoxes[i].Max[Axis]; + ASSERT(CurrentMax->IsMax()); + + const float Limit = box.GetMax(Axis); + if(Limit == CurrentMax->Value) + { + } + else if(Limit > CurrentMax->Value) + { + CurrentMax->Value = Limit; + + // Max is moving right: + SAP_EndPoint* NewPos = CurrentMax; + ASSERT(NewPos); + + SAP_EndPoint* tmp; + while((tmp = NewPos->Next) && tmp->Value < Limit) + { + NewPos = tmp; + + if(!NewPos->IsMax()) + { + // Our max passed a min => start overlap + const udword id0 = CurrentMax->GetBoxID(); + const udword id1 = NewPos->GetBoxID(); + + if(id0!=id1 && Intersect(box, mBoxes[id1])) mPairs.AddPair(id0, id1); + } + } + + CurrentMax->InsertAfter(NewPos); + } + else// if(Limit < CurrentMax->Value) + { + CurrentMax->Value = Limit; + + // Max is moving left: + SAP_EndPoint* NewPos = CurrentMax; + ASSERT(NewPos); + + SAP_EndPoint* tmp; + while((tmp = NewPos->Previous) && tmp->Value > Limit) + { + NewPos = tmp; + + if(!NewPos->IsMax()) + { + // Our max passed a min => stop overlap + const udword id0 = CurrentMax->GetBoxID(); + const udword id1 = NewPos->GetBoxID(); + + if(id0!=id1) mPairs.RemovePair(id0, id1); + } + } + + CurrentMax->InsertBefore(NewPos); + } + } + } + + return true; +} diff --git a/libraries/ode-0.9/OPCODE/OPC_SweepAndPrune.h b/libraries/ode-0.9/OPCODE/OPC_SweepAndPrune.h new file mode 100644 index 0000000000..2cbbb7e6ca --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_SweepAndPrune.h @@ -0,0 +1,86 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains an implementation of the sweep-and-prune algorithm (moved from Z-Collide) + * \file OPC_SweepAndPrune.h + * \author Pierre Terdiman + * \date January, 29, 2000 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_SWEEPANDPRUNE_H__ +#define __OPC_SWEEPANDPRUNE_H__ + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * User-callback, called by OPCODE for each colliding pairs. + * \param id0 [in] id of colliding object + * \param id1 [in] id of colliding object + * \param user_data [in] user-defined data + * \return TRUE to continue enumeration + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + typedef BOOL (*PairCallback) (udword id0, udword id1, void* user_data); + + class SAP_Element; + class SAP_EndPoint; + class SAP_Box; + + class OPCODE_API SAP_PairData + { + public: + SAP_PairData(); + ~SAP_PairData(); + + bool Init(udword nb_objects); + + void AddPair(udword id1, udword id2); + void RemovePair(udword id1, udword id2); + + void DumpPairs(Pairs& pairs) const; + void DumpPairs(PairCallback callback, void* user_data) const; + private: + udword mNbElements; //!< Total number of elements in the pool + udword mNbUsedElements; //!< Number of used elements + SAP_Element* mElementPool; //!< Array of mNbElements elements + SAP_Element* mFirstFree; //!< First free element in the pool + + udword mNbObjects; //!< Max number of objects we can handle + SAP_Element** mArray; //!< Pointers to pool + // Internal methods + SAP_Element* GetFreeElem(udword id, SAP_Element* next, udword* remap=null); + inline_ void FreeElem(SAP_Element* elem); + void Release(); + }; + + class OPCODE_API SweepAndPrune + { + public: + SweepAndPrune(); + ~SweepAndPrune(); + + bool Init(udword nb_objects, const AABB** boxes); + bool UpdateObject(udword i, const AABB& box); + + void GetPairs(Pairs& pairs) const; + void GetPairs(PairCallback callback, void* user_data) const; + private: + SAP_PairData mPairs; + + udword mNbObjects; + SAP_Box* mBoxes; + SAP_EndPoint* mList[3]; + // Internal methods + bool CheckListsIntegrity(); + }; + +#endif //__OPC_SWEEPANDPRUNE_H__ diff --git a/libraries/ode-0.9/OPCODE/OPC_TreeBuilders.cpp b/libraries/ode-0.9/OPCODE/OPC_TreeBuilders.cpp new file mode 100644 index 0000000000..d2359a0ef2 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_TreeBuilders.cpp @@ -0,0 +1,255 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * 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 udword* 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++); + // 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; + mIMesh->GetTriangle(VP, index); + + // 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 udword* 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; + for(udword i=0;iGetTriangle(VP, primitives[i]); + // 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 udword* 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;iHasLeafNodes()!=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; + static bool GJKInitDone=false; + 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; + 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; + mIMesh0->GetTriangle(VP0, id0); + mIMesh1->GetTriangle(VP1, id1); + + // 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; + mIMesh1->GetTriangle(VP, id1); + + // 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; + mIMesh0->GetTriangle(VP, id0); + + // 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; imesh->GetTriangle(VP, prim_index); \ + /* Transform them in a common space */ \ + TransformPoint(mLeafVerts[0], *VP.Vertex[0], rot, trans); \ + TransformPoint(mLeafVerts[1], *VP.Vertex[1], rot, trans); \ + TransformPoint(mLeafVerts[2], *VP.Vertex[2], rot, trans); + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for no-leaf AABB trees. + * \param a [in] collision node from first tree + * \param b [in] collision node from second tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::_Collide(const AABBNoLeafNode* a, const AABBNoLeafNode* b) +{ + // Perform BV-BV overlap test + if(!BoxBoxOverlap(a->mAABB.mExtents, a->mAABB.mCenter, b->mAABB.mExtents, b->mAABB.mCenter)) return; + + // Catch leaf status + BOOL BHasPosLeaf = b->HasPosLeaf(); + BOOL BHasNegLeaf = b->HasNegLeaf(); + + if(a->HasPosLeaf()) + { + FETCH_LEAF(a->GetPosPrimitive(), mIMesh0, mR0to1, mT0to1) + + if(BHasPosLeaf) PrimTestTriIndex(b->GetPosPrimitive()); + else _CollideTriBox(b->GetPos()); + + if(ContactFound()) return; + + if(BHasNegLeaf) PrimTestTriIndex(b->GetNegPrimitive()); + else _CollideTriBox(b->GetNeg()); + } + else + { + if(BHasPosLeaf) + { + FETCH_LEAF(b->GetPosPrimitive(), mIMesh1, mR1to0, mT1to0) + + _CollideBoxTri(a->GetPos()); + } + else _Collide(a->GetPos(), b->GetPos()); + + if(ContactFound()) return; + + if(BHasNegLeaf) + { + FETCH_LEAF(b->GetNegPrimitive(), mIMesh1, mR1to0, mT1to0) + + _CollideBoxTri(a->GetPos()); + } + else _Collide(a->GetPos(), b->GetNeg()); + } + + if(ContactFound()) return; + + if(a->HasNegLeaf()) + { + FETCH_LEAF(a->GetNegPrimitive(), mIMesh0, mR0to1, mT0to1) + + if(BHasPosLeaf) PrimTestTriIndex(b->GetPosPrimitive()); + else _CollideTriBox(b->GetPos()); + + if(ContactFound()) return; + + if(BHasNegLeaf) PrimTestTriIndex(b->GetNegPrimitive()); + else _CollideTriBox(b->GetNeg()); + } + else + { + if(BHasPosLeaf) + { + // ### That leaf has possibly already been fetched + FETCH_LEAF(b->GetPosPrimitive(), mIMesh1, mR1to0, mT1to0) + + _CollideBoxTri(a->GetNeg()); + } + else _Collide(a->GetNeg(), b->GetPos()); + + if(ContactFound()) return; + + if(BHasNegLeaf) + { + // ### That leaf has possibly already been fetched + FETCH_LEAF(b->GetNegPrimitive(), mIMesh1, mR1to0, mT1to0) + + _CollideBoxTri(a->GetNeg()); + } + else _Collide(a->GetNeg(), b->GetNeg()); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Quantized trees +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized AABB trees. + * \param b0 [in] collision node from first tree + * \param b1 [in] collision node from second tree + * \param a [in] extent from box A + * \param Pa [in] center from box A + * \param b [in] extent from box B + * \param Pb [in] center from box B + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::_Collide(const AABBQuantizedNode* b0, const AABBQuantizedNode* b1, const Point& a, const Point& Pa, const Point& b, const Point& Pb) +{ + // Perform BV-BV overlap test + if(!BoxBoxOverlap(a, Pa, b, Pb)) return; + + if(b0->IsLeaf() && b1->IsLeaf()) { PrimTest(b0->GetPrimitive(), b1->GetPrimitive()); return; } + + if(b1->IsLeaf() || (!b0->IsLeaf() && (b0->GetSize() > b1->GetSize()))) + { + // Dequantize box + const QuantizedAABB* Box = &b0->GetNeg()->mAABB; + const Point negPa(float(Box->mCenter[0]) * mCenterCoeff0.x, float(Box->mCenter[1]) * mCenterCoeff0.y, float(Box->mCenter[2]) * mCenterCoeff0.z); + const Point nega(float(Box->mExtents[0]) * mExtentsCoeff0.x, float(Box->mExtents[1]) * mExtentsCoeff0.y, float(Box->mExtents[2]) * mExtentsCoeff0.z); + _Collide(b0->GetNeg(), b1, nega, negPa, b, Pb); + + if(ContactFound()) return; + + // Dequantize box + Box = &b0->GetPos()->mAABB; + const Point posPa(float(Box->mCenter[0]) * mCenterCoeff0.x, float(Box->mCenter[1]) * mCenterCoeff0.y, float(Box->mCenter[2]) * mCenterCoeff0.z); + const Point posa(float(Box->mExtents[0]) * mExtentsCoeff0.x, float(Box->mExtents[1]) * mExtentsCoeff0.y, float(Box->mExtents[2]) * mExtentsCoeff0.z); + _Collide(b0->GetPos(), b1, posa, posPa, b, Pb); + } + else + { + // Dequantize box + const QuantizedAABB* Box = &b1->GetNeg()->mAABB; + const Point negPb(float(Box->mCenter[0]) * mCenterCoeff1.x, float(Box->mCenter[1]) * mCenterCoeff1.y, float(Box->mCenter[2]) * mCenterCoeff1.z); + const Point negb(float(Box->mExtents[0]) * mExtentsCoeff1.x, float(Box->mExtents[1]) * mExtentsCoeff1.y, float(Box->mExtents[2]) * mExtentsCoeff1.z); + _Collide(b0, b1->GetNeg(), a, Pa, negb, negPb); + + if(ContactFound()) return; + + // Dequantize box + Box = &b1->GetPos()->mAABB; + const Point posPb(float(Box->mCenter[0]) * mCenterCoeff1.x, float(Box->mCenter[1]) * mCenterCoeff1.y, float(Box->mCenter[2]) * mCenterCoeff1.z); + const Point posb(float(Box->mExtents[0]) * mExtentsCoeff1.x, float(Box->mExtents[1]) * mExtentsCoeff1.y, float(Box->mExtents[2]) * mExtentsCoeff1.z); + _Collide(b0, b1->GetPos(), a, Pa, posb, posPb); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Quantized no-leaf trees +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision of a leaf node from A and a quantized branch from B. + * \param leaf [in] leaf triangle from first tree + * \param b [in] collision node from second tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::_CollideTriBox(const AABBQuantizedNoLeafNode* b) +{ + // Dequantize box + const QuantizedAABB* bb = &b->mAABB; + const Point Pb(float(bb->mCenter[0]) * mCenterCoeff1.x, float(bb->mCenter[1]) * mCenterCoeff1.y, float(bb->mCenter[2]) * mCenterCoeff1.z); + const Point eb(float(bb->mExtents[0]) * mExtentsCoeff1.x, float(bb->mExtents[1]) * mExtentsCoeff1.y, float(bb->mExtents[2]) * mExtentsCoeff1.z); + + // Perform triangle-box overlap test + if(!TriBoxOverlap(Pb, eb)) return; + + if(b->HasPosLeaf()) PrimTestTriIndex(b->GetPosPrimitive()); + else _CollideTriBox(b->GetPos()); + + if(ContactFound()) return; + + if(b->HasNegLeaf()) PrimTestTriIndex(b->GetNegPrimitive()); + else _CollideTriBox(b->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision of a leaf node from B and a quantized branch from A. + * \param b [in] collision node from first tree + * \param leaf [in] leaf triangle from second tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::_CollideBoxTri(const AABBQuantizedNoLeafNode* b) +{ + // Dequantize box + const QuantizedAABB* bb = &b->mAABB; + const Point Pa(float(bb->mCenter[0]) * mCenterCoeff0.x, float(bb->mCenter[1]) * mCenterCoeff0.y, float(bb->mCenter[2]) * mCenterCoeff0.z); + const Point ea(float(bb->mExtents[0]) * mExtentsCoeff0.x, float(bb->mExtents[1]) * mExtentsCoeff0.y, float(bb->mExtents[2]) * mExtentsCoeff0.z); + + // Perform triangle-box overlap test + if(!TriBoxOverlap(Pa, ea)) return; + + if(b->HasPosLeaf()) PrimTestIndexTri(b->GetPosPrimitive()); + else _CollideBoxTri(b->GetPos()); + + if(ContactFound()) return; + + if(b->HasNegLeaf()) PrimTestIndexTri(b->GetNegPrimitive()); + else _CollideBoxTri(b->GetNeg()); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Recursive collision query for quantized no-leaf AABB trees. + * \param a [in] collision node from first tree + * \param b [in] collision node from second tree + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void AABBTreeCollider::_Collide(const AABBQuantizedNoLeafNode* a, const AABBQuantizedNoLeafNode* b) +{ + // Dequantize box A + const QuantizedAABB* ab = &a->mAABB; + const Point Pa(float(ab->mCenter[0]) * mCenterCoeff0.x, float(ab->mCenter[1]) * mCenterCoeff0.y, float(ab->mCenter[2]) * mCenterCoeff0.z); + const Point ea(float(ab->mExtents[0]) * mExtentsCoeff0.x, float(ab->mExtents[1]) * mExtentsCoeff0.y, float(ab->mExtents[2]) * mExtentsCoeff0.z); + // Dequantize box B + const QuantizedAABB* bb = &b->mAABB; + const Point Pb(float(bb->mCenter[0]) * mCenterCoeff1.x, float(bb->mCenter[1]) * mCenterCoeff1.y, float(bb->mCenter[2]) * mCenterCoeff1.z); + const Point eb(float(bb->mExtents[0]) * mExtentsCoeff1.x, float(bb->mExtents[1]) * mExtentsCoeff1.y, float(bb->mExtents[2]) * mExtentsCoeff1.z); + + // Perform BV-BV overlap test + if(!BoxBoxOverlap(ea, Pa, eb, Pb)) return; + + // Catch leaf status + BOOL BHasPosLeaf = b->HasPosLeaf(); + BOOL BHasNegLeaf = b->HasNegLeaf(); + + if(a->HasPosLeaf()) + { + FETCH_LEAF(a->GetPosPrimitive(), mIMesh0, mR0to1, mT0to1) + + if(BHasPosLeaf) PrimTestTriIndex(b->GetPosPrimitive()); + else _CollideTriBox(b->GetPos()); + + if(ContactFound()) return; + + if(BHasNegLeaf) PrimTestTriIndex(b->GetNegPrimitive()); + else _CollideTriBox(b->GetNeg()); + } + else + { + if(BHasPosLeaf) + { + FETCH_LEAF(b->GetPosPrimitive(), mIMesh1, mR1to0, mT1to0) + + _CollideBoxTri(a->GetPos()); + } + else _Collide(a->GetPos(), b->GetPos()); + + if(ContactFound()) return; + + if(BHasNegLeaf) + { + FETCH_LEAF(b->GetNegPrimitive(), mIMesh1, mR1to0, mT1to0) + + _CollideBoxTri(a->GetPos()); + } + else _Collide(a->GetPos(), b->GetNeg()); + } + + if(ContactFound()) return; + + if(a->HasNegLeaf()) + { + FETCH_LEAF(a->GetNegPrimitive(), mIMesh0, mR0to1, mT0to1) + + if(BHasPosLeaf) PrimTestTriIndex(b->GetPosPrimitive()); + else _CollideTriBox(b->GetPos()); + + if(ContactFound()) return; + + if(BHasNegLeaf) PrimTestTriIndex(b->GetNegPrimitive()); + else _CollideTriBox(b->GetNeg()); + } + else + { + if(BHasPosLeaf) + { + // ### That leaf has possibly already been fetched + FETCH_LEAF(b->GetPosPrimitive(), mIMesh1, mR1to0, mT1to0) + + _CollideBoxTri(a->GetNeg()); + } + else _Collide(a->GetNeg(), b->GetPos()); + + if(ContactFound()) return; + + if(BHasNegLeaf) + { + // ### That leaf has possibly already been fetched + FETCH_LEAF(b->GetNegPrimitive(), mIMesh1, mR1to0, mT1to0) + + _CollideBoxTri(a->GetNeg()); + } + else _Collide(a->GetNeg(), b->GetNeg()); + } +} diff --git a/libraries/ode-0.9/OPCODE/OPC_TreeCollider.h b/libraries/ode-0.9/OPCODE/OPC_TreeCollider.h new file mode 100644 index 0000000000..1e943a4bf4 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_TreeCollider.h @@ -0,0 +1,246 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains code for a tree collider. + * \file OPC_TreeCollider.h + * \author Pierre Terdiman + * \date March, 20, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_TREECOLLIDER_H__ +#define __OPC_TREECOLLIDER_H__ + + //! This structure holds cached information used by the algorithm. + //! Two model pointers and two colliding primitives are cached. Model pointers are assigned + //! to their respective meshes, and the pair of colliding primitives is used for temporal + //! coherence. That is, in case temporal coherence is enabled, those two primitives are + //! tested for overlap before everything else. If they still collide, we're done before + //! even entering the recursive collision code. + struct OPCODE_API BVTCache : Pair + { + //! Constructor + inline_ BVTCache() + { + ResetCache(); + ResetCountDown(); + } + + void ResetCache() + { + Model0 = null; + Model1 = null; + id0 = 0; + id1 = 1; +#ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE ! + HullTest = true; + SepVector.pid = 0; + SepVector.qid = 0; + SepVector.SV = Point(1.0f, 0.0f, 0.0f); +#endif // __MESHMERIZER_H__ + } + +#ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE ! + inline_ void ResetCountDown() + { + CountDown = 50; + } +#else + void ResetCountDown(){}; +#endif // __MESHMERIZER_H__ + + const Model* Model0; //!< Model for first object + const Model* Model1; //!< Model for second object + +#ifdef __MESHMERIZER_H__ // Collision hulls only supported within ICE ! + SVCache SepVector; + udword CountDown; + bool HullTest; +#endif // __MESHMERIZER_H__ + }; + + class OPCODE_API AABBTreeCollider : public Collider + { + public: + // Constructor / Destructor + AABBTreeCollider(); + virtual ~AABBTreeCollider(); + // Generic collision query + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Generic collision query for generic OPCODE models. After the call, access the results with: + * - GetContactStatus() + * - GetNbPairs() + * - GetPairs() + * + * \param cache [in] collision cache for model pointers and a colliding pair of primitives + * \param world0 [in] world matrix for first object, or null + * \param world1 [in] world matrix for second object, or null + * \return true if success + * \warning SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + bool Collide(BVTCache& cache, const Matrix4x4* world0=null, const Matrix4x4* world1=null); + + // Collision queries + bool Collide(const AABBCollisionTree* tree0, const AABBCollisionTree* tree1, const Matrix4x4* world0=null, const Matrix4x4* world1=null, Pair* cache=null); + bool Collide(const AABBNoLeafTree* tree0, const AABBNoLeafTree* tree1, const Matrix4x4* world0=null, const Matrix4x4* world1=null, Pair* cache=null); + bool Collide(const AABBQuantizedTree* tree0, const AABBQuantizedTree* tree1, const Matrix4x4* world0=null, const Matrix4x4* world1=null, Pair* cache=null); + bool Collide(const AABBQuantizedNoLeafTree* tree0, const AABBQuantizedNoLeafTree* tree1, const Matrix4x4* world0=null, const Matrix4x4* world1=null, Pair* cache=null); + // Settings + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Settings: selects between full box-box tests or "SAT-lite" tests (where Class III axes are discarded) + * \param flag [in] true for full tests, false for coarse tests + * \see SetFullPrimBoxTest(bool flag) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetFullBoxBoxTest(bool flag) { mFullBoxBoxTest = flag; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Settings: selects between full triangle-box tests or "SAT-lite" tests (where Class III axes are discarded) + * \param flag [in] true for full tests, false for coarse tests + * \see SetFullBoxBoxTest(bool flag) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ void SetFullPrimBoxTest(bool flag) { mFullPrimBoxTest = flag; } + + // Stats + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Stats: gets the number of BV-BV overlap tests after a collision query. + * \see GetNbPrimPrimTests() + * \see GetNbBVPrimTests() + * \return the number of BV-BV tests performed during last query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbBVBVTests() const { return mNbBVBVTests; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Stats: gets the number of Triangle-Triangle overlap tests after a collision query. + * \see GetNbBVBVTests() + * \see GetNbBVPrimTests() + * \return the number of Triangle-Triangle tests performed during last query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbPrimPrimTests() const { return mNbPrimPrimTests; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Stats: gets the number of BV-Triangle overlap tests after a collision query. + * \see GetNbBVBVTests() + * \see GetNbPrimPrimTests() + * \return the number of BV-Triangle tests performed during last query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbBVPrimTests() const { return mNbBVPrimTests; } + + // Data access + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the number of contacts after a collision query. + * \see GetContactStatus() + * \see GetPairs() + * \return the number of contacts / colliding pairs. + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbPairs() const { return mPairs.GetNbEntries()>>1; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the pairs of colliding triangles after a collision query. + * \see GetContactStatus() + * \see GetNbPairs() + * \return the list of colliding pairs (triangle indices) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ const Pair* GetPairs() const { return (const Pair*)mPairs.GetEntries(); } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Validates current settings. You should call this method after all the settings and callbacks have been defined for a collider. + * \return null if everything is ok, else a string describing the problem + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(Collider) const char* ValidateSettings(); + + protected: + // Colliding pairs + Container mPairs; //!< Pairs of colliding primitives + // User mesh interfaces + const MeshInterface* mIMesh0; //!< User-defined mesh interface for object0 + const MeshInterface* mIMesh1; //!< User-defined mesh interface for object1 + // Stats + udword mNbBVBVTests; //!< Number of BV-BV tests + udword mNbPrimPrimTests; //!< Number of Primitive-Primitive tests + udword mNbBVPrimTests; //!< Number of BV-Primitive tests + // Precomputed data + Matrix3x3 mAR; //!< Absolute rotation matrix + Matrix3x3 mR0to1; //!< Rotation from object0 to object1 + Matrix3x3 mR1to0; //!< Rotation from object1 to object0 + Point mT0to1; //!< Translation from object0 to object1 + Point mT1to0; //!< Translation from object1 to object0 + // Dequantization coeffs + Point mCenterCoeff0; + Point mExtentsCoeff0; + Point mCenterCoeff1; + Point mExtentsCoeff1; + // Leaf description + Point mLeafVerts[3]; //!< Triangle vertices + udword mLeafIndex; //!< Triangle index + // Settings + bool mFullBoxBoxTest; //!< Perform full BV-BV tests (true) or SAT-lite tests (false) + bool mFullPrimBoxTest; //!< Perform full Primitive-BV tests (true) or SAT-lite tests (false) + // Internal methods + + // Standard AABB trees + void _Collide(const AABBCollisionNode* b0, const AABBCollisionNode* b1); + // Quantized AABB trees + void _Collide(const AABBQuantizedNode* b0, const AABBQuantizedNode* b1, const Point& a, const Point& Pa, const Point& b, const Point& Pb); + // No-leaf AABB trees + void _CollideTriBox(const AABBNoLeafNode* b); + void _CollideBoxTri(const AABBNoLeafNode* b); + void _Collide(const AABBNoLeafNode* a, const AABBNoLeafNode* b); + // Quantized no-leaf AABB trees + void _CollideTriBox(const AABBQuantizedNoLeafNode* b); + void _CollideBoxTri(const AABBQuantizedNoLeafNode* b); + void _Collide(const AABBQuantizedNoLeafNode* a, const AABBQuantizedNoLeafNode* b); + // Overlap tests + void PrimTest(udword id0, udword id1); + inline_ void PrimTestTriIndex(udword id1); + inline_ void PrimTestIndexTri(udword id0); + + inline_ BOOL BoxBoxOverlap(const Point& ea, const Point& ca, const Point& eb, const Point& cb); + inline_ BOOL TriBoxOverlap(const Point& center, const Point& extents); + inline_ BOOL TriTriOverlap(const Point& V0, const Point& V1, const Point& V2, const Point& U0, const Point& U1, const Point& U2); + // Init methods + void InitQuery(const Matrix4x4* world0=null, const Matrix4x4* world1=null); + bool CheckTemporalCoherence(Pair* cache); + + inline_ BOOL Setup(const MeshInterface* mi0, const MeshInterface* mi1) + { + mIMesh0 = mi0; + mIMesh1 = mi1; + + if(!mIMesh0 || !mIMesh1) return FALSE; + + return TRUE; + } + }; + +#endif // __OPC_TREECOLLIDER_H__ diff --git a/libraries/ode-0.9/OPCODE/OPC_TriBoxOverlap.h b/libraries/ode-0.9/OPCODE/OPC_TriBoxOverlap.h new file mode 100644 index 0000000000..b3a9bdee7c --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_TriBoxOverlap.h @@ -0,0 +1,339 @@ + +//! This macro quickly finds the min & max values among 3 variables +#define FINDMINMAX(x0, x1, x2, min, max) \ + min = max = x0; \ + if(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 Möller, a bit optimized: + * - with some more lazy evaluation (faster path on PC) + * - with a tiny bit of assembly + * - with "SAT-lite" applied if needed + * - and perhaps with some more minor modifs... + * + * \param center [in] box center + * \param extents [in] box extents + * \return true if triangle & box overlap + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +inline_ BOOL AABBTreeCollider::TriBoxOverlap(const Point& center, const Point& extents) +{ + // Stats + mNbBVPrimTests++; + + // use separating axis theorem to test overlap between triangle and box + // need to test for overlap in these directions: + // 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle + // we do not even need to test these) + // 2) normal of the triangle + // 3) crossproduct(edge from tri, {x,y,z}-directin) + // this gives 3x3=9 more tests + + // move everything so that the boxcenter is in (0,0,0) + Point v0, v1, v2; + v0.x = mLeafVerts[0].x - center.x; + v1.x = mLeafVerts[1].x - center.x; + v2.x = mLeafVerts[2].x - center.x; + + // First, test overlap in the {x,y,z}-directions +#ifdef OPC_USE_FCOMI + // find min, max of the triangle in x-direction, and test for overlap in X + if(FCMin3(v0.x, v1.x, v2.x)>extents.x) return FALSE; + if(FCMax3(v0.x, v1.x, v2.x)<-extents.x) return FALSE; + + // same for Y + v0.y = mLeafVerts[0].y - center.y; + v1.y = mLeafVerts[1].y - center.y; + v2.y = mLeafVerts[2].y - center.y; + + if(FCMin3(v0.y, v1.y, v2.y)>extents.y) return FALSE; + if(FCMax3(v0.y, v1.y, v2.y)<-extents.y) return FALSE; + + // same for Z + v0.z = mLeafVerts[0].z - center.z; + v1.z = mLeafVerts[1].z - center.z; + v2.z = mLeafVerts[2].z - center.z; + + if(FCMin3(v0.z, v1.z, v2.z)>extents.z) return FALSE; + if(FCMax3(v0.z, v1.z, v2.z)<-extents.z) return FALSE; +#else + float min,max; + // Find min, max of the triangle in x-direction, and test for overlap in X + FINDMINMAX(v0.x, v1.x, v2.x, min, max); + if(min>extents.x || max<-extents.x) return FALSE; + + // Same for Y + v0.y = mLeafVerts[0].y - center.y; + v1.y = mLeafVerts[1].y - center.y; + v2.y = mLeafVerts[2].y - center.y; + + FINDMINMAX(v0.y, v1.y, v2.y, min, max); + if(min>extents.y || max<-extents.y) return FALSE; + + // Same for Z + v0.z = mLeafVerts[0].z - center.z; + v1.z = mLeafVerts[1].z - center.z; + v2.z = mLeafVerts[2].z - center.z; + + FINDMINMAX(v0.z, v1.z, v2.z, min, max); + if(min>extents.z || max<-extents.z) return FALSE; +#endif + // 2) Test if the box intersects the plane of the triangle + // compute plane equation of triangle: normal*x+d=0 + // ### could be precomputed since we use the same leaf triangle several times + const Point e0 = v1 - v0; + const Point e1 = v2 - v1; + const Point normal = e0 ^ e1; + const float d = -normal|v0; + if(!planeBoxOverlap(normal, d, extents)) return FALSE; + + // 3) "Class III" tests + if(mFullPrimBoxTest) + { + IMPLEMENT_CLASS3_TESTS + } + return TRUE; +} + +//! A dedicated version where the box is constant +inline_ BOOL OBBCollider::TriBoxOverlap() +{ + // Stats + mNbVolumePrimTests++; + + // Hook + const Point& extents = mBoxExtents; + const Point& v0 = mLeafVerts[0]; + const Point& v1 = mLeafVerts[1]; + const Point& v2 = mLeafVerts[2]; + + // use separating axis theorem to test overlap between triangle and box + // need to test for overlap in these directions: + // 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle + // we do not even need to test these) + // 2) normal of the triangle + // 3) crossproduct(edge from tri, {x,y,z}-directin) + // this gives 3x3=9 more tests + + // Box center is already in (0,0,0) + + // First, test overlap in the {x,y,z}-directions +#ifdef OPC_USE_FCOMI + // find min, max of the triangle in x-direction, and test for overlap in X + if(FCMin3(v0.x, v1.x, v2.x)>mBoxExtents.x) return FALSE; + if(FCMax3(v0.x, v1.x, v2.x)<-mBoxExtents.x) return FALSE; + + if(FCMin3(v0.y, v1.y, v2.y)>mBoxExtents.y) return FALSE; + if(FCMax3(v0.y, v1.y, v2.y)<-mBoxExtents.y) return FALSE; + + if(FCMin3(v0.z, v1.z, v2.z)>mBoxExtents.z) return FALSE; + if(FCMax3(v0.z, v1.z, v2.z)<-mBoxExtents.z) return FALSE; +#else + float min,max; + // Find min, max of the triangle in x-direction, and test for overlap in X + FINDMINMAX(v0.x, v1.x, v2.x, min, max); + if(min>mBoxExtents.x || max<-mBoxExtents.x) return FALSE; + + FINDMINMAX(v0.y, v1.y, v2.y, min, max); + if(min>mBoxExtents.y || max<-mBoxExtents.y) return FALSE; + + FINDMINMAX(v0.z, v1.z, v2.z, min, max); + if(min>mBoxExtents.z || max<-mBoxExtents.z) return FALSE; +#endif + // 2) Test if the box intersects the plane of the triangle + // compute plane equation of triangle: normal*x+d=0 + // ### could be precomputed since we use the same leaf triangle several times + const Point e0 = v1 - v0; + const Point e1 = v2 - v1; + const Point normal = e0 ^ e1; + const float d = -normal|v0; + if(!planeBoxOverlap(normal, d, mBoxExtents)) return FALSE; + + // 3) "Class III" tests - here we always do full tests since the box is a primitive (not a BV) + { + IMPLEMENT_CLASS3_TESTS + } + return TRUE; +} + +//! ...and another one, jeez +inline_ BOOL AABBCollider::TriBoxOverlap() +{ + // Stats + mNbVolumePrimTests++; + + // Hook + const Point& center = mBox.mCenter; + const Point& extents = mBox.mExtents; + + // use separating axis theorem to test overlap between triangle and box + // need to test for overlap in these directions: + // 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle + // we do not even need to test these) + // 2) normal of the triangle + // 3) crossproduct(edge from tri, {x,y,z}-directin) + // this gives 3x3=9 more tests + + // move everything so that the boxcenter is in (0,0,0) + Point v0, v1, v2; + v0.x = mLeafVerts[0].x - center.x; + v1.x = mLeafVerts[1].x - center.x; + v2.x = mLeafVerts[2].x - center.x; + + // First, test overlap in the {x,y,z}-directions +#ifdef OPC_USE_FCOMI + // find min, max of the triangle in x-direction, and test for overlap in X + if(FCMin3(v0.x, v1.x, v2.x)>extents.x) return FALSE; + if(FCMax3(v0.x, v1.x, v2.x)<-extents.x) return FALSE; + + // same for Y + v0.y = mLeafVerts[0].y - center.y; + v1.y = mLeafVerts[1].y - center.y; + v2.y = mLeafVerts[2].y - center.y; + + if(FCMin3(v0.y, v1.y, v2.y)>extents.y) return FALSE; + if(FCMax3(v0.y, v1.y, v2.y)<-extents.y) return FALSE; + + // same for Z + v0.z = mLeafVerts[0].z - center.z; + v1.z = mLeafVerts[1].z - center.z; + v2.z = mLeafVerts[2].z - center.z; + + if(FCMin3(v0.z, v1.z, v2.z)>extents.z) return FALSE; + if(FCMax3(v0.z, v1.z, v2.z)<-extents.z) return FALSE; +#else + float min,max; + // Find min, max of the triangle in x-direction, and test for overlap in X + FINDMINMAX(v0.x, v1.x, v2.x, min, max); + if(min>extents.x || max<-extents.x) return FALSE; + + // Same for Y + v0.y = mLeafVerts[0].y - center.y; + v1.y = mLeafVerts[1].y - center.y; + v2.y = mLeafVerts[2].y - center.y; + + FINDMINMAX(v0.y, v1.y, v2.y, min, max); + if(min>extents.y || max<-extents.y) return FALSE; + + // Same for Z + v0.z = mLeafVerts[0].z - center.z; + v1.z = mLeafVerts[1].z - center.z; + v2.z = mLeafVerts[2].z - center.z; + + FINDMINMAX(v0.z, v1.z, v2.z, min, max); + if(min>extents.z || max<-extents.z) return FALSE; +#endif + // 2) Test if the box intersects the plane of the triangle + // compute plane equation of triangle: normal*x+d=0 + // ### could be precomputed since we use the same leaf triangle several times + const Point e0 = v1 - v0; + const Point e1 = v2 - v1; + const Point normal = e0 ^ e1; + const float d = -normal|v0; + if(!planeBoxOverlap(normal, d, extents)) return FALSE; + + // 3) "Class III" tests - here we always do full tests since the box is a primitive (not a BV) + { + IMPLEMENT_CLASS3_TESTS + } + return TRUE; +} diff --git a/libraries/ode-0.9/OPCODE/OPC_TriTriOverlap.h b/libraries/ode-0.9/OPCODE/OPC_TriTriOverlap.h new file mode 100644 index 0000000000..1e71c6a5c1 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_TriTriOverlap.h @@ -0,0 +1,279 @@ + +//! 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]HasPosLeaf()) mTouchedPrimitives->Add(udword(node->GetPosPrimitive())); \ + else _Dump(node->GetPos()); \ + \ + if(ContactFound()) return; \ + \ + if(node->HasNegLeaf()) mTouchedPrimitives->Add(udword(node->GetNegPrimitive())); \ + else _Dump(node->GetNeg()); \ +} + +#define IMPLEMENT_LEAFDUMP(type) \ +void VolumeCollider::_Dump(const type* node) \ +{ \ + if(node->IsLeaf()) \ + { \ + mTouchedPrimitives->Add(udword(node->GetPrimitive())); \ + } \ + else \ + { \ + _Dump(node->GetPos()); \ + \ + if(ContactFound()) return; \ + \ + _Dump(node->GetNeg()); \ + } \ +} + +IMPLEMENT_NOLEAFDUMP(AABBNoLeafNode) +IMPLEMENT_NOLEAFDUMP(AABBQuantizedNoLeafNode) + +IMPLEMENT_LEAFDUMP(AABBCollisionNode) +IMPLEMENT_LEAFDUMP(AABBQuantizedNode) diff --git a/libraries/ode-0.9/OPCODE/OPC_VolumeCollider.h b/libraries/ode-0.9/OPCODE/OPC_VolumeCollider.h new file mode 100644 index 0000000000..c0b812e7da --- /dev/null +++ b/libraries/ode-0.9/OPCODE/OPC_VolumeCollider.h @@ -0,0 +1,138 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/** + * Contains base volume collider class. + * \file OPC_VolumeCollider.h + * \author Pierre Terdiman + * \date June, 2, 2001 + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Include Guard +#ifndef __OPC_VOLUMECOLLIDER_H__ +#define __OPC_VOLUMECOLLIDER_H__ + + struct OPCODE_API VolumeCache + { + VolumeCache() : Model(null) {} + ~VolumeCache() {} + + Container TouchedPrimitives; //!< Indices of touched primitives + const BaseModel* Model; //!< Owner + }; + + class OPCODE_API VolumeCollider : public Collider + { + public: + // Constructor / Destructor + VolumeCollider(); + virtual ~VolumeCollider() = 0; + + // Collision report + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the number of touched primitives after a collision query. + * \see GetContactStatus() + * \see GetTouchedPrimitives() + * \return the number of touched primitives + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbTouchedPrimitives() const { return mTouchedPrimitives ? mTouchedPrimitives->GetNbEntries() : 0; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Gets the list of touched primitives after a collision query. + * \see GetContactStatus() + * \see GetNbTouchedPrimitives() + * \return the list of touched primitives (primitive indices) + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ const udword* GetTouchedPrimitives() const { return mTouchedPrimitives ? mTouchedPrimitives->GetEntries() : null; } + + // Stats + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Stats: gets the number of Volume-BV overlap tests after a collision query. + * \see GetNbVolumePrimTests() + * \return the number of Volume-BV tests performed during last query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbVolumeBVTests() const { return mNbVolumeBVTests; } + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Stats: gets the number of Volume-Triangle overlap tests after a collision query. + * \see GetNbVolumeBVTests() + * \return the number of Volume-Triangle tests performed during last query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + inline_ udword GetNbVolumePrimTests() const { return mNbVolumePrimTests; } + + // Settings + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Validates current settings. You should call this method after all the settings / callbacks have been defined for a collider. + * \return null if everything is ok, else a string describing the problem + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(Collider) const char* ValidateSettings(); + + protected: + // Touched primitives + Container* mTouchedPrimitives; //!< List of touched primitives + + // Dequantization coeffs + Point mCenterCoeff; + Point mExtentsCoeff; + // Stats + udword mNbVolumeBVTests; //!< Number of Volume-BV tests + udword mNbVolumePrimTests; //!< Number of Volume-Primitive tests + // Internal methods + void _Dump(const AABBCollisionNode* node); + void _Dump(const AABBNoLeafNode* node); + void _Dump(const AABBQuantizedNode* node); + void _Dump(const AABBQuantizedNoLeafNode* node); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Initializes a query + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + override(Collider) inline_ void InitQuery() + { + // Reset stats & contact status + mNbVolumeBVTests = 0; + mNbVolumePrimTests = 0; + Collider::InitQuery(); + } + + inline_ BOOL IsCacheValid(VolumeCache& cache) + { + // We're going to do a volume-vs-model query. + if(cache.Model!=mCurrentModel) + { + // Cached list was for another model so we can't keep it + // Keep track of new owner and reset cache + cache.Model = mCurrentModel; + return FALSE; + } + else + { + // Same models, no problem + return TRUE; + } + } + }; + +#endif // __OPC_VOLUMECOLLIDER_H__ diff --git a/libraries/ode-0.9/OPCODE/Opcode.cpp b/libraries/ode-0.9/OPCODE/Opcode.cpp new file mode 100644 index 0000000000..c9fa104e0f --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Opcode.cpp @@ -0,0 +1,65 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * 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" + +bool Opcode::InitOpcode() +{ + Log("// Initializing OPCODE\n\n"); +// LogAPIInfo(); + return true; +} + +void ReleasePruningSorters(); +bool Opcode::CloseOpcode() +{ + Log("// Closing OPCODE\n\n"); + + ReleasePruningSorters(); + + return true; +} + +#ifdef ICE_MAIN + +void ModuleAttach(HINSTANCE hinstance) +{ +} + +void ModuleDetach() +{ +} + +#endif diff --git a/libraries/ode-0.9/OPCODE/Opcode.dsp b/libraries/ode-0.9/OPCODE/Opcode.dsp new file mode 100644 index 0000000000..560cf56c8e --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Opcode.dsp @@ -0,0 +1,470 @@ +# Microsoft Developer Studio Project File - Name="OPCODE" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=OPCODE - 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 "Opcode.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 "Opcode.mak" CFG="OPCODE - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "OPCODE - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "OPCODE - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName ""$/TR4/ODE/VC6", WNKAAAAA" +# PROP Scc_LocalPath "..\vc6" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "OPCODE - 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 "Release" +# PROP Intermediate_Dir "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 /G6 /Zp4 /MD /O2 /Ob0 /I ".\\" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "ICE_NO_DLL" /FD /c +# SUBTRACT CPP /Fr /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /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\OPCODE.lib" + +!ELSEIF "$(CFG)" == "OPCODE - 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 "Debug" +# PROP Intermediate_Dir "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 /G6 /Zp4 /MDd /Gm /ZI /Od /I ".\\" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "ICE_NO_DLL" /FR /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /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\OPCODE_D.lib" + +!ENDIF + +# Begin Target + +# Name "OPCODE - Win32 Release" +# Name "OPCODE - Win32 Debug" +# Begin Source File + +SOURCE=.\Ice\IceAABB.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceAABB.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceAxes.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceBoundingSphere.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceContainer.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceContainer.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceFPU.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceHPoint.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceHPoint.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceIndexedTriangle.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceIndexedTriangle.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceLSS.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceMatrix3x3.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceMatrix3x3.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceMatrix4x4.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceMatrix4x4.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceMemoryMacros.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceOBB.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceOBB.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IcePairs.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IcePlane.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IcePlane.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IcePoint.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IcePoint.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IcePreprocessor.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceRandom.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceRandom.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceRay.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceRay.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceRevisitedRadix.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceRevisitedRadix.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceSegment.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceSegment.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceTriangle.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceTriangle.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceTrilist.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceTypes.h +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\Ice\IceUtils.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_AABBCollider.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_AABBCollider.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_AABBTree.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_AABBTree.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_BaseModel.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_BaseModel.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_BoxBoxOverlap.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_BoxPruning.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_BoxPruning.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_Collider.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_Collider.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_Common.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_Common.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_HybridModel.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_HybridModel.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_IceHook.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_LSSAABBOverlap.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_LSSCollider.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_LSSCollider.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_LSSTriOverlap.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_MeshInterface.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_MeshInterface.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_Model.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_Model.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_OBBCollider.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_OBBCollider.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_OptimizedTree.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_OptimizedTree.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_Picking.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_Picking.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_PlanesAABBOverlap.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_PlanesCollider.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_PlanesCollider.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_PlanesTriOverlap.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_RayAABBOverlap.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_RayCollider.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_RayCollider.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_RayTriOverlap.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_Settings.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_SphereAABBOverlap.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_SphereCollider.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_SphereCollider.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_SphereTriOverlap.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_SweepAndPrune.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_SweepAndPrune.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_TreeBuilders.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_TreeBuilders.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_TreeCollider.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_TreeCollider.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_TriBoxOverlap.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_TriTriOverlap.h +# End Source File +# Begin Source File + +SOURCE=.\OPC_VolumeCollider.cpp +# End Source File +# Begin Source File + +SOURCE=.\OPC_VolumeCollider.h +# End Source File +# Begin Source File + +SOURCE=.\Opcode.cpp +# End Source File +# Begin Source File + +SOURCE=.\Opcode.h +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Target +# End Project diff --git a/libraries/ode-0.9/OPCODE/Opcode.dsw b/libraries/ode-0.9/OPCODE/Opcode.dsw new file mode 100644 index 0000000000..27f5c28d4e --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Opcode.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "OPCODE"=.\Opcode.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/libraries/ode-0.9/OPCODE/Opcode.h b/libraries/ode-0.9/OPCODE/Opcode.h new file mode 100644 index 0000000000..2a7a6c5a3e --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Opcode.h @@ -0,0 +1,113 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * 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_IceHook.h" + + namespace Opcode + { + // Bulk-of-the-work + #include "OPC_Settings.h" + #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" + // Sweep-and-prune + #include "OPC_BoxPruning.h" + #include "OPC_SweepAndPrune.h" + + FUNCTION OPCODE_API bool InitOpcode(); + FUNCTION OPCODE_API bool CloseOpcode(); + } + +#endif // __OPCODE_H__ diff --git a/libraries/ode-0.9/OPCODE/README-ODE.txt b/libraries/ode-0.9/OPCODE/README-ODE.txt new file mode 100644 index 0000000000..c5d5800952 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/README-ODE.txt @@ -0,0 +1,13 @@ + +This is a copy of the OPCODE collision detection library by Pierre Terdiman. +See http://www.codercorner.com/Opcode.htm for more information, and read +the ReadMe.txt in this directory. + +If you want to use the TriList (triangle mesh) geometry class in ODE, the +OPCODE library must be compiled. If you are using the autotools support to +compile ODE, you just have to specify --with-trimesh=opcode when calling ./configure. + +This code was originally written for and compiled on windows, but it has been +ported so that it should compile under unix/gcc too. Your mileage may vary. + +Russ Smith, April 12 2005. diff --git a/libraries/ode-0.9/OPCODE/ReadMe.txt b/libraries/ode-0.9/OPCODE/ReadMe.txt new file mode 100644 index 0000000000..8a39eff436 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/ReadMe.txt @@ -0,0 +1,171 @@ + + OPCODE distribution 1.3 (june 2003) + ----------------------- + + New in Opcode 1.3: + - fixed the divide by 0 bug that was happening when all centers where located on a coordinate axis (thanks to Jorrit T) + - linearized "complete" vanilla AABB trees + - ANSI-compliant "for" loops (for the ones porting it to Linux...) + - callbacks & pointers moved to mesh interface + - support for triangle & vertex strides + - optimized the sphere-triangle overlap code a bit + - dynamic trees (refit) + - more builders + - ValidateSubdivision in builders + - LSS collider + - primitive-bv tests can now be skipped in most volume queries + - temporal coherence now also works for airborne objects + - temporal coherence completed for boxes / all contacts, LSS, etc + - ray-collider now uses a callback + - some common "usages" have been introduced (only picking for now) + - SPLIT_COMPLETE removed (now implicitely using mLimit = 1) + - hybrid collision models + - sweep-and-prune code added, moved from my old Z-Collide lib + - it now works with meshes made of only 1 triangle (except in mesh-mesh case!) + + Disclaimer: + + - I forced myself to actually *do* the release today no matter what. Else it would never have been done. That's + why the code may not be very polished. I also removed a *lot* of things (more usages, distance queries, etc...) + that weren't ready for prime-time (or that were linked to too many of my supporting libs) + + - Some comments may also be obsolete here and there. The old User Manual for Opcode 1.2 may not fit version 1.3 + either, since there's a new "mesh interface" to support strides, etc. + + - Everything in the "Ice" directory has been hacked out of my engine and edited until everything compiled. Don't + expect anything out there to be cute or something. In particular, some CPP files are not even included when not + needed, so you can expect some linker errors if you try messing around with them... + + Otherwise, it should be just like previous version, only better. In particular, hybrid models can be very + memory-friendly (sometimes using like 10 times less ram than the best trees from version 1.2). The possible + speed hit is often invisible (if it even exists), especially using temporal coherence in "all contacts" mode. + (Admittedly, this depends on your particular usage pattern / what you do on collided triangles). + + The sweep-and-prune code is similar to the "vanilla" version found in V-Collide (but that one's better IMHO...) + The simple "radix" version is often just as good, see for yourself. + + OPCODE distribution 1.2 (august 2002) + ----------------------- + + New in Opcode 1.2: + - new VolumeCollider base class + - simplified callback setup + - you can now use callbacks or pointers (setup at compile time) + - destination array not needed anymore in the RayCollider (faster in-out tests) + - renamed classes: AABBRayCollider => RayCollider, AABBSphereCollider => SphereCollider + - the sphere query now only returns a list of faces (extra info discarded). On the other hand it's a lot faster. + - OBB, AABB and planes queries. Original OBB and AABB queries contributed by Erwin de Vries. + - cosmetic changes in OPC_BoxBoxOverlap.h contributed by Gottfried Chen + - some inlining problems fixed + - faster ray-mesh tests using the separating axis theorem + - new split value in AABB tree construction (contributed by Igor Kravtchenko). Provides faster queries most of the time. + - improved temporal coherence for sphere & AABB queries (works in "All contacts" mode) + + Notes: + + - Everything in the "Ice code" directory (in VC++) is basically copy-pasted from my engine, with a lot + of code removed until there was no link error anymore. Don't expect those files to be cute or anything, + they've never been meant to be released and they're often updated/modified/messy. + - Some experimental features have been removed as well. Else I would never have released the 1.2... + - Not as polished/optimal as I would like it to be, but that's life. I promised myself to release it + before october 2002 (one YEAR later ?!).... That's the only reason why it's there. + - Some people reported ColDet was faster. Uh, come on. They were using Opcode in + "All contacts" mode whereas ColDet was doing "first contact"... + + OPCODE distribution 1.1 (october 2001) + ----------------------- + + New in Opcode 1.1: + - stabbing queries + - sphere queries + - abtract base class for colliders + - settings validation methods + - compilation flags now grouped in OPC_Settings.h + - smaller files, new VC++ virtual dirs (cleaner) + + Notes: + + - "override(baseclass)" is a personal cosmetic thing. It's the same as "virtual", but provides more info. + - I code in 1600*1200, so some lines may look a bit long.. + - This version is not as polished as the previous one due to lack of time. The stabbing & sphere queries + can still be optimized: for example by trying other atomic overlap tests. I'm using my first ray-AABB + code, but the newer one seems better. Tim Schröder's one is good as well. See: www.codercorner.com/RayAABB.cpp + - The trees can easily be compressed even more, I save this for later (lack of time, lack of time!) + - I removed various tests before releasing this one: + - a separation line, a.k.a. "front" in QuickCD, because gains were unclear + - distance queries in a PQP style, because it was way too slow + - support for deformable models, too slow as well + - You can easily use Opcode to do your player-vs-world collision detection, in a Nettle/Telemachos way. + If someone out there wants to donate some art / level for the cause, I'd be glad to release a demo. (current + demo uses copyrighted art I'm not allowed to spread) + - Sorry for the lack of real docs and/or solid examples. I just don't have enough time. + + OPCODE distribution 1.0 (march 2001) + ----------------------- + + - First release + + =============================================================================== + + WHAT ? + + OPCODE means OPtimized COllision DEtection. + So this is a collision detection package similar to RAPID. Here's a + quick list of features: + + - C++ interface, developed for Windows systems using VC++ 6.0 + - Works on arbitrary meshes (convex or non-convex), even polygon soups + - Current implementation uses AABB-trees + - Introduces Primitive-BV overlap tests during recursive collision queries (whereas + standard libraries only rely on Primitive-Primitive and BV-BV tests) + - Introduces no-leaf trees, i.e. collision trees whose leaf nodes have been removed + - Supports collision queries on quantized trees (decompressed on-the-fly) + - Supports "first contact" or "all contacts" modes (ŕ la RAPID) + - Uses temporal coherence for "first contact" mode (~10 to 20 times faster, useful + in rigid body simulation during bisection) + - Memory footprint is 7.2 times smaller than RAPID's one, which is ideal for console + games with limited ram (actually, if you use the unmodified RAPID code using double + precision, it's more like 13 times smaller...) + - And yet it often runs faster than RAPID (according to RDTSC, sometimes more than 5 + times faster when objects are deeply overlapping) + - Performance is usually close to RAPID's one in close-proximity situations + - Stabbing, planes & volume queries (sphere, AABB, OBB, LSS) + - Sweep-and-prune + - Now works with deformable meshes + - Hybrid trees + + + What it can be used for: + - standard mesh-mesh collision detection (similar to RAPID, SOLID, QuickCD, PQP, ColDet...) + - N-body collisions (similar to V-Collide) + - camera-vs-world collisions (similar to Telemachos/Paul Nettle/Stan Melax articles) + - shadow feelers to speed up lightmap computations + - in-out tests to speed up voxelization processes + - picking + - rigid body simulation + - view frustum culling + - etc + + WHY ? + + - Because RAPID uses too many bytes. + - Because the idea was nice... + + WHEN ? + + It's been coded in march 2001 following a thread on the GD-Algorithms list. + + GDAlgorithms-list mailing list + GDAlgorithms-list@lists.sourceforge.net + http://lists.sourceforge.net/lists/listinfo/gdalgorithms-list + + WHO ? + + Pierre Terdiman + June, 1, 2003 + + p.terdiman@wanadoo.fr + p.terdiman@codercorner.com + + http://www.codercorner.com + http://www.codercorner.com/Opcode.htm diff --git a/libraries/ode-0.9/OPCODE/StdAfx.cpp b/libraries/ode-0.9/OPCODE/StdAfx.cpp new file mode 100644 index 0000000000..9c381f6cec --- /dev/null +++ b/libraries/ode-0.9/OPCODE/StdAfx.cpp @@ -0,0 +1,10 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//#define ICE_MAIN +#include "Stdafx.h" diff --git a/libraries/ode-0.9/OPCODE/Stdafx.h b/libraries/ode-0.9/OPCODE/Stdafx.h new file mode 100644 index 0000000000..0223a6ca0e --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Stdafx.h @@ -0,0 +1,24 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +/* + * OPCODE - Optimized Collision Detection + * Copyright (C) 2001 Pierre Terdiman + * Homepage: http://www.codercorner.com/Opcode.htm + */ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_STDAFX_H__EFB95044_1D31_11D5_8B0F_0050BAC83302__INCLUDED_) +#define AFX_STDAFX_H__EFB95044_1D31_11D5_8B0F_0050BAC83302__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +// Insert your headers here +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +#include "Opcode.h" + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__EFB95044_1D31_11D5_8B0F_0050BAC83302__INCLUDED_) diff --git a/libraries/ode-0.9/OPCODE/TemporalCoherence.txt b/libraries/ode-0.9/OPCODE/TemporalCoherence.txt new file mode 100644 index 0000000000..fb8593188d --- /dev/null +++ b/libraries/ode-0.9/OPCODE/TemporalCoherence.txt @@ -0,0 +1,32 @@ + +> Hi John, +> +> I know I'll forget to tell you this if I don't write it right now.... +> +> >(2) How is the receiving geometry for the shadow decided? +> +> I wrote about an LSS-test but actually performing a new VFC test (from the +> light's view) is the same. In both cases, here's a trick to take advantage +> of temporal coherence : test the world against a slightly larger than +> necessary LSS or frustum. Keep the list of touched surfaces. Then next +> frame, if the new volume is still contained within the previous one used +for +> the query, you can reuse the same list immediately. Actually it's a bit +> similar to what you did in your sphere-tree, I think. Anyway, now the +O(log +> N) VFC is O(1) for some frames. It's not worth it for the "real" VFC, but +> when you have N virtual frustum to test to drop N shadows, that's another +> story. +> +> Two downsides: +> - You need more ram to keep track of one list of meshes / shadow, but +> usually it's not a lot. +> - By using a larger volume for the query you possibly touch more +> faces/surfaces, which will be rendered in the shadow pass. Usually it's +not +> a problem either since rendering is simply faster than geometric queries +> those days. But of course, "your mileage may vary". +> +> Happy new year ! +> +> Pierre diff --git a/libraries/ode-0.9/README.txt b/libraries/ode-0.9/README.txt new file mode 100644 index 0000000000..c9275f9f40 --- /dev/null +++ b/libraries/ode-0.9/README.txt @@ -0,0 +1,41 @@ +The 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. + diff --git a/libraries/ode-0.9/aclocal.m4 b/libraries/ode-0.9/aclocal.m4 new file mode 100644 index 0000000000..b8cf9cd5a5 --- /dev/null +++ b/libraries/ode-0.9/aclocal.m4 @@ -0,0 +1,874 @@ +# generated automatically by aclocal 1.10 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 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. + +# 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_if(m4_PACKAGE_VERSION, [2.61],, +[m4_fatal([this file was generated for autoconf 2.61. +You have another version of autoconf. If you want to use that, +you should regenerate the build system entirely.], [63])]) + +# Copyright (C) 2002, 2003, 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_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], [], + [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 AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.10])dnl +_AM_AUTOCONF_VERSION(m4_PACKAGE_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 +# 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_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[for mf in $CONFIG_FILES; 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 10q "$mf" | grep '^#.*generated by automake' > /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"]) +]) + +# 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 8 + +# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. +AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 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 12 + +# 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_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $1 | $1:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $1" >`AS_DIRNAME([$1])`/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 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_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], +[AC_FOREACH([_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 outputing 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 + diff --git a/libraries/ode-0.9/autogen.sh b/libraries/ode-0.9/autogen.sh new file mode 100755 index 0000000000..68a9759a5c --- /dev/null +++ b/libraries/ode-0.9/autogen.sh @@ -0,0 +1,42 @@ +#!/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.8.2 or later" +echo "Warnings about underquoted definitions are harmless" + +echo "Running aclocal" +aclocal -I . || exit 1 +echo "Running autoheader" +autoheader || exit 1 +echo "Running automake" +automake --foreign --include-deps --add-missing --copy || exit 1 +echo "Running autoconf" +autoconf || exit 1 + +#./configure $* + +echo "Now you are ready to run ./configure" diff --git a/libraries/ode-0.9/build/README.txt b/libraries/ode-0.9/build/README.txt new file mode 100644 index 0000000000..853cc0da51 --- /dev/null +++ b/libraries/ode-0.9/build/README.txt @@ -0,0 +1,44 @@ +Premake-based Windows Build System +Contributed by Jason Perkins (jason379@users.sourceforge.net) +------------------------------------------------------------------- + + SVN USERS: Before using these project files you must copy + config-default.h to ode/include/ode/config.h (or run Premake to + generate a new set of project files, see below). + + +ABOUT THESE FILES + + These project files are automatically generated using a tool called + Premake, available from http://premake.sourceforge.net/. The scripts + used to build them have the ".lua" file extension. To regenerate the + stock project files for inclusion in a new release, type: + + premake --makeall + + +CREATING CUSTOM PROJECT FILES + + To create a set of custom project files, first type `premake --help` + to see the options that you have available. Then generate the new + project files using the form: + + premake [options] --target [toolset] + + For instance: + + premake --no-trimesh --target vs2005 + + To build the test applications and Drawstuff library, use the form: + + premake --with-tests --target [toolset] + + If you ever decide that you want to remove your custom project, you + can just type: + + premake --with-tests --clean + + Feel free to direct any questions or comments to myself or the ODE + mailing list. + + diff --git a/libraries/ode-0.9/build/config-default.h b/libraries/ode-0.9/build/config-default.h new file mode 100644 index 0000000000..7d64006b2c --- /dev/null +++ b/libraries/ode-0.9/build/config-default.h @@ -0,0 +1,176 @@ +/* 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. + * + * dSINGLE/dDOUBLE - force ODE to use single-precision (float) + * or double-precision (double) for numbers. + * Only one should be defined. + * + * 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. + * + * 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. + * + ******************************************************************/ + +#define dSINGLE +/* #define dDOUBLE */ + +#define dTRIMESH_ENABLED 1 +#define dTRIMESH_OPCODE 1 + +#define dTRIMESH_OPCODE_USE_NEW_TRIMESH_TRIMESH_COLLIDER 0 + +/* #define dUSE_MALLOC_FOR_ALLOCA */ + + +/****************************************************************** + * 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 + + +/* Define a DLL export symbol for those platforms that need it */ +#if defined(ODE_PLATFORM_WINDOWS) + #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 + + +/* Pull in the standard headers */ +#include +#include +#include +#include +#include +#include + +#if !defined(ODE_PLATFORM_PS3) + #include +#endif + +#if !defined(ODE_PLATFORM_WINDOWS) + #include +#endif + + +/* Visual C does not define these functions */ +#if defined(_MSC_VER) + #define copysignf _copysign + #define copysign _copysign +#endif + + +/* Define a value for infinity */ +#if defined(HUGE_VALF) + #define ODE_INFINITY4 HUGE_VALF + #define ODE_INFINITY8 HUGE_VAL +#elif defined(FLT_MAX) + #define ODE_INFINITY4 FLT_MAX + #define ODE_INFINITY8 DBL_MAX +#else + static union { unsigned char __c[4]; float __f; } __ode_huge_valf = {{0,0,0x80,0x7f}}; + static union { unsigned char __c[8]; double __d; } __ode_huge_val = {{0,0,0,0,0,0,0xf0,0x7f}}; + #define ODE_INFINITY4 (__ode_huge_valf.__f) + #define ODE_INFINITY8 (__ode_huge_val.__d) +#endif + +#ifdef dSINGLE + #define dInfinity ODE_INFINITY4 + #define dEpsilon FLT_EPSILON +#else + #define dInfinity ODE_INFINITY8 + #define dEpsilon DBL_EPSILON +#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 + +/* 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 + + +/* Define this if your system supports anonymous memory maps (linux does) */ +#define MMAP_ANONYMOUS + +#endif diff --git a/libraries/ode-0.9/build/demos.lua b/libraries/ode-0.9/build/demos.lua new file mode 100644 index 0000000000..4752ba64c9 --- /dev/null +++ b/libraries/ode-0.9/build/demos.lua @@ -0,0 +1,88 @@ +-- Here are the lists of demos to build. Add/remove new +-- demos here and everything else should just work + + local demos = + { + "boxstack", + "buggy", + "chain1", + "chain2", + "collision", + "crash", + "feedback", + "friction", + "heightfield", + "hinge", + "I", + "jointsPR", + "joints", + "motor", + "ode", + "plane2d", + "slider", + "space", + "space_stress", + "step" + } + + if (not options["no-trimesh"]) then + table.insert(demos, "basket") + if (not options["no-cylinder"]) then + table.insert(demos, "cyl") + end + table.insert(demos, "moving_trimesh") + table.insert(demos, "trimesh") + end + + if (not options["no-cylinder"]) then + table.insert(demos, "cylvssphere") + end + + +-- Separate distribution files into toolset subdirectories + + if (options["usetargetpath"]) then + packagepath = options["target"] + else + packagepath = "custom" + end + + +-- Factory function for demo packages + + function makedemo(index, name) + package = newpackage() + package.name = "demo_" .. name + package.kind = "exe" + package.language = "c++" + package.path = packagepath + package.objdir = "obj/"..name + + package.includepaths = { "../../include" } + package.defines = { "_CRT_SECURE_NO_DEPRECATE" } + + if (options.target == "vs6" or options.target == "vs2002" or options.target == "vs2003") then + package.config.DebugLib.buildflags = { "static-runtime" } + package.config.ReleaseLib.buildflags = { "static-runtime" } + end + + package.links = { "ode", "drawstuff" } + if (windows) then + table.insert(package.links, { "user32", "winmm", "gdi32", "opengl32", "glu32" }) + else + table.insert(package.links, { "GL", "GLU" }) + end + + if (name == "chain1") then + package.files = { "../../ode/demo/demo_" .. name .. ".c" } + else + package.files = { "../../ode/demo/demo_" .. name .. ".cpp" } + end + + if (windows) then + table.insert(package.defines, "WIN32") + table.insert(package.files, "../../drawstuff/src/resources.rc") + end + end + + table.foreach(demos, makedemo) diff --git a/libraries/ode-0.9/build/drawstuff.lua b/libraries/ode-0.9/build/drawstuff.lua new file mode 100644 index 0000000000..c36b35006e --- /dev/null +++ b/libraries/ode-0.9/build/drawstuff.lua @@ -0,0 +1,112 @@ +package.name = "drawstuff" +package.language = "c++" +package.objdir = "obj/drawstuff" + + +-- Separate distribution files into toolset subdirectories + + if (options["usetargetpath"]) then + package.path = options["target"] + else + package.path = "custom" + end + + +-- Package Build Settings + + local dll_defines = + { + "DS_DLL", + "USRDLL" + } + + local lib_defines = + { + "DS_LIB" + } + + if (options["enable-shared-only"]) then + package.kind = "dll" + table.insert(package.defines, dll_defines) + elseif (options["enable-static-only"]) then + package.kind = "lib" + table.insert(package.defines, lib_defines) + else + package.config["DebugDLL"].kind = "dll" + package.config["DebugLib"].kind = "lib" + package.config["ReleaseDLL"].kind = "dll" + package.config["ReleaseLib"].kind = "lib" + + table.insert(package.config["DebugDLL"].defines, dll_defines) + table.insert(package.config["ReleaseDLL"].defines, dll_defines) + table.insert(package.config["DebugLib"].defines, lib_defines) + table.insert(package.config["ReleaseLib"].defines, lib_defines) + end + + package.includepaths = + { + "../../include" + } + + -- disable VS2005 CRT security warnings + if (options["target"] == "vs2005") then + table.insert(package.defines, "_CRT_SECURE_NO_DEPRECATE") + end + + +-- Build Flags + + package.config["DebugLib"].buildflags = { } + package.config["DebugDLL"].buildflags = { } + + package.config["ReleaseDLL"].buildflags = { "optimize-speed", "no-symbols", "no-frame-pointer" } + package.config["ReleaseLib"].buildflags = { "optimize-speed", "no-symbols", "no-frame-pointer" } + + if (options.target == "vs6" or options.target == "vs2002" or options.target == "vs2003") then + table.insert(package.config.DebugLib.buildflags, "static-runtime") + table.insert(package.config.ReleaseLib.buildflags, "static-runtime") + end + + +-- Libraries + + local windows_libs = + { + "user32", + "opengl32", + "glu32", + "winmm", + "gdi32" + } + + local x11_libs = + { + "X11", + "GL", + "GLU" + } + + if (windows) then + table.insert(package.links, windows_libs) + else + table.insert(package.links, x11_libs) + end + + +-- Files + + package.files = + { + matchfiles("../../include/drawstuff/*.h"), + "../../drawstuff/src/internal.h", + "../../drawstuff/src/drawstuff.cpp" + } + + if (windows) then + table.insert(package.defines, "WIN32") + table.insert(package.files, "../../drawstuff/src/resource.h") + table.insert(package.files, "../../drawstuff/src/resources.rc") + table.insert(package.files, "../../drawstuff/src/windows.cpp") + else + table.insert(package.files, "../../drawstuff/src/x11.cpp") + end diff --git a/libraries/ode-0.9/build/gnu/Makefile b/libraries/ode-0.9/build/gnu/Makefile new file mode 100644 index 0000000000..e392a26c4e --- /dev/null +++ b/libraries/ode-0.9/build/gnu/Makefile @@ -0,0 +1,155 @@ +# Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` +# Options: +# CONFIG=[DebugDLL|ReleaseDLL|DebugLib|ReleaseLib] + +ifndef CONFIG + CONFIG=DebugDLL +endif + +export CONFIG + +.PHONY: all clean ode drawstuff demo_boxstack demo_buggy demo_chain1 demo_chain2 demo_collision demo_crash demo_feedback demo_friction demo_heightfield demo_hinge demo_I demo_joints demo_motor demo_ode demo_plane2d demo_slider demo_space demo_space_stress demo_step demo_basket demo_cyl demo_moving_trimesh demo_trimesh demo_cylvssphere tests + +all: ode drawstuff demo_boxstack demo_buggy demo_chain1 demo_chain2 demo_collision demo_crash demo_feedback demo_friction demo_heightfield demo_hinge demo_I demo_joints demo_motor demo_ode demo_plane2d demo_slider demo_space demo_space_stress demo_step demo_basket demo_cyl demo_moving_trimesh demo_trimesh demo_cylvssphere tests + +Makefile: ../premake.lua ../ode.lua ../drawstuff.lua ../demos.lua ../demos.lua ../demos.lua ../demos.lua ../demos.lua ../demos.lua ../demos.lua ../demos.lua ../demos.lua ../demos.lua ../demos.lua ../demos.lua ../demos.lua ../demos.lua ../demos.lua ../demos.lua ../demos.lua ../demos.lua ../demos.lua ../demos.lua ../demos.lua ../demos.lua ../demos.lua ../demos.lua ../tests.lua + @echo ==== Regenerating Makefiles ==== + @premake --file $^ --usetargetpath --with-demos --with-tests --clean --target gnu + +ode: + @echo ==== Building ode ==== + @$(MAKE) --no-print-directory -C . -f ode.make + +drawstuff: + @echo ==== Building drawstuff ==== + @$(MAKE) --no-print-directory -C . -f drawstuff.make + +demo_boxstack: ode drawstuff + @echo ==== Building demo_boxstack ==== + @$(MAKE) --no-print-directory -C . -f demo_boxstack.make + +demo_buggy: ode drawstuff + @echo ==== Building demo_buggy ==== + @$(MAKE) --no-print-directory -C . -f demo_buggy.make + +demo_chain1: ode drawstuff + @echo ==== Building demo_chain1 ==== + @$(MAKE) --no-print-directory -C . -f demo_chain1.make + +demo_chain2: ode drawstuff + @echo ==== Building demo_chain2 ==== + @$(MAKE) --no-print-directory -C . -f demo_chain2.make + +demo_collision: ode drawstuff + @echo ==== Building demo_collision ==== + @$(MAKE) --no-print-directory -C . -f demo_collision.make + +demo_crash: ode drawstuff + @echo ==== Building demo_crash ==== + @$(MAKE) --no-print-directory -C . -f demo_crash.make + +demo_feedback: ode drawstuff + @echo ==== Building demo_feedback ==== + @$(MAKE) --no-print-directory -C . -f demo_feedback.make + +demo_friction: ode drawstuff + @echo ==== Building demo_friction ==== + @$(MAKE) --no-print-directory -C . -f demo_friction.make + +demo_heightfield: ode drawstuff + @echo ==== Building demo_heightfield ==== + @$(MAKE) --no-print-directory -C . -f demo_heightfield.make + +demo_hinge: ode drawstuff + @echo ==== Building demo_hinge ==== + @$(MAKE) --no-print-directory -C . -f demo_hinge.make + +demo_I: ode drawstuff + @echo ==== Building demo_I ==== + @$(MAKE) --no-print-directory -C . -f demo_I.make + +demo_joints: ode drawstuff + @echo ==== Building demo_joints ==== + @$(MAKE) --no-print-directory -C . -f demo_joints.make + +demo_motor: ode drawstuff + @echo ==== Building demo_motor ==== + @$(MAKE) --no-print-directory -C . -f demo_motor.make + +demo_ode: ode drawstuff + @echo ==== Building demo_ode ==== + @$(MAKE) --no-print-directory -C . -f demo_ode.make + +demo_plane2d: ode drawstuff + @echo ==== Building demo_plane2d ==== + @$(MAKE) --no-print-directory -C . -f demo_plane2d.make + +demo_slider: ode drawstuff + @echo ==== Building demo_slider ==== + @$(MAKE) --no-print-directory -C . -f demo_slider.make + +demo_space: ode drawstuff + @echo ==== Building demo_space ==== + @$(MAKE) --no-print-directory -C . -f demo_space.make + +demo_space_stress: ode drawstuff + @echo ==== Building demo_space_stress ==== + @$(MAKE) --no-print-directory -C . -f demo_space_stress.make + +demo_step: ode drawstuff + @echo ==== Building demo_step ==== + @$(MAKE) --no-print-directory -C . -f demo_step.make + +demo_basket: ode drawstuff + @echo ==== Building demo_basket ==== + @$(MAKE) --no-print-directory -C . -f demo_basket.make + +demo_cyl: ode drawstuff + @echo ==== Building demo_cyl ==== + @$(MAKE) --no-print-directory -C . -f demo_cyl.make + +demo_moving_trimesh: ode drawstuff + @echo ==== Building demo_moving_trimesh ==== + @$(MAKE) --no-print-directory -C . -f demo_moving_trimesh.make + +demo_trimesh: ode drawstuff + @echo ==== Building demo_trimesh ==== + @$(MAKE) --no-print-directory -C . -f demo_trimesh.make + +demo_cylvssphere: ode drawstuff + @echo ==== Building demo_cylvssphere ==== + @$(MAKE) --no-print-directory -C . -f demo_cylvssphere.make + +tests: ode + @echo ==== Building tests ==== + @$(MAKE) --no-print-directory -C . -f tests.make + +clean: + @$(MAKE) --no-print-directory -C . -f ode.make clean + @$(MAKE) --no-print-directory -C . -f drawstuff.make clean + @$(MAKE) --no-print-directory -C . -f demo_boxstack.make clean + @$(MAKE) --no-print-directory -C . -f demo_buggy.make clean + @$(MAKE) --no-print-directory -C . -f demo_chain1.make clean + @$(MAKE) --no-print-directory -C . -f demo_chain2.make clean + @$(MAKE) --no-print-directory -C . -f demo_collision.make clean + @$(MAKE) --no-print-directory -C . -f demo_crash.make clean + @$(MAKE) --no-print-directory -C . -f demo_feedback.make clean + @$(MAKE) --no-print-directory -C . -f demo_friction.make clean + @$(MAKE) --no-print-directory -C . -f demo_heightfield.make clean + @$(MAKE) --no-print-directory -C . -f demo_hinge.make clean + @$(MAKE) --no-print-directory -C . -f demo_I.make clean + @$(MAKE) --no-print-directory -C . -f demo_joints.make clean + @$(MAKE) --no-print-directory -C . -f demo_motor.make clean + @$(MAKE) --no-print-directory -C . -f demo_ode.make clean + @$(MAKE) --no-print-directory -C . -f demo_plane2d.make clean + @$(MAKE) --no-print-directory -C . -f demo_slider.make clean + @$(MAKE) --no-print-directory -C . -f demo_space.make clean + @$(MAKE) --no-print-directory -C . -f demo_space_stress.make clean + @$(MAKE) --no-print-directory -C . -f demo_step.make clean + @$(MAKE) --no-print-directory -C . -f demo_basket.make clean + @$(MAKE) --no-print-directory -C . -f demo_cyl.make clean + @$(MAKE) --no-print-directory -C . -f demo_moving_trimesh.make clean + @$(MAKE) --no-print-directory -C . -f demo_trimesh.make clean + @$(MAKE) --no-print-directory -C . -f demo_cylvssphere.make clean + @$(MAKE) --no-print-directory -C . -f tests.make clean diff --git a/libraries/ode-0.9/build/gnu/demo_I.make b/libraries/ode-0.9/build/gnu/demo_I.make new file mode 100644 index 0000000000..4e661c20be --- /dev/null +++ b/libraries/ode-0.9/build/gnu/demo_I.make @@ -0,0 +1,124 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/I/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_I.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/I/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_I.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/I/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_I.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/I/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_I.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/demo_I.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking demo_I + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning demo_I +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/demo_I.o: ../../ode/demo/demo_I.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/demo_basket.make b/libraries/ode-0.9/build/gnu/demo_basket.make new file mode 100644 index 0000000000..ba7605ae65 --- /dev/null +++ b/libraries/ode-0.9/build/gnu/demo_basket.make @@ -0,0 +1,124 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/basket/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_basket.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/basket/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_basket.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/basket/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_basket.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/basket/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_basket.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/demo_basket.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking demo_basket + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning demo_basket +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/demo_basket.o: ../../ode/demo/demo_basket.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/demo_boxstack.make b/libraries/ode-0.9/build/gnu/demo_boxstack.make new file mode 100644 index 0000000000..9e3f3d7610 --- /dev/null +++ b/libraries/ode-0.9/build/gnu/demo_boxstack.make @@ -0,0 +1,124 @@ +# C++ Static Library Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/boxstack/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_boxstack.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/boxstack/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_boxstack.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/boxstack/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_boxstack.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/boxstack/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_boxstack.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/demo_boxstack.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking demo_boxstack + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning demo_boxstack +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/demo_boxstack.o: ../../ode/demo/demo_boxstack.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/demo_buggy.make b/libraries/ode-0.9/build/gnu/demo_buggy.make new file mode 100644 index 0000000000..1fe86eee5b --- /dev/null +++ b/libraries/ode-0.9/build/gnu/demo_buggy.make @@ -0,0 +1,124 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/buggy/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_buggy.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/buggy/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_buggy.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/buggy/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_buggy.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/buggy/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_buggy.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/demo_buggy.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking demo_buggy + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning demo_buggy +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/demo_buggy.o: ../../ode/demo/demo_buggy.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/demo_chain1.make b/libraries/ode-0.9/build/gnu/demo_chain1.make new file mode 100644 index 0000000000..5aeaa9b748 --- /dev/null +++ b/libraries/ode-0.9/build/gnu/demo_chain1.make @@ -0,0 +1,124 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/chain1/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_chain1.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/chain1/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_chain1.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/chain1/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_chain1.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/chain1/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_chain1.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/demo_chain1.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking demo_chain1 + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning demo_chain1 +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/demo_chain1.o: ../../ode/demo/demo_chain1.c + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CC) $(CFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/demo_chain2.make b/libraries/ode-0.9/build/gnu/demo_chain2.make new file mode 100644 index 0000000000..c5ebf07392 --- /dev/null +++ b/libraries/ode-0.9/build/gnu/demo_chain2.make @@ -0,0 +1,124 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/chain2/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_chain2.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/chain2/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_chain2.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/chain2/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_chain2.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/chain2/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_chain2.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/demo_chain2.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking demo_chain2 + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning demo_chain2 +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/demo_chain2.o: ../../ode/demo/demo_chain2.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/demo_collision.make b/libraries/ode-0.9/build/gnu/demo_collision.make new file mode 100644 index 0000000000..1ce042abdb --- /dev/null +++ b/libraries/ode-0.9/build/gnu/demo_collision.make @@ -0,0 +1,124 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/collision/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_collision.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/collision/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_collision.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/collision/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_collision.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/collision/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_collision.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/demo_collision.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking demo_collision + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning demo_collision +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/demo_collision.o: ../../ode/demo/demo_collision.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/demo_crash.make b/libraries/ode-0.9/build/gnu/demo_crash.make new file mode 100644 index 0000000000..8e22ec5b58 --- /dev/null +++ b/libraries/ode-0.9/build/gnu/demo_crash.make @@ -0,0 +1,124 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/crash/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_crash.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/crash/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_crash.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/crash/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_crash.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/crash/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_crash.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/demo_crash.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking demo_crash + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning demo_crash +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/demo_crash.o: ../../ode/demo/demo_crash.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/demo_cyl.make b/libraries/ode-0.9/build/gnu/demo_cyl.make new file mode 100644 index 0000000000..9258ae8adc --- /dev/null +++ b/libraries/ode-0.9/build/gnu/demo_cyl.make @@ -0,0 +1,124 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/cyl/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_cyl.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/cyl/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_cyl.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/cyl/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_cyl.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/cyl/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_cyl.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/demo_cyl.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking demo_cyl + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning demo_cyl +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/demo_cyl.o: ../../ode/demo/demo_cyl.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/demo_cylvssphere.make b/libraries/ode-0.9/build/gnu/demo_cylvssphere.make new file mode 100644 index 0000000000..a153c24588 --- /dev/null +++ b/libraries/ode-0.9/build/gnu/demo_cylvssphere.make @@ -0,0 +1,124 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/cylvssphere/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_cylvssphere.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/cylvssphere/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_cylvssphere.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/cylvssphere/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_cylvssphere.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/cylvssphere/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_cylvssphere.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/demo_cylvssphere.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking demo_cylvssphere + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning demo_cylvssphere +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/demo_cylvssphere.o: ../../ode/demo/demo_cylvssphere.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/demo_feedback.make b/libraries/ode-0.9/build/gnu/demo_feedback.make new file mode 100644 index 0000000000..e3e53ab8cb --- /dev/null +++ b/libraries/ode-0.9/build/gnu/demo_feedback.make @@ -0,0 +1,124 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/feedback/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_feedback.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/feedback/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_feedback.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/feedback/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_feedback.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/feedback/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_feedback.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/demo_feedback.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking demo_feedback + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning demo_feedback +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/demo_feedback.o: ../../ode/demo/demo_feedback.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/demo_friction.make b/libraries/ode-0.9/build/gnu/demo_friction.make new file mode 100644 index 0000000000..2d589198f1 --- /dev/null +++ b/libraries/ode-0.9/build/gnu/demo_friction.make @@ -0,0 +1,124 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/friction/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_friction.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/friction/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_friction.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/friction/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_friction.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/friction/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_friction.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/demo_friction.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking demo_friction + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning demo_friction +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/demo_friction.o: ../../ode/demo/demo_friction.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/demo_heightfield.make b/libraries/ode-0.9/build/gnu/demo_heightfield.make new file mode 100644 index 0000000000..f60cb0c909 --- /dev/null +++ b/libraries/ode-0.9/build/gnu/demo_heightfield.make @@ -0,0 +1,124 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/heightfield/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_heightfield.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/heightfield/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_heightfield.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/heightfield/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_heightfield.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/heightfield/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_heightfield.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/demo_heightfield.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking demo_heightfield + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning demo_heightfield +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/demo_heightfield.o: ../../ode/demo/demo_heightfield.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/demo_hinge.make b/libraries/ode-0.9/build/gnu/demo_hinge.make new file mode 100644 index 0000000000..17e17b2924 --- /dev/null +++ b/libraries/ode-0.9/build/gnu/demo_hinge.make @@ -0,0 +1,124 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/hinge/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_hinge.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/hinge/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_hinge.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/hinge/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_hinge.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/hinge/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_hinge.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/demo_hinge.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking demo_hinge + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning demo_hinge +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/demo_hinge.o: ../../ode/demo/demo_hinge.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/demo_joints.make b/libraries/ode-0.9/build/gnu/demo_joints.make new file mode 100644 index 0000000000..d1581abbda --- /dev/null +++ b/libraries/ode-0.9/build/gnu/demo_joints.make @@ -0,0 +1,124 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/joints/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_joints.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/joints/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_joints.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/joints/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_joints.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/joints/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_joints.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/demo_joints.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking demo_joints + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning demo_joints +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/demo_joints.o: ../../ode/demo/demo_joints.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/demo_motor.make b/libraries/ode-0.9/build/gnu/demo_motor.make new file mode 100644 index 0000000000..b49b00d31f --- /dev/null +++ b/libraries/ode-0.9/build/gnu/demo_motor.make @@ -0,0 +1,124 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/motor/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_motor.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/motor/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_motor.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/motor/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_motor.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/motor/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_motor.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/demo_motor.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking demo_motor + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning demo_motor +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/demo_motor.o: ../../ode/demo/demo_motor.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/demo_moving_trimesh.make b/libraries/ode-0.9/build/gnu/demo_moving_trimesh.make new file mode 100644 index 0000000000..381c7bfd79 --- /dev/null +++ b/libraries/ode-0.9/build/gnu/demo_moving_trimesh.make @@ -0,0 +1,124 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/moving_trimesh/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_moving_trimesh.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/moving_trimesh/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_moving_trimesh.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/moving_trimesh/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_moving_trimesh.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/moving_trimesh/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_moving_trimesh.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/demo_moving_trimesh.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking demo_moving_trimesh + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning demo_moving_trimesh +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/demo_moving_trimesh.o: ../../ode/demo/demo_moving_trimesh.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/demo_ode.make b/libraries/ode-0.9/build/gnu/demo_ode.make new file mode 100644 index 0000000000..3c5b3a5475 --- /dev/null +++ b/libraries/ode-0.9/build/gnu/demo_ode.make @@ -0,0 +1,124 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/ode/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_ode.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/ode/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_ode.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/ode/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_ode.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/ode/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_ode.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/demo_ode.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking demo_ode + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning demo_ode +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/demo_ode.o: ../../ode/demo/demo_ode.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/demo_plane2d.make b/libraries/ode-0.9/build/gnu/demo_plane2d.make new file mode 100644 index 0000000000..aa07b22e27 --- /dev/null +++ b/libraries/ode-0.9/build/gnu/demo_plane2d.make @@ -0,0 +1,124 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/plane2d/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_plane2d.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/plane2d/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_plane2d.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/plane2d/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_plane2d.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/plane2d/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_plane2d.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/demo_plane2d.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking demo_plane2d + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning demo_plane2d +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/demo_plane2d.o: ../../ode/demo/demo_plane2d.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/demo_slider.make b/libraries/ode-0.9/build/gnu/demo_slider.make new file mode 100644 index 0000000000..ed3dc42d09 --- /dev/null +++ b/libraries/ode-0.9/build/gnu/demo_slider.make @@ -0,0 +1,124 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/slider/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_slider.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/slider/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_slider.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/slider/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_slider.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/slider/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_slider.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/demo_slider.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking demo_slider + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning demo_slider +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/demo_slider.o: ../../ode/demo/demo_slider.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/demo_space.make b/libraries/ode-0.9/build/gnu/demo_space.make new file mode 100644 index 0000000000..352b3acf3e --- /dev/null +++ b/libraries/ode-0.9/build/gnu/demo_space.make @@ -0,0 +1,124 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/space/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_space.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/space/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_space.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/space/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_space.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/space/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_space.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/demo_space.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking demo_space + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning demo_space +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/demo_space.o: ../../ode/demo/demo_space.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/demo_space_stress.make b/libraries/ode-0.9/build/gnu/demo_space_stress.make new file mode 100644 index 0000000000..e55f9b88c6 --- /dev/null +++ b/libraries/ode-0.9/build/gnu/demo_space_stress.make @@ -0,0 +1,124 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/space_stress/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_space_stress.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/space_stress/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_space_stress.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/space_stress/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_space_stress.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/space_stress/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_space_stress.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/demo_space_stress.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking demo_space_stress + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning demo_space_stress +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/demo_space_stress.o: ../../ode/demo/demo_space_stress.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/demo_step.make b/libraries/ode-0.9/build/gnu/demo_step.make new file mode 100644 index 0000000000..9d33c53356 --- /dev/null +++ b/libraries/ode-0.9/build/gnu/demo_step.make @@ -0,0 +1,124 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/step/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_step.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/step/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_step.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/step/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_step.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/step/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_step.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/demo_step.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking demo_step + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning demo_step +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/demo_step.o: ../../ode/demo/demo_step.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/demo_trimesh.make b/libraries/ode-0.9/build/gnu/demo_trimesh.make new file mode 100644 index 0000000000..15973d3ccd --- /dev/null +++ b/libraries/ode-0.9/build/gnu/demo_trimesh.make @@ -0,0 +1,124 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/trimesh/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugDLL/ode.dll ../../lib/DebugDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_trimesh.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/trimesh/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseDLL/ode.dll ../../lib/ReleaseDLL/drawstuff.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_trimesh.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/trimesh/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/DebugLib/libode.a ../../lib/DebugLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_trimesh.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/trimesh/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a -luser32 -lwinmm -lgdi32 -lopengl32 -lglu32 + LDDEPS := ../../lib/ReleaseLib/libode.a ../../lib/ReleaseLib/libdrawstuff.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -D "WIN32" -I "../../include" + TARGET := demo_trimesh.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/demo_trimesh.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking demo_trimesh + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning demo_trimesh +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/demo_trimesh.o: ../../ode/demo/demo_trimesh.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/drawstuff.make b/libraries/ode-0.9/build/gnu/drawstuff.make new file mode 100644 index 0000000000..5d55c538f5 --- /dev/null +++ b/libraries/ode-0.9/build/gnu/drawstuff.make @@ -0,0 +1,130 @@ +# C++ Static Library Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/drawstuff/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "WIN32" -D "DS_DLL" -D "USRDLL" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -shared -luser32 -lopengl32 -lglu32 -lwinmm -lgdi32 + LDDEPS := + RESFLAGS := -D "WIN32" -D "DS_DLL" -D "USRDLL" -I "../../include" + TARGET := drawstuff.dll + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/drawstuff/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "WIN32" -D "DS_DLL" -D "USRDLL" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -O3 -fomit-frame-pointer + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -shared -s -luser32 -lopengl32 -lglu32 -lwinmm -lgdi32 + LDDEPS := + RESFLAGS := -D "WIN32" -D "DS_DLL" -D "USRDLL" -I "../../include" + TARGET := drawstuff.dll + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/drawstuff/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "WIN32" -D "DS_LIB" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -luser32 -lopengl32 -lglu32 -lwinmm -lgdi32 + LDDEPS := + RESFLAGS := -D "WIN32" -D "DS_LIB" -I "../../include" + TARGET := libdrawstuff.a + BLDCMD = ar -rcs $(OUTDIR)/$(TARGET) $(OBJECTS) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/drawstuff/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "WIN32" -D "DS_LIB" -I "../../include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -O3 -fomit-frame-pointer + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -s -luser32 -lopengl32 -lglu32 -lwinmm -lgdi32 + LDDEPS := + RESFLAGS := -D "WIN32" -D "DS_LIB" -I "../../include" + TARGET := libdrawstuff.a + BLDCMD = ar -rcs $(OUTDIR)/$(TARGET) $(OBJECTS) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/drawstuff.o \ + $(OBJDIR)/windows.o \ + +RESOURCES := \ + $(OBJDIR)/resources.res \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking drawstuff + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning drawstuff +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/drawstuff.o: ../../drawstuff/src/drawstuff.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/windows.o: ../../drawstuff/src/windows.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/resources.res: ../../drawstuff/src/resources.rc + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @windres $< -O coff -o $@ $(RESFLAGS) + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/ode.make b/libraries/ode-0.9/build/gnu/ode.make new file mode 100644 index 0000000000..413a5aa9cb --- /dev/null +++ b/libraries/ode-0.9/build/gnu/ode.make @@ -0,0 +1,706 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/ode/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "WIN32" -D "ODE_DLL" -I "../../include" -I "../../OPCODE" -I "../../GIMPACT/include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -shared -luser32 + LDDEPS := + RESFLAGS := -D "WIN32" -D "ODE_DLL" -I "../../include" -I "../../OPCODE" -I "../../GIMPACT/include" + TARGET := ode.dll + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/ode/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "WIN32" -D "ODE_DLL" -I "../../include" -I "../../OPCODE" -I "../../GIMPACT/include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -O3 -fomit-frame-pointer + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -shared -s -luser32 + LDDEPS := + RESFLAGS := -D "WIN32" -D "ODE_DLL" -I "../../include" -I "../../OPCODE" -I "../../GIMPACT/include" + TARGET := ode.dll + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/ode/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "WIN32" -D "ODE_LIB" -I "../../include" -I "../../OPCODE" -I "../../GIMPACT/include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -luser32 + LDDEPS := + RESFLAGS := -D "WIN32" -D "ODE_LIB" -I "../../include" -I "../../OPCODE" -I "../../GIMPACT/include" + TARGET := libode.a + BLDCMD = ar -rcs $(OUTDIR)/$(TARGET) $(OBJECTS) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/ode/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "WIN32" -D "ODE_LIB" -I "../../include" -I "../../OPCODE" -I "../../GIMPACT/include" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -O3 -fomit-frame-pointer + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) -s -luser32 + LDDEPS := + RESFLAGS := -D "WIN32" -D "ODE_LIB" -I "../../include" -I "../../OPCODE" -I "../../GIMPACT/include" + TARGET := libode.a + BLDCMD = ar -rcs $(OUTDIR)/$(TARGET) $(OBJECTS) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/fastdot.o \ + $(OBJDIR)/fastldlt.o \ + $(OBJDIR)/fastlsolve.o \ + $(OBJDIR)/fastltsolve.o \ + $(OBJDIR)/array.o \ + $(OBJDIR)/box.o \ + $(OBJDIR)/capsule.o \ + $(OBJDIR)/collision_cylinder_box.o \ + $(OBJDIR)/collision_cylinder_plane.o \ + $(OBJDIR)/collision_cylinder_sphere.o \ + $(OBJDIR)/collision_cylinder_trimesh.o \ + $(OBJDIR)/collision_kernel.o \ + $(OBJDIR)/collision_quadtreespace.o \ + $(OBJDIR)/collision_space.o \ + $(OBJDIR)/collision_transform.o \ + $(OBJDIR)/collision_trimesh_box.o \ + $(OBJDIR)/collision_trimesh_ccylinder.o \ + $(OBJDIR)/collision_trimesh_distance.o \ + $(OBJDIR)/collision_trimesh_gimpact.o \ + $(OBJDIR)/collision_trimesh_opcode.o \ + $(OBJDIR)/collision_trimesh_plane.o \ + $(OBJDIR)/collision_trimesh_ray.o \ + $(OBJDIR)/collision_trimesh_sphere.o \ + $(OBJDIR)/collision_trimesh_trimesh.o \ + $(OBJDIR)/collision_trimesh_trimesh_new.o \ + $(OBJDIR)/collision_util.o \ + $(OBJDIR)/convex.o \ + $(OBJDIR)/cylinder.o \ + $(OBJDIR)/error.o \ + $(OBJDIR)/export-dif.o \ + $(OBJDIR)/heightfield.o \ + $(OBJDIR)/joint.o \ + $(OBJDIR)/lcp.o \ + $(OBJDIR)/mass.o \ + $(OBJDIR)/mat.o \ + $(OBJDIR)/matrix.o \ + $(OBJDIR)/memory.o \ + $(OBJDIR)/misc.o \ + $(OBJDIR)/obstack.o \ + $(OBJDIR)/ode.o \ + $(OBJDIR)/odemath.o \ + $(OBJDIR)/plane.o \ + $(OBJDIR)/quickstep.o \ + $(OBJDIR)/ray.o \ + $(OBJDIR)/rotation.o \ + $(OBJDIR)/sphere.o \ + $(OBJDIR)/step.o \ + $(OBJDIR)/stepfast.o \ + $(OBJDIR)/testing.o \ + $(OBJDIR)/timer.o \ + $(OBJDIR)/util.o \ + $(OBJDIR)/gimpact.o \ + $(OBJDIR)/gim_boxpruning.o \ + $(OBJDIR)/gim_contact.o \ + $(OBJDIR)/gim_math.o \ + $(OBJDIR)/gim_memory.o \ + $(OBJDIR)/gim_trimesh.o \ + $(OBJDIR)/gim_trimesh_capsule_collision.o \ + $(OBJDIR)/gim_trimesh_ray_collision.o \ + $(OBJDIR)/gim_trimesh_sphere_collision.o \ + $(OBJDIR)/gim_trimesh_trimesh_collision.o \ + $(OBJDIR)/gim_tri_tri_overlap.o \ + $(OBJDIR)/Opcode.o \ + $(OBJDIR)/OPC_AABBCollider.o \ + $(OBJDIR)/OPC_AABBTree.o \ + $(OBJDIR)/OPC_BaseModel.o \ + $(OBJDIR)/OPC_BoxPruning.o \ + $(OBJDIR)/OPC_Collider.o \ + $(OBJDIR)/OPC_Common.o \ + $(OBJDIR)/OPC_HybridModel.o \ + $(OBJDIR)/OPC_LSSCollider.o \ + $(OBJDIR)/OPC_MeshInterface.o \ + $(OBJDIR)/OPC_Model.o \ + $(OBJDIR)/OPC_OBBCollider.o \ + $(OBJDIR)/OPC_OptimizedTree.o \ + $(OBJDIR)/OPC_Picking.o \ + $(OBJDIR)/OPC_PlanesCollider.o \ + $(OBJDIR)/OPC_RayCollider.o \ + $(OBJDIR)/OPC_SphereCollider.o \ + $(OBJDIR)/OPC_SweepAndPrune.o \ + $(OBJDIR)/OPC_TreeBuilders.o \ + $(OBJDIR)/OPC_TreeCollider.o \ + $(OBJDIR)/OPC_VolumeCollider.o \ + $(OBJDIR)/StdAfx.o \ + $(OBJDIR)/IceAABB.o \ + $(OBJDIR)/IceContainer.o \ + $(OBJDIR)/IceHPoint.o \ + $(OBJDIR)/IceIndexedTriangle.o \ + $(OBJDIR)/IceMatrix3x3.o \ + $(OBJDIR)/IceMatrix4x4.o \ + $(OBJDIR)/IceOBB.o \ + $(OBJDIR)/IcePlane.o \ + $(OBJDIR)/IcePoint.o \ + $(OBJDIR)/IceRandom.o \ + $(OBJDIR)/IceRay.o \ + $(OBJDIR)/IceRevisitedRadix.o \ + $(OBJDIR)/IceSegment.o \ + $(OBJDIR)/IceTriangle.o \ + $(OBJDIR)/IceUtils.o \ + +RESOURCES := \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking ode + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning ode +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/fastdot.o: ../../ode/src/fastdot.c + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CC) $(CFLAGS) -o $@ -c $< + +$(OBJDIR)/fastldlt.o: ../../ode/src/fastldlt.c + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CC) $(CFLAGS) -o $@ -c $< + +$(OBJDIR)/fastlsolve.o: ../../ode/src/fastlsolve.c + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CC) $(CFLAGS) -o $@ -c $< + +$(OBJDIR)/fastltsolve.o: ../../ode/src/fastltsolve.c + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CC) $(CFLAGS) -o $@ -c $< + +$(OBJDIR)/array.o: ../../ode/src/array.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/box.o: ../../ode/src/box.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/capsule.o: ../../ode/src/capsule.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/collision_cylinder_box.o: ../../ode/src/collision_cylinder_box.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/collision_cylinder_plane.o: ../../ode/src/collision_cylinder_plane.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/collision_cylinder_sphere.o: ../../ode/src/collision_cylinder_sphere.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/collision_cylinder_trimesh.o: ../../ode/src/collision_cylinder_trimesh.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/collision_kernel.o: ../../ode/src/collision_kernel.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/collision_quadtreespace.o: ../../ode/src/collision_quadtreespace.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/collision_space.o: ../../ode/src/collision_space.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/collision_transform.o: ../../ode/src/collision_transform.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/collision_trimesh_box.o: ../../ode/src/collision_trimesh_box.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/collision_trimesh_ccylinder.o: ../../ode/src/collision_trimesh_ccylinder.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/collision_trimesh_distance.o: ../../ode/src/collision_trimesh_distance.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/collision_trimesh_gimpact.o: ../../ode/src/collision_trimesh_gimpact.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/collision_trimesh_opcode.o: ../../ode/src/collision_trimesh_opcode.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/collision_trimesh_plane.o: ../../ode/src/collision_trimesh_plane.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/collision_trimesh_ray.o: ../../ode/src/collision_trimesh_ray.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/collision_trimesh_sphere.o: ../../ode/src/collision_trimesh_sphere.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/collision_trimesh_trimesh.o: ../../ode/src/collision_trimesh_trimesh.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/collision_trimesh_trimesh_new.o: ../../ode/src/collision_trimesh_trimesh_new.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/collision_util.o: ../../ode/src/collision_util.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/convex.o: ../../ode/src/convex.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/cylinder.o: ../../ode/src/cylinder.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/error.o: ../../ode/src/error.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/export-dif.o: ../../ode/src/export-dif.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/heightfield.o: ../../ode/src/heightfield.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/joint.o: ../../ode/src/joint.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/lcp.o: ../../ode/src/lcp.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/mass.o: ../../ode/src/mass.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/mat.o: ../../ode/src/mat.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/matrix.o: ../../ode/src/matrix.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/memory.o: ../../ode/src/memory.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/misc.o: ../../ode/src/misc.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/obstack.o: ../../ode/src/obstack.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/ode.o: ../../ode/src/ode.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/odemath.o: ../../ode/src/odemath.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/plane.o: ../../ode/src/plane.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/quickstep.o: ../../ode/src/quickstep.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/ray.o: ../../ode/src/ray.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/rotation.o: ../../ode/src/rotation.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/sphere.o: ../../ode/src/sphere.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/step.o: ../../ode/src/step.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/stepfast.o: ../../ode/src/stepfast.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/testing.o: ../../ode/src/testing.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/timer.o: ../../ode/src/timer.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/util.o: ../../ode/src/util.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/gimpact.o: ../../GIMPACT/src/gimpact.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/gim_boxpruning.o: ../../GIMPACT/src/gim_boxpruning.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/gim_contact.o: ../../GIMPACT/src/gim_contact.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/gim_math.o: ../../GIMPACT/src/gim_math.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/gim_memory.o: ../../GIMPACT/src/gim_memory.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/gim_trimesh.o: ../../GIMPACT/src/gim_trimesh.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/gim_trimesh_capsule_collision.o: ../../GIMPACT/src/gim_trimesh_capsule_collision.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/gim_trimesh_ray_collision.o: ../../GIMPACT/src/gim_trimesh_ray_collision.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/gim_trimesh_sphere_collision.o: ../../GIMPACT/src/gim_trimesh_sphere_collision.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/gim_trimesh_trimesh_collision.o: ../../GIMPACT/src/gim_trimesh_trimesh_collision.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/gim_tri_tri_overlap.o: ../../GIMPACT/src/gim_tri_tri_overlap.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/Opcode.o: ../../OPCODE/Opcode.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/OPC_AABBCollider.o: ../../OPCODE/OPC_AABBCollider.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/OPC_AABBTree.o: ../../OPCODE/OPC_AABBTree.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/OPC_BaseModel.o: ../../OPCODE/OPC_BaseModel.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/OPC_BoxPruning.o: ../../OPCODE/OPC_BoxPruning.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/OPC_Collider.o: ../../OPCODE/OPC_Collider.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/OPC_Common.o: ../../OPCODE/OPC_Common.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/OPC_HybridModel.o: ../../OPCODE/OPC_HybridModel.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/OPC_LSSCollider.o: ../../OPCODE/OPC_LSSCollider.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/OPC_MeshInterface.o: ../../OPCODE/OPC_MeshInterface.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/OPC_Model.o: ../../OPCODE/OPC_Model.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/OPC_OBBCollider.o: ../../OPCODE/OPC_OBBCollider.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/OPC_OptimizedTree.o: ../../OPCODE/OPC_OptimizedTree.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/OPC_Picking.o: ../../OPCODE/OPC_Picking.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/OPC_PlanesCollider.o: ../../OPCODE/OPC_PlanesCollider.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/OPC_RayCollider.o: ../../OPCODE/OPC_RayCollider.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/OPC_SphereCollider.o: ../../OPCODE/OPC_SphereCollider.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/OPC_SweepAndPrune.o: ../../OPCODE/OPC_SweepAndPrune.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/OPC_TreeBuilders.o: ../../OPCODE/OPC_TreeBuilders.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/OPC_TreeCollider.o: ../../OPCODE/OPC_TreeCollider.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/OPC_VolumeCollider.o: ../../OPCODE/OPC_VolumeCollider.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/StdAfx.o: ../../OPCODE/StdAfx.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/IceAABB.o: ../../OPCODE/Ice/IceAABB.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/IceContainer.o: ../../OPCODE/Ice/IceContainer.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/IceHPoint.o: ../../OPCODE/Ice/IceHPoint.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/IceIndexedTriangle.o: ../../OPCODE/Ice/IceIndexedTriangle.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/IceMatrix3x3.o: ../../OPCODE/Ice/IceMatrix3x3.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/IceMatrix4x4.o: ../../OPCODE/Ice/IceMatrix4x4.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/IceOBB.o: ../../OPCODE/Ice/IceOBB.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/IcePlane.o: ../../OPCODE/Ice/IcePlane.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/IcePoint.o: ../../OPCODE/Ice/IcePoint.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/IceRandom.o: ../../OPCODE/Ice/IceRandom.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/IceRay.o: ../../OPCODE/Ice/IceRay.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/IceRevisitedRadix.o: ../../OPCODE/Ice/IceRevisitedRadix.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/IceSegment.o: ../../OPCODE/Ice/IceSegment.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/IceTriangle.o: ../../OPCODE/Ice/IceTriangle.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/IceUtils.o: ../../OPCODE/Ice/IceUtils.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/gnu/tests.make b/libraries/ode-0.9/build/gnu/tests.make new file mode 100644 index 0000000000..869e809012 --- /dev/null +++ b/libraries/ode-0.9/build/gnu/tests.make @@ -0,0 +1,166 @@ +# C++ Console Executable Makefile autogenerated by premake +# Don't edit this file! Instead edit `premake.lua` then rerun `make` + +ifndef CONFIG + CONFIG=DebugDLL +endif + +ifeq ($(CONFIG),DebugDLL) + BINDIR := ../../lib/DebugDLL + LIBDIR := ../../lib/DebugDLL + OBJDIR := obj/tests/DebugDLL + OUTDIR := ../../lib/DebugDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -I "../../include" -I "../../tests/CppTestHarness" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugDLL/ode.dll + LDDEPS := ../../lib/DebugDLL/ode.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -I "../../include" -I "../../tests/CppTestHarness" + TARGET := tests.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseDLL) + BINDIR := ../../lib/ReleaseDLL + LIBDIR := ../../lib/ReleaseDLL + OBJDIR := obj/tests/ReleaseDLL + OUTDIR := ../../lib/ReleaseDLL + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -I "../../include" -I "../../tests/CppTestHarness" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseDLL/ode.dll + LDDEPS := ../../lib/ReleaseDLL/ode.dll + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -I "../../include" -I "../../tests/CppTestHarness" + TARGET := tests.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),DebugLib) + BINDIR := ../../lib/DebugLib + LIBDIR := ../../lib/DebugLib + OBJDIR := obj/tests/DebugLib + OUTDIR := ../../lib/DebugLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -I "../../include" -I "../../tests/CppTestHarness" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/DebugLib/libode.a + LDDEPS := ../../lib/DebugLib/libode.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -I "../../include" -I "../../tests/CppTestHarness" + TARGET := tests.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +ifeq ($(CONFIG),ReleaseLib) + BINDIR := ../../lib/ReleaseLib + LIBDIR := ../../lib/ReleaseLib + OBJDIR := obj/tests/ReleaseLib + OUTDIR := ../../lib/ReleaseLib + CPPFLAGS := -MMD -D "_CRT_SECURE_NO_DEPRECATE" -I "../../include" -I "../../tests/CppTestHarness" + CFLAGS += $(CPPFLAGS) $(TARGET_ARCH) -g + CXXFLAGS := $(CFLAGS) + LDFLAGS += -L$(BINDIR) -L$(LIBDIR) ../../lib/ReleaseLib/libode.a + LDDEPS := ../../lib/ReleaseLib/libode.a + RESFLAGS := -D "_CRT_SECURE_NO_DEPRECATE" -I "../../include" -I "../../tests/CppTestHarness" + TARGET := tests.exe + BLDCMD = $(CXX) -o $(OUTDIR)/$(TARGET) $(OBJECTS) $(LDFLAGS) $(RESOURCES) $(TARGET_ARCH) +endif + +OBJECTS := \ + $(OBJDIR)/main.o \ + $(OBJDIR)/box_sphere.o \ + $(OBJDIR)/HTMLTestReporter.o \ + $(OBJDIR)/PrintfTestReporter.o \ + $(OBJDIR)/Test.o \ + $(OBJDIR)/TestLauncher.o \ + $(OBJDIR)/TestReporter.o \ + $(OBJDIR)/TestResults.o \ + $(OBJDIR)/TestRunner.o \ + +RESOURCES := \ + +MKDIR_TYPE := msdos +CMD := $(subst \,\\,$(ComSpec)$(COMSPEC)) +ifeq (,$(CMD)) + MKDIR_TYPE := posix +endif +ifeq (/bin/sh.exe,$(SHELL)) + MKDIR_TYPE := posix +endif +ifeq ($(MKDIR_TYPE),posix) + CMD_MKBINDIR := mkdir -p $(BINDIR) + CMD_MKLIBDIR := mkdir -p $(LIBDIR) + CMD_MKOUTDIR := mkdir -p $(OUTDIR) + CMD_MKOBJDIR := mkdir -p $(OBJDIR) +else + CMD_MKBINDIR := $(CMD) /c if not exist $(subst /,\\,$(BINDIR)) mkdir $(subst /,\\,$(BINDIR)) + CMD_MKLIBDIR := $(CMD) /c if not exist $(subst /,\\,$(LIBDIR)) mkdir $(subst /,\\,$(LIBDIR)) + CMD_MKOUTDIR := $(CMD) /c if not exist $(subst /,\\,$(OUTDIR)) mkdir $(subst /,\\,$(OUTDIR)) + CMD_MKOBJDIR := $(CMD) /c if not exist $(subst /,\\,$(OBJDIR)) mkdir $(subst /,\\,$(OBJDIR)) +endif + +.PHONY: clean + +$(OUTDIR)/$(TARGET): $(OBJECTS) $(LDDEPS) $(RESOURCES) + @echo Linking tests + -@$(CMD_MKBINDIR) + -@$(CMD_MKLIBDIR) + -@$(CMD_MKOUTDIR) + @$(BLDCMD) + +clean: + @echo Cleaning tests +ifeq ($(MKDIR_TYPE),posix) + -@rm -rf $(OUTDIR)/$(TARGET) $(OBJDIR) +else + -@if exist $(subst /,\,$(OUTDIR)/$(TARGET)) del /q $(subst /,\,$(OUTDIR)/$(TARGET)) + -@if exist $(subst /,\,$(OBJDIR)) del /q $(subst /,\,$(OBJDIR)) + -@if exist $(subst /,\,$(OBJDIR)) rmdir /s /q $(subst /,\,$(OBJDIR)) +endif + +$(OBJDIR)/main.o: ../../tests/main.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/box_sphere.o: ../../tests/colliders/box_sphere.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/HTMLTestReporter.o: ../../tests/CppTestHarness/HTMLTestReporter.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/PrintfTestReporter.o: ../../tests/CppTestHarness/PrintfTestReporter.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/Test.o: ../../tests/CppTestHarness/Test.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/TestLauncher.o: ../../tests/CppTestHarness/TestLauncher.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/TestReporter.o: ../../tests/CppTestHarness/TestReporter.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/TestResults.o: ../../tests/CppTestHarness/TestResults.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +$(OBJDIR)/TestRunner.o: ../../tests/CppTestHarness/TestRunner.cpp + -@$(CMD_MKOBJDIR) + @echo $(notdir $<) + @$(CXX) $(CXXFLAGS) -o $@ -c $< + +-include $(OBJECTS:%.o=%.d) + diff --git a/libraries/ode-0.9/build/ode.lua b/libraries/ode-0.9/build/ode.lua new file mode 100644 index 0000000000..568cd260f1 --- /dev/null +++ b/libraries/ode-0.9/build/ode.lua @@ -0,0 +1,166 @@ +package.name = "ode" +package.language = "c++" +package.objdir = "obj/ode" + + +-- Separate distribution files into toolset subdirectories + + if (options["usetargetpath"]) then + package.path = options["target"] + else + package.path = "custom" + end + + +-- Write a custom to include/ode, based on the specified flags + + io.input("config-default.h") + local text = io.read("*a") + + if (options["with-doubles"]) then + text = string.gsub(text, "#define dSINGLE", "/* #define dSINGLE */") + text = string.gsub(text, "/%* #define dDOUBLE %*/", "#define dDOUBLE") + end + + 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 + + io.output("../include/ode/config.h") + io.write(text) + io.close() + + +-- Package Build Settings + + if (options["enable-shared-only"]) then + + package.kind = "dll" + table.insert(package.defines, "ODE_DLL") + + elseif (options["enable-static-only"]) then + + package.kind = "lib" + table.insert(package.defines, "ODE_LIB") + + else + + package.config["DebugDLL"].kind = "dll" + package.config["DebugLib"].kind = "lib" + package.config["ReleaseDLL"].kind = "dll" + package.config["ReleaseLib"].kind = "lib" + + table.insert(package.config["DebugDLL"].defines, "ODE_DLL") + table.insert(package.config["ReleaseDLL"].defines, "ODE_DLL") + table.insert(package.config["DebugLib"].defines, "ODE_LIB") + table.insert(package.config["ReleaseLib"].defines, "ODE_LIB") + + end + + package.includepaths = + { + "../../include", + "../../OPCODE", + "../../GIMPACT/include" + } + + if (windows) then + table.insert(package.defines, "WIN32") + end + + -- disable VS2005 CRT security warnings + if (options["target"] == "vs2005") then + table.insert(package.defines, "_CRT_SECURE_NO_DEPRECATE") + end + + +-- Build Flags + + package.config["DebugLib"].buildflags = { } + package.config["DebugDLL"].buildflags = { } + + package.config["ReleaseDLL"].buildflags = { "optimize-speed", "no-symbols", "no-frame-pointer" } + package.config["ReleaseLib"].buildflags = { "optimize-speed", "no-symbols", "no-frame-pointer" } + + if (options.target == "vs6" or options.target == "vs2002" or options.target == "vs2003") then + table.insert(package.config.DebugLib.buildflags, "static-runtime") + table.insert(package.config.ReleaseLib.buildflags, "static-runtime") + end + + +-- Libraries + + if (windows) then + table.insert(package.links, "user32") + end + + +-- Files + + core_files = + { + matchfiles("../../include/ode/*.h"), + matchfiles ("../../ode/src/*.h", "../../ode/src/*.c", "../../ode/src/*.cpp") + } + + excluded_files = + { + "../../ode/src/collision_std.cpp", + "../../ode/src/scrapbook.cpp", + "../../ode/src/stack.cpp" + } + + trimesh_files = + { + "../../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" + } + + opcode_files = + { + matchrecursive("../../OPCODE/*.h", "../../OPCODE/*.cpp") + } + + gimpact_files = + { + matchrecursive("../../GIMPACT/*.h", "../../GIMPACT/*.cpp") + } + + dif_files = + { + "../../ode/src/export-dif.cpp" + } + + package.files = { core_files } + package.excludes = { excluded_files } + + if (options["no-dif"]) then + table.insert(package.excludes, dif_files) + end + + if (options["no-trimesh"]) then + table.insert(package.excludes, trimesh_files) + else + table.insert(package.files, gimpact_files) + table.insert(package.files, opcode_files) + end diff --git a/libraries/ode-0.9/build/premake.lua b/libraries/ode-0.9/build/premake.lua new file mode 100644 index 0000000000..350365acca --- /dev/null +++ b/libraries/ode-0.9/build/premake.lua @@ -0,0 +1,98 @@ +project.name = "ode" + + if (options["target"] == "vs6") then + error("Visual Studio 6 is no longer supported; please upgrade to Visual Studio 2005 C++ Express.") + end + + +-- Define the build configurations. You can also use the flags +-- `--enable-shared-only` and `--enable-static-only` if you want to +-- call these packages from within your own Premake-enabled project. + + if (not options["enable-shared-only"] and not options["enable-static-only"]) then + project.configs = { "DebugDLL", "ReleaseDLL", "DebugLib", "ReleaseLib" } + end + + +-- Project options + + addoption("with-doubles", "Use double instead of float as base numeric type") + addoption("with-demos", "Builds the demo applications and DrawStuff library") + addoption("with-tests", "Builds the unit test application") + addoption("with-gimpact", "Use GIMPACT for trimesh collisions (experimental)") + addoption("no-dif", "Exclude DIF (Dynamics Interchange Format) exports") + addoption("no-trimesh", "Exclude trimesh collision geometry") + addoption("no-alloca", "Use heap memory instead of the stack (experimental)") + + +-- If the `--usetargetpath` flag is specified, each set of generated files +-- be placed in a directory named for the target toolset. This flag is +-- used by the `--makeall` command (see below). + + if (options["usetargetpath"]) then + project.path = options["target"] + end + + +-- Set the output directories + + if (options["enable-shared-only"] or options["enable-static-only"]) then + project.config["Debug"].bindir = "../lib/debug" + project.config["Debug"].libdir = "../lib/debug" + project.config["Release"].bindir = "../lib/release" + project.config["Release"].bindir = "../lib/release" + else + project.config["DebugDLL"].bindir = "../lib/DebugDLL" + project.config["DebugDLL"].libdir = "../lib/DebugDLL" + project.config["ReleaseDLL"].bindir = "../lib/ReleaseDLL" + project.config["ReleaseDLL"].libdir = "../lib/ReleaseDLL" + project.config["DebugLib"].bindir = "../lib/DebugLib" + project.config["DebugLib"].libdir = "../lib/DebugLib" + project.config["ReleaseLib"].bindir = "../lib/ReleaseLib" + project.config["ReleaseLib"].libdir = "../lib/ReleaseLib" + end + + +-- Build packages + + dopackage("ode.lua") + + if (options["with-demos"]) then + dopackage("drawstuff.lua") + dopackage("demos.lua") + end + + if (options["with-tests"]) then + dopackage("tests.lua") + end + + +-- Remove all intermediate files + + function doclean(cmd, arg) + docommand(cmd, arg) + if (options["target"] == "") then + os.remove("../include/ode/config.h") + end + os.rmdir("custom") + os.rmdir("../lib/debug") + os.rmdir("../lib/release") + os.rmdir("../lib/DebugDLL") + os.rmdir("../lib/DebugLib") + os.rmdir("../lib/ReleaseDLL") + os.rmdir("../lib/ReleaseLib") + os.rmdir("gnu/obj") + os.rmdir("vs2002/obj") + os.rmdir("vs2003/obj") + os.rmdir("vs2005/obj") + end + + +-- Generate all toolsets in one go + + function domakeall(cmd, arg) + os.execute("premake --usetargetpath --with-demos --with-tests --clean --target vs2002") + os.execute("premake --usetargetpath --with-demos --with-tests --clean --target vs2003") + os.execute("premake --usetargetpath --with-demos --with-tests --clean --target vs2005") + os.execute("premake --usetargetpath --with-demos --with-tests --clean --target gnu") + end diff --git a/libraries/ode-0.9/build/tests.lua b/libraries/ode-0.9/build/tests.lua new file mode 100644 index 0000000000..25da24e704 --- /dev/null +++ b/libraries/ode-0.9/build/tests.lua @@ -0,0 +1,26 @@ + package.name = "tests" + package.kind = "exe" + package.language = "c++" + package.path = packagepath + package.objdir = "obj/tests" + + package.includepaths = + { + "../../include", + "../../tests/CppTestHarness" + } + + package.defines = + { + "_CRT_SECURE_NO_DEPRECATE" + } + + package.links = + { + "ode" + } + + package.files = + { + matchrecursive("../../tests/*.h", "../../tests/*.cpp") + } diff --git a/libraries/ode-0.9/build/vs2002/demo_I.vcproj b/libraries/ode-0.9/build/vs2002/demo_I.vcproj new file mode 100644 index 0000000000..83eec4b06f --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/demo_I.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/demo_basket.vcproj b/libraries/ode-0.9/build/vs2002/demo_basket.vcproj new file mode 100644 index 0000000000..5ed08efc4a --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/demo_basket.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/demo_boxstack.vcproj b/libraries/ode-0.9/build/vs2002/demo_boxstack.vcproj new file mode 100644 index 0000000000..ccc1e1260f --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/demo_boxstack.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/demo_buggy.vcproj b/libraries/ode-0.9/build/vs2002/demo_buggy.vcproj new file mode 100644 index 0000000000..b5f413e509 --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/demo_buggy.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/demo_chain1.vcproj b/libraries/ode-0.9/build/vs2002/demo_chain1.vcproj new file mode 100644 index 0000000000..d7894f6f72 --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/demo_chain1.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/demo_chain2.vcproj b/libraries/ode-0.9/build/vs2002/demo_chain2.vcproj new file mode 100644 index 0000000000..d4b82bb2e4 --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/demo_chain2.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/demo_collision.vcproj b/libraries/ode-0.9/build/vs2002/demo_collision.vcproj new file mode 100644 index 0000000000..321c47923b --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/demo_collision.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/demo_crash.vcproj b/libraries/ode-0.9/build/vs2002/demo_crash.vcproj new file mode 100644 index 0000000000..4d38fa8716 --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/demo_crash.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/demo_cyl.vcproj b/libraries/ode-0.9/build/vs2002/demo_cyl.vcproj new file mode 100644 index 0000000000..e9f854b266 --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/demo_cyl.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/demo_cylvssphere.vcproj b/libraries/ode-0.9/build/vs2002/demo_cylvssphere.vcproj new file mode 100644 index 0000000000..411d008aea --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/demo_cylvssphere.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/demo_feedback.vcproj b/libraries/ode-0.9/build/vs2002/demo_feedback.vcproj new file mode 100644 index 0000000000..0d2d3c3c59 --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/demo_feedback.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/demo_friction.vcproj b/libraries/ode-0.9/build/vs2002/demo_friction.vcproj new file mode 100644 index 0000000000..20adbb313a --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/demo_friction.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/demo_heightfield.vcproj b/libraries/ode-0.9/build/vs2002/demo_heightfield.vcproj new file mode 100644 index 0000000000..fd6cafdb3c --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/demo_heightfield.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/demo_hinge.vcproj b/libraries/ode-0.9/build/vs2002/demo_hinge.vcproj new file mode 100644 index 0000000000..fb46da4649 --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/demo_hinge.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/demo_joints.vcproj b/libraries/ode-0.9/build/vs2002/demo_joints.vcproj new file mode 100644 index 0000000000..d8491a48d7 --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/demo_joints.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/demo_motor.vcproj b/libraries/ode-0.9/build/vs2002/demo_motor.vcproj new file mode 100644 index 0000000000..5f797fdc35 --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/demo_motor.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/demo_moving_trimesh.vcproj b/libraries/ode-0.9/build/vs2002/demo_moving_trimesh.vcproj new file mode 100644 index 0000000000..829b78c64a --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/demo_moving_trimesh.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/demo_ode.vcproj b/libraries/ode-0.9/build/vs2002/demo_ode.vcproj new file mode 100644 index 0000000000..6285736d45 --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/demo_ode.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/demo_plane2d.vcproj b/libraries/ode-0.9/build/vs2002/demo_plane2d.vcproj new file mode 100644 index 0000000000..e0d7c840a7 --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/demo_plane2d.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/demo_slider.vcproj b/libraries/ode-0.9/build/vs2002/demo_slider.vcproj new file mode 100644 index 0000000000..c3132f9c4e --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/demo_slider.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/demo_space.vcproj b/libraries/ode-0.9/build/vs2002/demo_space.vcproj new file mode 100644 index 0000000000..546c0450aa --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/demo_space.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/demo_space_stress.vcproj b/libraries/ode-0.9/build/vs2002/demo_space_stress.vcproj new file mode 100644 index 0000000000..ff27b34554 --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/demo_space_stress.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/demo_step.vcproj b/libraries/ode-0.9/build/vs2002/demo_step.vcproj new file mode 100644 index 0000000000..a5d29e82b2 --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/demo_step.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/demo_trimesh.vcproj b/libraries/ode-0.9/build/vs2002/demo_trimesh.vcproj new file mode 100644 index 0000000000..19fb4fd42a --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/demo_trimesh.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/drawstuff.vcproj b/libraries/ode-0.9/build/vs2002/drawstuff.vcproj new file mode 100644 index 0000000000..d6aac06d7b --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/drawstuff.vcproj @@ -0,0 +1,240 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/ode.sln b/libraries/ode-0.9/build/vs2002/ode.sln new file mode 100644 index 0000000000..70dcd5063f --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/ode.sln @@ -0,0 +1,336 @@ +Microsoft Visual Studio Solution File, Format Version 7.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ode", "./ode.vcproj", "{7530658D-B5A8-6046-ACD2-C155B5A252A8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "drawstuff", "./drawstuff.vcproj", "{4E655490-1B05-844D-871C-BA0F04084AF7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_boxstack", "./demo_boxstack.vcproj", "{B9222926-060B-3248-830A-7C83791F4C61}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_buggy", "./demo_buggy.vcproj", "{8C0F98C4-A95C-6B42-A522-8BC78284EB24}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_chain1", "./demo_chain1.vcproj", "{AD6DDB03-D653-0A48-929F-EB8523978EF2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_chain2", "./demo_chain2.vcproj", "{341B4B78-CA98-5244-8CB0-5F4BCA52B8AB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_collision", "./demo_collision.vcproj", "{31540B38-E155-6443-B2CD-BA527144D859}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_crash", "./demo_crash.vcproj", "{7021A282-47AE-294A-9482-DB85E9820FBA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_feedback", "./demo_feedback.vcproj", "{9749BFD4-C4AE-164E-80B4-909F77D77869}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_friction", "./demo_friction.vcproj", "{1C345B16-ACE5-6549-8E84-C91B8392FD0C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_heightfield", "./demo_heightfield.vcproj", "{B8CB1716-5EFF-F442-B261-4056E3F8B8D1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_hinge", "./demo_hinge.vcproj", "{FB9A21A7-A63E-D744-A1D0-F393E7730DC2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_I", "./demo_I.vcproj", "{A382F22A-4053-3445-9E14-02B3447E5F1E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_joints", "./demo_joints.vcproj", "{9C43F96A-1793-5743-A767-2519C9FA48F8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_motor", "./demo_motor.vcproj", "{C0CBBFAD-5F99-9B43-969E-13B3B46EBED5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_ode", "./demo_ode.vcproj", "{439C6FAA-CF31-3E42-AD89-CCC07CBE3727}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_plane2d", "./demo_plane2d.vcproj", "{17389BAF-67B5-0747-9126-D01B69F4A0C5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_slider", "./demo_slider.vcproj", "{B0D00D10-D115-5849-976C-2A03A5E0B7D5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_space", "./demo_space.vcproj", "{15F48142-ACD9-0347-B18C-3C26152AEADE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_space_stress", "./demo_space_stress.vcproj", "{86143476-EE08-104B-9C2B-FADE62C8DC23}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_step", "./demo_step.vcproj", "{B818CB9B-879B-2B44-82E2-2F96FA8D61E8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_basket", "./demo_basket.vcproj", "{4D85F0AA-E59F-3B43-918F-B5033A5E3BD4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_cyl", "./demo_cyl.vcproj", "{35B7AA42-1B0A-D644-9728-2D9E83806F40}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_moving_trimesh", "./demo_moving_trimesh.vcproj", "{F98194BC-7D59-0742-A5A1-7CA698E65FE2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_trimesh", "./demo_trimesh.vcproj", "{EE803EF6-9285-BA47-AD4A-C5AE76BF7FDC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_cylvssphere", "./demo_cylvssphere.vcproj", "{81101776-8512-C64E-875D-4FE66D465AB1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests", "./tests.vcproj", "{E10C083A-2A98-6D4F-A1D3-EF613C0C7141}" +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + ConfigName.0 = DebugDLL + ConfigName.1 = ReleaseDLL + ConfigName.2 = DebugLib + ConfigName.3 = ReleaseLib + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + {B9222926-060B-3248-830A-7C83791F4C61}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + {B9222926-060B-3248-830A-7C83791F4C61}.1 = {4E655490-1B05-844D-871C-BA0F04084AF7} + {8C0F98C4-A95C-6B42-A522-8BC78284EB24}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + {8C0F98C4-A95C-6B42-A522-8BC78284EB24}.1 = {4E655490-1B05-844D-871C-BA0F04084AF7} + {AD6DDB03-D653-0A48-929F-EB8523978EF2}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + {AD6DDB03-D653-0A48-929F-EB8523978EF2}.1 = {4E655490-1B05-844D-871C-BA0F04084AF7} + {341B4B78-CA98-5244-8CB0-5F4BCA52B8AB}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + {341B4B78-CA98-5244-8CB0-5F4BCA52B8AB}.1 = {4E655490-1B05-844D-871C-BA0F04084AF7} + {31540B38-E155-6443-B2CD-BA527144D859}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + {31540B38-E155-6443-B2CD-BA527144D859}.1 = {4E655490-1B05-844D-871C-BA0F04084AF7} + {7021A282-47AE-294A-9482-DB85E9820FBA}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + {7021A282-47AE-294A-9482-DB85E9820FBA}.1 = {4E655490-1B05-844D-871C-BA0F04084AF7} + {9749BFD4-C4AE-164E-80B4-909F77D77869}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + {9749BFD4-C4AE-164E-80B4-909F77D77869}.1 = {4E655490-1B05-844D-871C-BA0F04084AF7} + {1C345B16-ACE5-6549-8E84-C91B8392FD0C}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + {1C345B16-ACE5-6549-8E84-C91B8392FD0C}.1 = {4E655490-1B05-844D-871C-BA0F04084AF7} + {B8CB1716-5EFF-F442-B261-4056E3F8B8D1}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + {B8CB1716-5EFF-F442-B261-4056E3F8B8D1}.1 = {4E655490-1B05-844D-871C-BA0F04084AF7} + {FB9A21A7-A63E-D744-A1D0-F393E7730DC2}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + {FB9A21A7-A63E-D744-A1D0-F393E7730DC2}.1 = {4E655490-1B05-844D-871C-BA0F04084AF7} + {A382F22A-4053-3445-9E14-02B3447E5F1E}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + {A382F22A-4053-3445-9E14-02B3447E5F1E}.1 = {4E655490-1B05-844D-871C-BA0F04084AF7} + {9C43F96A-1793-5743-A767-2519C9FA48F8}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + {9C43F96A-1793-5743-A767-2519C9FA48F8}.1 = {4E655490-1B05-844D-871C-BA0F04084AF7} + {C0CBBFAD-5F99-9B43-969E-13B3B46EBED5}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + {C0CBBFAD-5F99-9B43-969E-13B3B46EBED5}.1 = {4E655490-1B05-844D-871C-BA0F04084AF7} + {439C6FAA-CF31-3E42-AD89-CCC07CBE3727}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + {439C6FAA-CF31-3E42-AD89-CCC07CBE3727}.1 = {4E655490-1B05-844D-871C-BA0F04084AF7} + {17389BAF-67B5-0747-9126-D01B69F4A0C5}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + {17389BAF-67B5-0747-9126-D01B69F4A0C5}.1 = {4E655490-1B05-844D-871C-BA0F04084AF7} + {B0D00D10-D115-5849-976C-2A03A5E0B7D5}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + {B0D00D10-D115-5849-976C-2A03A5E0B7D5}.1 = {4E655490-1B05-844D-871C-BA0F04084AF7} + {15F48142-ACD9-0347-B18C-3C26152AEADE}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + {15F48142-ACD9-0347-B18C-3C26152AEADE}.1 = {4E655490-1B05-844D-871C-BA0F04084AF7} + {86143476-EE08-104B-9C2B-FADE62C8DC23}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + {86143476-EE08-104B-9C2B-FADE62C8DC23}.1 = {4E655490-1B05-844D-871C-BA0F04084AF7} + {B818CB9B-879B-2B44-82E2-2F96FA8D61E8}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + {B818CB9B-879B-2B44-82E2-2F96FA8D61E8}.1 = {4E655490-1B05-844D-871C-BA0F04084AF7} + {4D85F0AA-E59F-3B43-918F-B5033A5E3BD4}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + {4D85F0AA-E59F-3B43-918F-B5033A5E3BD4}.1 = {4E655490-1B05-844D-871C-BA0F04084AF7} + {35B7AA42-1B0A-D644-9728-2D9E83806F40}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + {35B7AA42-1B0A-D644-9728-2D9E83806F40}.1 = {4E655490-1B05-844D-871C-BA0F04084AF7} + {F98194BC-7D59-0742-A5A1-7CA698E65FE2}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + {F98194BC-7D59-0742-A5A1-7CA698E65FE2}.1 = {4E655490-1B05-844D-871C-BA0F04084AF7} + {EE803EF6-9285-BA47-AD4A-C5AE76BF7FDC}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + {EE803EF6-9285-BA47-AD4A-C5AE76BF7FDC}.1 = {4E655490-1B05-844D-871C-BA0F04084AF7} + {81101776-8512-C64E-875D-4FE66D465AB1}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + {81101776-8512-C64E-875D-4FE66D465AB1}.1 = {4E655490-1B05-844D-871C-BA0F04084AF7} + {E10C083A-2A98-6D4F-A1D3-EF613C0C7141}.0 = {7530658D-B5A8-6046-ACD2-C155B5A252A8} + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {7530658D-B5A8-6046-ACD2-C155B5A252A8}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {7530658D-B5A8-6046-ACD2-C155B5A252A8}.DebugDLL.Build.0 = DebugDLL|Win32 + {7530658D-B5A8-6046-ACD2-C155B5A252A8}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {7530658D-B5A8-6046-ACD2-C155B5A252A8}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {7530658D-B5A8-6046-ACD2-C155B5A252A8}.DebugLib.ActiveCfg = DebugLib|Win32 + {7530658D-B5A8-6046-ACD2-C155B5A252A8}.DebugLib.Build.0 = DebugLib|Win32 + {7530658D-B5A8-6046-ACD2-C155B5A252A8}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {7530658D-B5A8-6046-ACD2-C155B5A252A8}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {4E655490-1B05-844D-871C-BA0F04084AF7}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {4E655490-1B05-844D-871C-BA0F04084AF7}.DebugDLL.Build.0 = DebugDLL|Win32 + {4E655490-1B05-844D-871C-BA0F04084AF7}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {4E655490-1B05-844D-871C-BA0F04084AF7}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {4E655490-1B05-844D-871C-BA0F04084AF7}.DebugLib.ActiveCfg = DebugLib|Win32 + {4E655490-1B05-844D-871C-BA0F04084AF7}.DebugLib.Build.0 = DebugLib|Win32 + {4E655490-1B05-844D-871C-BA0F04084AF7}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {4E655490-1B05-844D-871C-BA0F04084AF7}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {B9222926-060B-3248-830A-7C83791F4C61}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {B9222926-060B-3248-830A-7C83791F4C61}.DebugDLL.Build.0 = DebugDLL|Win32 + {B9222926-060B-3248-830A-7C83791F4C61}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {B9222926-060B-3248-830A-7C83791F4C61}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {B9222926-060B-3248-830A-7C83791F4C61}.DebugLib.ActiveCfg = DebugLib|Win32 + {B9222926-060B-3248-830A-7C83791F4C61}.DebugLib.Build.0 = DebugLib|Win32 + {B9222926-060B-3248-830A-7C83791F4C61}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {B9222926-060B-3248-830A-7C83791F4C61}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {8C0F98C4-A95C-6B42-A522-8BC78284EB24}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {8C0F98C4-A95C-6B42-A522-8BC78284EB24}.DebugDLL.Build.0 = DebugDLL|Win32 + {8C0F98C4-A95C-6B42-A522-8BC78284EB24}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {8C0F98C4-A95C-6B42-A522-8BC78284EB24}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {8C0F98C4-A95C-6B42-A522-8BC78284EB24}.DebugLib.ActiveCfg = DebugLib|Win32 + {8C0F98C4-A95C-6B42-A522-8BC78284EB24}.DebugLib.Build.0 = DebugLib|Win32 + {8C0F98C4-A95C-6B42-A522-8BC78284EB24}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {8C0F98C4-A95C-6B42-A522-8BC78284EB24}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {AD6DDB03-D653-0A48-929F-EB8523978EF2}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {AD6DDB03-D653-0A48-929F-EB8523978EF2}.DebugDLL.Build.0 = DebugDLL|Win32 + {AD6DDB03-D653-0A48-929F-EB8523978EF2}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {AD6DDB03-D653-0A48-929F-EB8523978EF2}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {AD6DDB03-D653-0A48-929F-EB8523978EF2}.DebugLib.ActiveCfg = DebugLib|Win32 + {AD6DDB03-D653-0A48-929F-EB8523978EF2}.DebugLib.Build.0 = DebugLib|Win32 + {AD6DDB03-D653-0A48-929F-EB8523978EF2}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {AD6DDB03-D653-0A48-929F-EB8523978EF2}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {341B4B78-CA98-5244-8CB0-5F4BCA52B8AB}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {341B4B78-CA98-5244-8CB0-5F4BCA52B8AB}.DebugDLL.Build.0 = DebugDLL|Win32 + {341B4B78-CA98-5244-8CB0-5F4BCA52B8AB}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {341B4B78-CA98-5244-8CB0-5F4BCA52B8AB}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {341B4B78-CA98-5244-8CB0-5F4BCA52B8AB}.DebugLib.ActiveCfg = DebugLib|Win32 + {341B4B78-CA98-5244-8CB0-5F4BCA52B8AB}.DebugLib.Build.0 = DebugLib|Win32 + {341B4B78-CA98-5244-8CB0-5F4BCA52B8AB}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {341B4B78-CA98-5244-8CB0-5F4BCA52B8AB}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {31540B38-E155-6443-B2CD-BA527144D859}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {31540B38-E155-6443-B2CD-BA527144D859}.DebugDLL.Build.0 = DebugDLL|Win32 + {31540B38-E155-6443-B2CD-BA527144D859}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {31540B38-E155-6443-B2CD-BA527144D859}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {31540B38-E155-6443-B2CD-BA527144D859}.DebugLib.ActiveCfg = DebugLib|Win32 + {31540B38-E155-6443-B2CD-BA527144D859}.DebugLib.Build.0 = DebugLib|Win32 + {31540B38-E155-6443-B2CD-BA527144D859}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {31540B38-E155-6443-B2CD-BA527144D859}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {7021A282-47AE-294A-9482-DB85E9820FBA}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {7021A282-47AE-294A-9482-DB85E9820FBA}.DebugDLL.Build.0 = DebugDLL|Win32 + {7021A282-47AE-294A-9482-DB85E9820FBA}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {7021A282-47AE-294A-9482-DB85E9820FBA}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {7021A282-47AE-294A-9482-DB85E9820FBA}.DebugLib.ActiveCfg = DebugLib|Win32 + {7021A282-47AE-294A-9482-DB85E9820FBA}.DebugLib.Build.0 = DebugLib|Win32 + {7021A282-47AE-294A-9482-DB85E9820FBA}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {7021A282-47AE-294A-9482-DB85E9820FBA}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {9749BFD4-C4AE-164E-80B4-909F77D77869}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {9749BFD4-C4AE-164E-80B4-909F77D77869}.DebugDLL.Build.0 = DebugDLL|Win32 + {9749BFD4-C4AE-164E-80B4-909F77D77869}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {9749BFD4-C4AE-164E-80B4-909F77D77869}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {9749BFD4-C4AE-164E-80B4-909F77D77869}.DebugLib.ActiveCfg = DebugLib|Win32 + {9749BFD4-C4AE-164E-80B4-909F77D77869}.DebugLib.Build.0 = DebugLib|Win32 + {9749BFD4-C4AE-164E-80B4-909F77D77869}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {9749BFD4-C4AE-164E-80B4-909F77D77869}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {1C345B16-ACE5-6549-8E84-C91B8392FD0C}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {1C345B16-ACE5-6549-8E84-C91B8392FD0C}.DebugDLL.Build.0 = DebugDLL|Win32 + {1C345B16-ACE5-6549-8E84-C91B8392FD0C}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {1C345B16-ACE5-6549-8E84-C91B8392FD0C}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {1C345B16-ACE5-6549-8E84-C91B8392FD0C}.DebugLib.ActiveCfg = DebugLib|Win32 + {1C345B16-ACE5-6549-8E84-C91B8392FD0C}.DebugLib.Build.0 = DebugLib|Win32 + {1C345B16-ACE5-6549-8E84-C91B8392FD0C}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {1C345B16-ACE5-6549-8E84-C91B8392FD0C}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {B8CB1716-5EFF-F442-B261-4056E3F8B8D1}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {B8CB1716-5EFF-F442-B261-4056E3F8B8D1}.DebugDLL.Build.0 = DebugDLL|Win32 + {B8CB1716-5EFF-F442-B261-4056E3F8B8D1}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {B8CB1716-5EFF-F442-B261-4056E3F8B8D1}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {B8CB1716-5EFF-F442-B261-4056E3F8B8D1}.DebugLib.ActiveCfg = DebugLib|Win32 + {B8CB1716-5EFF-F442-B261-4056E3F8B8D1}.DebugLib.Build.0 = DebugLib|Win32 + {B8CB1716-5EFF-F442-B261-4056E3F8B8D1}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {B8CB1716-5EFF-F442-B261-4056E3F8B8D1}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {FB9A21A7-A63E-D744-A1D0-F393E7730DC2}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {FB9A21A7-A63E-D744-A1D0-F393E7730DC2}.DebugDLL.Build.0 = DebugDLL|Win32 + {FB9A21A7-A63E-D744-A1D0-F393E7730DC2}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {FB9A21A7-A63E-D744-A1D0-F393E7730DC2}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {FB9A21A7-A63E-D744-A1D0-F393E7730DC2}.DebugLib.ActiveCfg = DebugLib|Win32 + {FB9A21A7-A63E-D744-A1D0-F393E7730DC2}.DebugLib.Build.0 = DebugLib|Win32 + {FB9A21A7-A63E-D744-A1D0-F393E7730DC2}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {FB9A21A7-A63E-D744-A1D0-F393E7730DC2}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {A382F22A-4053-3445-9E14-02B3447E5F1E}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {A382F22A-4053-3445-9E14-02B3447E5F1E}.DebugDLL.Build.0 = DebugDLL|Win32 + {A382F22A-4053-3445-9E14-02B3447E5F1E}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {A382F22A-4053-3445-9E14-02B3447E5F1E}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {A382F22A-4053-3445-9E14-02B3447E5F1E}.DebugLib.ActiveCfg = DebugLib|Win32 + {A382F22A-4053-3445-9E14-02B3447E5F1E}.DebugLib.Build.0 = DebugLib|Win32 + {A382F22A-4053-3445-9E14-02B3447E5F1E}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {A382F22A-4053-3445-9E14-02B3447E5F1E}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {9C43F96A-1793-5743-A767-2519C9FA48F8}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {9C43F96A-1793-5743-A767-2519C9FA48F8}.DebugDLL.Build.0 = DebugDLL|Win32 + {9C43F96A-1793-5743-A767-2519C9FA48F8}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {9C43F96A-1793-5743-A767-2519C9FA48F8}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {9C43F96A-1793-5743-A767-2519C9FA48F8}.DebugLib.ActiveCfg = DebugLib|Win32 + {9C43F96A-1793-5743-A767-2519C9FA48F8}.DebugLib.Build.0 = DebugLib|Win32 + {9C43F96A-1793-5743-A767-2519C9FA48F8}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {9C43F96A-1793-5743-A767-2519C9FA48F8}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {C0CBBFAD-5F99-9B43-969E-13B3B46EBED5}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {C0CBBFAD-5F99-9B43-969E-13B3B46EBED5}.DebugDLL.Build.0 = DebugDLL|Win32 + {C0CBBFAD-5F99-9B43-969E-13B3B46EBED5}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {C0CBBFAD-5F99-9B43-969E-13B3B46EBED5}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {C0CBBFAD-5F99-9B43-969E-13B3B46EBED5}.DebugLib.ActiveCfg = DebugLib|Win32 + {C0CBBFAD-5F99-9B43-969E-13B3B46EBED5}.DebugLib.Build.0 = DebugLib|Win32 + {C0CBBFAD-5F99-9B43-969E-13B3B46EBED5}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {C0CBBFAD-5F99-9B43-969E-13B3B46EBED5}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {439C6FAA-CF31-3E42-AD89-CCC07CBE3727}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {439C6FAA-CF31-3E42-AD89-CCC07CBE3727}.DebugDLL.Build.0 = DebugDLL|Win32 + {439C6FAA-CF31-3E42-AD89-CCC07CBE3727}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {439C6FAA-CF31-3E42-AD89-CCC07CBE3727}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {439C6FAA-CF31-3E42-AD89-CCC07CBE3727}.DebugLib.ActiveCfg = DebugLib|Win32 + {439C6FAA-CF31-3E42-AD89-CCC07CBE3727}.DebugLib.Build.0 = DebugLib|Win32 + {439C6FAA-CF31-3E42-AD89-CCC07CBE3727}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {439C6FAA-CF31-3E42-AD89-CCC07CBE3727}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {17389BAF-67B5-0747-9126-D01B69F4A0C5}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {17389BAF-67B5-0747-9126-D01B69F4A0C5}.DebugDLL.Build.0 = DebugDLL|Win32 + {17389BAF-67B5-0747-9126-D01B69F4A0C5}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {17389BAF-67B5-0747-9126-D01B69F4A0C5}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {17389BAF-67B5-0747-9126-D01B69F4A0C5}.DebugLib.ActiveCfg = DebugLib|Win32 + {17389BAF-67B5-0747-9126-D01B69F4A0C5}.DebugLib.Build.0 = DebugLib|Win32 + {17389BAF-67B5-0747-9126-D01B69F4A0C5}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {17389BAF-67B5-0747-9126-D01B69F4A0C5}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {B0D00D10-D115-5849-976C-2A03A5E0B7D5}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {B0D00D10-D115-5849-976C-2A03A5E0B7D5}.DebugDLL.Build.0 = DebugDLL|Win32 + {B0D00D10-D115-5849-976C-2A03A5E0B7D5}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {B0D00D10-D115-5849-976C-2A03A5E0B7D5}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {B0D00D10-D115-5849-976C-2A03A5E0B7D5}.DebugLib.ActiveCfg = DebugLib|Win32 + {B0D00D10-D115-5849-976C-2A03A5E0B7D5}.DebugLib.Build.0 = DebugLib|Win32 + {B0D00D10-D115-5849-976C-2A03A5E0B7D5}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {B0D00D10-D115-5849-976C-2A03A5E0B7D5}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {15F48142-ACD9-0347-B18C-3C26152AEADE}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {15F48142-ACD9-0347-B18C-3C26152AEADE}.DebugDLL.Build.0 = DebugDLL|Win32 + {15F48142-ACD9-0347-B18C-3C26152AEADE}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {15F48142-ACD9-0347-B18C-3C26152AEADE}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {15F48142-ACD9-0347-B18C-3C26152AEADE}.DebugLib.ActiveCfg = DebugLib|Win32 + {15F48142-ACD9-0347-B18C-3C26152AEADE}.DebugLib.Build.0 = DebugLib|Win32 + {15F48142-ACD9-0347-B18C-3C26152AEADE}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {15F48142-ACD9-0347-B18C-3C26152AEADE}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {86143476-EE08-104B-9C2B-FADE62C8DC23}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {86143476-EE08-104B-9C2B-FADE62C8DC23}.DebugDLL.Build.0 = DebugDLL|Win32 + {86143476-EE08-104B-9C2B-FADE62C8DC23}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {86143476-EE08-104B-9C2B-FADE62C8DC23}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {86143476-EE08-104B-9C2B-FADE62C8DC23}.DebugLib.ActiveCfg = DebugLib|Win32 + {86143476-EE08-104B-9C2B-FADE62C8DC23}.DebugLib.Build.0 = DebugLib|Win32 + {86143476-EE08-104B-9C2B-FADE62C8DC23}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {86143476-EE08-104B-9C2B-FADE62C8DC23}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {B818CB9B-879B-2B44-82E2-2F96FA8D61E8}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {B818CB9B-879B-2B44-82E2-2F96FA8D61E8}.DebugDLL.Build.0 = DebugDLL|Win32 + {B818CB9B-879B-2B44-82E2-2F96FA8D61E8}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {B818CB9B-879B-2B44-82E2-2F96FA8D61E8}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {B818CB9B-879B-2B44-82E2-2F96FA8D61E8}.DebugLib.ActiveCfg = DebugLib|Win32 + {B818CB9B-879B-2B44-82E2-2F96FA8D61E8}.DebugLib.Build.0 = DebugLib|Win32 + {B818CB9B-879B-2B44-82E2-2F96FA8D61E8}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {B818CB9B-879B-2B44-82E2-2F96FA8D61E8}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {4D85F0AA-E59F-3B43-918F-B5033A5E3BD4}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {4D85F0AA-E59F-3B43-918F-B5033A5E3BD4}.DebugDLL.Build.0 = DebugDLL|Win32 + {4D85F0AA-E59F-3B43-918F-B5033A5E3BD4}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {4D85F0AA-E59F-3B43-918F-B5033A5E3BD4}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {4D85F0AA-E59F-3B43-918F-B5033A5E3BD4}.DebugLib.ActiveCfg = DebugLib|Win32 + {4D85F0AA-E59F-3B43-918F-B5033A5E3BD4}.DebugLib.Build.0 = DebugLib|Win32 + {4D85F0AA-E59F-3B43-918F-B5033A5E3BD4}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {4D85F0AA-E59F-3B43-918F-B5033A5E3BD4}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {35B7AA42-1B0A-D644-9728-2D9E83806F40}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {35B7AA42-1B0A-D644-9728-2D9E83806F40}.DebugDLL.Build.0 = DebugDLL|Win32 + {35B7AA42-1B0A-D644-9728-2D9E83806F40}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {35B7AA42-1B0A-D644-9728-2D9E83806F40}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {35B7AA42-1B0A-D644-9728-2D9E83806F40}.DebugLib.ActiveCfg = DebugLib|Win32 + {35B7AA42-1B0A-D644-9728-2D9E83806F40}.DebugLib.Build.0 = DebugLib|Win32 + {35B7AA42-1B0A-D644-9728-2D9E83806F40}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {35B7AA42-1B0A-D644-9728-2D9E83806F40}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {F98194BC-7D59-0742-A5A1-7CA698E65FE2}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {F98194BC-7D59-0742-A5A1-7CA698E65FE2}.DebugDLL.Build.0 = DebugDLL|Win32 + {F98194BC-7D59-0742-A5A1-7CA698E65FE2}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {F98194BC-7D59-0742-A5A1-7CA698E65FE2}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {F98194BC-7D59-0742-A5A1-7CA698E65FE2}.DebugLib.ActiveCfg = DebugLib|Win32 + {F98194BC-7D59-0742-A5A1-7CA698E65FE2}.DebugLib.Build.0 = DebugLib|Win32 + {F98194BC-7D59-0742-A5A1-7CA698E65FE2}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {F98194BC-7D59-0742-A5A1-7CA698E65FE2}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {EE803EF6-9285-BA47-AD4A-C5AE76BF7FDC}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {EE803EF6-9285-BA47-AD4A-C5AE76BF7FDC}.DebugDLL.Build.0 = DebugDLL|Win32 + {EE803EF6-9285-BA47-AD4A-C5AE76BF7FDC}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {EE803EF6-9285-BA47-AD4A-C5AE76BF7FDC}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {EE803EF6-9285-BA47-AD4A-C5AE76BF7FDC}.DebugLib.ActiveCfg = DebugLib|Win32 + {EE803EF6-9285-BA47-AD4A-C5AE76BF7FDC}.DebugLib.Build.0 = DebugLib|Win32 + {EE803EF6-9285-BA47-AD4A-C5AE76BF7FDC}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {EE803EF6-9285-BA47-AD4A-C5AE76BF7FDC}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {81101776-8512-C64E-875D-4FE66D465AB1}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {81101776-8512-C64E-875D-4FE66D465AB1}.DebugDLL.Build.0 = DebugDLL|Win32 + {81101776-8512-C64E-875D-4FE66D465AB1}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {81101776-8512-C64E-875D-4FE66D465AB1}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {81101776-8512-C64E-875D-4FE66D465AB1}.DebugLib.ActiveCfg = DebugLib|Win32 + {81101776-8512-C64E-875D-4FE66D465AB1}.DebugLib.Build.0 = DebugLib|Win32 + {81101776-8512-C64E-875D-4FE66D465AB1}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {81101776-8512-C64E-875D-4FE66D465AB1}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {E10C083A-2A98-6D4F-A1D3-EF613C0C7141}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {E10C083A-2A98-6D4F-A1D3-EF613C0C7141}.DebugDLL.Build.0 = DebugDLL|Win32 + {E10C083A-2A98-6D4F-A1D3-EF613C0C7141}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {E10C083A-2A98-6D4F-A1D3-EF613C0C7141}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {E10C083A-2A98-6D4F-A1D3-EF613C0C7141}.DebugLib.ActiveCfg = DebugLib|Win32 + {E10C083A-2A98-6D4F-A1D3-EF613C0C7141}.DebugLib.Build.0 = DebugLib|Win32 + {E10C083A-2A98-6D4F-A1D3-EF613C0C7141}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {E10C083A-2A98-6D4F-A1D3-EF613C0C7141}.ReleaseLib.Build.0 = ReleaseLib|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/libraries/ode-0.9/build/vs2002/ode.vcproj b/libraries/ode-0.9/build/vs2002/ode.vcproj new file mode 100644 index 0000000000..ddaf370299 --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/ode.vcproj @@ -0,0 +1,864 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2002/tests.vcproj b/libraries/ode-0.9/build/vs2002/tests.vcproj new file mode 100644 index 0000000000..26bcef99ab --- /dev/null +++ b/libraries/ode-0.9/build/vs2002/tests.vcproj @@ -0,0 +1,296 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/demo_I.vcproj b/libraries/ode-0.9/build/vs2003/demo_I.vcproj new file mode 100644 index 0000000000..60b8c1c11a --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/demo_I.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/demo_basket.vcproj b/libraries/ode-0.9/build/vs2003/demo_basket.vcproj new file mode 100644 index 0000000000..c8c552d336 --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/demo_basket.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/demo_boxstack.vcproj b/libraries/ode-0.9/build/vs2003/demo_boxstack.vcproj new file mode 100644 index 0000000000..22c49205c1 --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/demo_boxstack.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/demo_buggy.vcproj b/libraries/ode-0.9/build/vs2003/demo_buggy.vcproj new file mode 100644 index 0000000000..dc4c38edf3 --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/demo_buggy.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/demo_chain1.vcproj b/libraries/ode-0.9/build/vs2003/demo_chain1.vcproj new file mode 100644 index 0000000000..cd20c46aa3 --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/demo_chain1.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/demo_chain2.vcproj b/libraries/ode-0.9/build/vs2003/demo_chain2.vcproj new file mode 100644 index 0000000000..d677b26417 --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/demo_chain2.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/demo_collision.vcproj b/libraries/ode-0.9/build/vs2003/demo_collision.vcproj new file mode 100644 index 0000000000..bf0f338924 --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/demo_collision.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/demo_crash.vcproj b/libraries/ode-0.9/build/vs2003/demo_crash.vcproj new file mode 100644 index 0000000000..3a5dad0b5c --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/demo_crash.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/demo_cyl.vcproj b/libraries/ode-0.9/build/vs2003/demo_cyl.vcproj new file mode 100644 index 0000000000..5584ae5674 --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/demo_cyl.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/demo_cylvssphere.vcproj b/libraries/ode-0.9/build/vs2003/demo_cylvssphere.vcproj new file mode 100644 index 0000000000..4c2870f92b --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/demo_cylvssphere.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/demo_feedback.vcproj b/libraries/ode-0.9/build/vs2003/demo_feedback.vcproj new file mode 100644 index 0000000000..361e72aac8 --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/demo_feedback.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/demo_friction.vcproj b/libraries/ode-0.9/build/vs2003/demo_friction.vcproj new file mode 100644 index 0000000000..a8a90c01c7 --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/demo_friction.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/demo_heightfield.vcproj b/libraries/ode-0.9/build/vs2003/demo_heightfield.vcproj new file mode 100644 index 0000000000..1287bc61b8 --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/demo_heightfield.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/demo_hinge.vcproj b/libraries/ode-0.9/build/vs2003/demo_hinge.vcproj new file mode 100644 index 0000000000..a7061b74a8 --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/demo_hinge.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/demo_joints.vcproj b/libraries/ode-0.9/build/vs2003/demo_joints.vcproj new file mode 100644 index 0000000000..b80d31c6c6 --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/demo_joints.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/demo_motor.vcproj b/libraries/ode-0.9/build/vs2003/demo_motor.vcproj new file mode 100644 index 0000000000..8fd9f90593 --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/demo_motor.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/demo_moving_trimesh.vcproj b/libraries/ode-0.9/build/vs2003/demo_moving_trimesh.vcproj new file mode 100644 index 0000000000..65079c023d --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/demo_moving_trimesh.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/demo_ode.vcproj b/libraries/ode-0.9/build/vs2003/demo_ode.vcproj new file mode 100644 index 0000000000..be0ce9955c --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/demo_ode.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/demo_plane2d.vcproj b/libraries/ode-0.9/build/vs2003/demo_plane2d.vcproj new file mode 100644 index 0000000000..874f182e19 --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/demo_plane2d.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/demo_slider.vcproj b/libraries/ode-0.9/build/vs2003/demo_slider.vcproj new file mode 100644 index 0000000000..a9c6bc1364 --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/demo_slider.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/demo_space.vcproj b/libraries/ode-0.9/build/vs2003/demo_space.vcproj new file mode 100644 index 0000000000..4243a9006c --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/demo_space.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/demo_space_stress.vcproj b/libraries/ode-0.9/build/vs2003/demo_space_stress.vcproj new file mode 100644 index 0000000000..988583ea99 --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/demo_space_stress.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/demo_step.vcproj b/libraries/ode-0.9/build/vs2003/demo_step.vcproj new file mode 100644 index 0000000000..353e12fb19 --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/demo_step.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/demo_trimesh.vcproj b/libraries/ode-0.9/build/vs2003/demo_trimesh.vcproj new file mode 100644 index 0000000000..b95ae50f27 --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/demo_trimesh.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/drawstuff.vcproj b/libraries/ode-0.9/build/vs2003/drawstuff.vcproj new file mode 100644 index 0000000000..39f0d56eed --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/drawstuff.vcproj @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/ode.sln b/libraries/ode-0.9/build/vs2003/ode.sln new file mode 100644 index 0000000000..e00732bba3 --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/ode.sln @@ -0,0 +1,388 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ode", "./ode.vcproj", "{5F0953F1-B966-BA4E-A31A-C002A407FD47}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "drawstuff", "./drawstuff.vcproj", "{029C9CCD-2B3E-BE45-8520-A231CD8C67EC}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_boxstack", "./demo_boxstack.vcproj", "{F25F1B18-2103-B147-A5F0-984D0D1EBBDA}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} = {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_buggy", "./demo_buggy.vcproj", "{79FFAF28-2FD1-6744-909F-7F7E68DDEB6D}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} = {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_chain1", "./demo_chain1.vcproj", "{DC6294E4-6A55-1D41-9846-53EC913D0DC3}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} = {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_chain2", "./demo_chain2.vcproj", "{D01EDE86-5B74-A24B-B084-FC79608D376D}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} = {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_collision", "./demo_collision.vcproj", "{238F8FBA-C48F-694E-9D78-6D99DA572645}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} = {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_crash", "./demo_crash.vcproj", "{4D828A55-6AAD-B948-8817-38EB3E85F504}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} = {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_feedback", "./demo_feedback.vcproj", "{2CFE9EEA-E735-BD49-96FF-34C2C3893AC7}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} = {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_friction", "./demo_friction.vcproj", "{ECE402AB-3062-6745-AC2A-85BB65CA000F}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} = {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_heightfield", "./demo_heightfield.vcproj", "{D746A3DA-E7D4-6A4A-B078-D5E5A79CFB5F}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} = {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_hinge", "./demo_hinge.vcproj", "{1F4FB263-EF66-F247-807C-30DA768C7072}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} = {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_I", "./demo_I.vcproj", "{F387003D-4CE3-7548-A471-3C2D188AB7D3}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} = {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_joints", "./demo_joints.vcproj", "{B05FDE9B-2066-9A49-A286-52FA07638F67}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} = {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_motor", "./demo_motor.vcproj", "{94367E2E-BAD6-C04F-9929-77D2FFFD945B}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} = {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_ode", "./demo_ode.vcproj", "{26876866-6691-1C48-BB6A-2CF14E2E2B16}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} = {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_plane2d", "./demo_plane2d.vcproj", "{4C672D5A-F87B-C645-8CA2-A9F4BF94525A}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} = {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_slider", "./demo_slider.vcproj", "{5621B59B-14FB-5741-8F14-90A0865161F8}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} = {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_space", "./demo_space.vcproj", "{8C77C726-B2ED-3745-9433-FF91E9D2556F}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} = {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_space_stress", "./demo_space_stress.vcproj", "{CE00A8A1-848B-9448-9A86-03F518195687}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} = {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_step", "./demo_step.vcproj", "{441E2B42-D9D5-FD48-872E-1F547FEFEC1D}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} = {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_basket", "./demo_basket.vcproj", "{658A5390-4A5E-5A48-9A10-B04A53848994}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} = {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_cyl", "./demo_cyl.vcproj", "{3E62DE94-D6E5-0F42-A99B-CAA0139E7C82}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} = {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_moving_trimesh", "./demo_moving_trimesh.vcproj", "{94C25B7D-977F-E744-A255-2554C19771A8}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} = {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_trimesh", "./demo_trimesh.vcproj", "{01532891-8699-8846-9409-0DADE3A53422}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} = {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_cylvssphere", "./demo_cylvssphere.vcproj", "{9419B36B-EB65-8F4C-9E29-9DE728FEF4BA}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} = {029C9CCD-2B3E-BE45-8520-A231CD8C67EC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests", "./tests.vcproj", "{65028345-CDF4-B74C-B94F-8F4A0493D8C4}" + ProjectSection(ProjectDependencies) = postProject + {5F0953F1-B966-BA4E-A31A-C002A407FD47} = {5F0953F1-B966-BA4E-A31A-C002A407FD47} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + DebugDLL = DebugDLL + ReleaseDLL = ReleaseDLL + DebugLib = DebugLib + ReleaseLib = ReleaseLib + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {5F0953F1-B966-BA4E-A31A-C002A407FD47}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {5F0953F1-B966-BA4E-A31A-C002A407FD47}.DebugDLL.Build.0 = DebugDLL|Win32 + {5F0953F1-B966-BA4E-A31A-C002A407FD47}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {5F0953F1-B966-BA4E-A31A-C002A407FD47}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {5F0953F1-B966-BA4E-A31A-C002A407FD47}.DebugLib.ActiveCfg = DebugLib|Win32 + {5F0953F1-B966-BA4E-A31A-C002A407FD47}.DebugLib.Build.0 = DebugLib|Win32 + {5F0953F1-B966-BA4E-A31A-C002A407FD47}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {5F0953F1-B966-BA4E-A31A-C002A407FD47}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC}.DebugDLL.Build.0 = DebugDLL|Win32 + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC}.DebugLib.ActiveCfg = DebugLib|Win32 + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC}.DebugLib.Build.0 = DebugLib|Win32 + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {029C9CCD-2B3E-BE45-8520-A231CD8C67EC}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {F25F1B18-2103-B147-A5F0-984D0D1EBBDA}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {F25F1B18-2103-B147-A5F0-984D0D1EBBDA}.DebugDLL.Build.0 = DebugDLL|Win32 + {F25F1B18-2103-B147-A5F0-984D0D1EBBDA}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {F25F1B18-2103-B147-A5F0-984D0D1EBBDA}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {F25F1B18-2103-B147-A5F0-984D0D1EBBDA}.DebugLib.ActiveCfg = DebugLib|Win32 + {F25F1B18-2103-B147-A5F0-984D0D1EBBDA}.DebugLib.Build.0 = DebugLib|Win32 + {F25F1B18-2103-B147-A5F0-984D0D1EBBDA}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {F25F1B18-2103-B147-A5F0-984D0D1EBBDA}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {79FFAF28-2FD1-6744-909F-7F7E68DDEB6D}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {79FFAF28-2FD1-6744-909F-7F7E68DDEB6D}.DebugDLL.Build.0 = DebugDLL|Win32 + {79FFAF28-2FD1-6744-909F-7F7E68DDEB6D}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {79FFAF28-2FD1-6744-909F-7F7E68DDEB6D}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {79FFAF28-2FD1-6744-909F-7F7E68DDEB6D}.DebugLib.ActiveCfg = DebugLib|Win32 + {79FFAF28-2FD1-6744-909F-7F7E68DDEB6D}.DebugLib.Build.0 = DebugLib|Win32 + {79FFAF28-2FD1-6744-909F-7F7E68DDEB6D}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {79FFAF28-2FD1-6744-909F-7F7E68DDEB6D}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {DC6294E4-6A55-1D41-9846-53EC913D0DC3}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {DC6294E4-6A55-1D41-9846-53EC913D0DC3}.DebugDLL.Build.0 = DebugDLL|Win32 + {DC6294E4-6A55-1D41-9846-53EC913D0DC3}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {DC6294E4-6A55-1D41-9846-53EC913D0DC3}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {DC6294E4-6A55-1D41-9846-53EC913D0DC3}.DebugLib.ActiveCfg = DebugLib|Win32 + {DC6294E4-6A55-1D41-9846-53EC913D0DC3}.DebugLib.Build.0 = DebugLib|Win32 + {DC6294E4-6A55-1D41-9846-53EC913D0DC3}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {DC6294E4-6A55-1D41-9846-53EC913D0DC3}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {D01EDE86-5B74-A24B-B084-FC79608D376D}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {D01EDE86-5B74-A24B-B084-FC79608D376D}.DebugDLL.Build.0 = DebugDLL|Win32 + {D01EDE86-5B74-A24B-B084-FC79608D376D}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {D01EDE86-5B74-A24B-B084-FC79608D376D}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {D01EDE86-5B74-A24B-B084-FC79608D376D}.DebugLib.ActiveCfg = DebugLib|Win32 + {D01EDE86-5B74-A24B-B084-FC79608D376D}.DebugLib.Build.0 = DebugLib|Win32 + {D01EDE86-5B74-A24B-B084-FC79608D376D}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {D01EDE86-5B74-A24B-B084-FC79608D376D}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {238F8FBA-C48F-694E-9D78-6D99DA572645}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {238F8FBA-C48F-694E-9D78-6D99DA572645}.DebugDLL.Build.0 = DebugDLL|Win32 + {238F8FBA-C48F-694E-9D78-6D99DA572645}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {238F8FBA-C48F-694E-9D78-6D99DA572645}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {238F8FBA-C48F-694E-9D78-6D99DA572645}.DebugLib.ActiveCfg = DebugLib|Win32 + {238F8FBA-C48F-694E-9D78-6D99DA572645}.DebugLib.Build.0 = DebugLib|Win32 + {238F8FBA-C48F-694E-9D78-6D99DA572645}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {238F8FBA-C48F-694E-9D78-6D99DA572645}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {4D828A55-6AAD-B948-8817-38EB3E85F504}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {4D828A55-6AAD-B948-8817-38EB3E85F504}.DebugDLL.Build.0 = DebugDLL|Win32 + {4D828A55-6AAD-B948-8817-38EB3E85F504}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {4D828A55-6AAD-B948-8817-38EB3E85F504}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {4D828A55-6AAD-B948-8817-38EB3E85F504}.DebugLib.ActiveCfg = DebugLib|Win32 + {4D828A55-6AAD-B948-8817-38EB3E85F504}.DebugLib.Build.0 = DebugLib|Win32 + {4D828A55-6AAD-B948-8817-38EB3E85F504}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {4D828A55-6AAD-B948-8817-38EB3E85F504}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {2CFE9EEA-E735-BD49-96FF-34C2C3893AC7}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {2CFE9EEA-E735-BD49-96FF-34C2C3893AC7}.DebugDLL.Build.0 = DebugDLL|Win32 + {2CFE9EEA-E735-BD49-96FF-34C2C3893AC7}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {2CFE9EEA-E735-BD49-96FF-34C2C3893AC7}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {2CFE9EEA-E735-BD49-96FF-34C2C3893AC7}.DebugLib.ActiveCfg = DebugLib|Win32 + {2CFE9EEA-E735-BD49-96FF-34C2C3893AC7}.DebugLib.Build.0 = DebugLib|Win32 + {2CFE9EEA-E735-BD49-96FF-34C2C3893AC7}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {2CFE9EEA-E735-BD49-96FF-34C2C3893AC7}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {ECE402AB-3062-6745-AC2A-85BB65CA000F}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {ECE402AB-3062-6745-AC2A-85BB65CA000F}.DebugDLL.Build.0 = DebugDLL|Win32 + {ECE402AB-3062-6745-AC2A-85BB65CA000F}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {ECE402AB-3062-6745-AC2A-85BB65CA000F}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {ECE402AB-3062-6745-AC2A-85BB65CA000F}.DebugLib.ActiveCfg = DebugLib|Win32 + {ECE402AB-3062-6745-AC2A-85BB65CA000F}.DebugLib.Build.0 = DebugLib|Win32 + {ECE402AB-3062-6745-AC2A-85BB65CA000F}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {ECE402AB-3062-6745-AC2A-85BB65CA000F}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {D746A3DA-E7D4-6A4A-B078-D5E5A79CFB5F}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {D746A3DA-E7D4-6A4A-B078-D5E5A79CFB5F}.DebugDLL.Build.0 = DebugDLL|Win32 + {D746A3DA-E7D4-6A4A-B078-D5E5A79CFB5F}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {D746A3DA-E7D4-6A4A-B078-D5E5A79CFB5F}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {D746A3DA-E7D4-6A4A-B078-D5E5A79CFB5F}.DebugLib.ActiveCfg = DebugLib|Win32 + {D746A3DA-E7D4-6A4A-B078-D5E5A79CFB5F}.DebugLib.Build.0 = DebugLib|Win32 + {D746A3DA-E7D4-6A4A-B078-D5E5A79CFB5F}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {D746A3DA-E7D4-6A4A-B078-D5E5A79CFB5F}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {1F4FB263-EF66-F247-807C-30DA768C7072}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {1F4FB263-EF66-F247-807C-30DA768C7072}.DebugDLL.Build.0 = DebugDLL|Win32 + {1F4FB263-EF66-F247-807C-30DA768C7072}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {1F4FB263-EF66-F247-807C-30DA768C7072}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {1F4FB263-EF66-F247-807C-30DA768C7072}.DebugLib.ActiveCfg = DebugLib|Win32 + {1F4FB263-EF66-F247-807C-30DA768C7072}.DebugLib.Build.0 = DebugLib|Win32 + {1F4FB263-EF66-F247-807C-30DA768C7072}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {1F4FB263-EF66-F247-807C-30DA768C7072}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {F387003D-4CE3-7548-A471-3C2D188AB7D3}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {F387003D-4CE3-7548-A471-3C2D188AB7D3}.DebugDLL.Build.0 = DebugDLL|Win32 + {F387003D-4CE3-7548-A471-3C2D188AB7D3}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {F387003D-4CE3-7548-A471-3C2D188AB7D3}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {F387003D-4CE3-7548-A471-3C2D188AB7D3}.DebugLib.ActiveCfg = DebugLib|Win32 + {F387003D-4CE3-7548-A471-3C2D188AB7D3}.DebugLib.Build.0 = DebugLib|Win32 + {F387003D-4CE3-7548-A471-3C2D188AB7D3}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {F387003D-4CE3-7548-A471-3C2D188AB7D3}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {B05FDE9B-2066-9A49-A286-52FA07638F67}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {B05FDE9B-2066-9A49-A286-52FA07638F67}.DebugDLL.Build.0 = DebugDLL|Win32 + {B05FDE9B-2066-9A49-A286-52FA07638F67}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {B05FDE9B-2066-9A49-A286-52FA07638F67}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {B05FDE9B-2066-9A49-A286-52FA07638F67}.DebugLib.ActiveCfg = DebugLib|Win32 + {B05FDE9B-2066-9A49-A286-52FA07638F67}.DebugLib.Build.0 = DebugLib|Win32 + {B05FDE9B-2066-9A49-A286-52FA07638F67}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {B05FDE9B-2066-9A49-A286-52FA07638F67}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {94367E2E-BAD6-C04F-9929-77D2FFFD945B}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {94367E2E-BAD6-C04F-9929-77D2FFFD945B}.DebugDLL.Build.0 = DebugDLL|Win32 + {94367E2E-BAD6-C04F-9929-77D2FFFD945B}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {94367E2E-BAD6-C04F-9929-77D2FFFD945B}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {94367E2E-BAD6-C04F-9929-77D2FFFD945B}.DebugLib.ActiveCfg = DebugLib|Win32 + {94367E2E-BAD6-C04F-9929-77D2FFFD945B}.DebugLib.Build.0 = DebugLib|Win32 + {94367E2E-BAD6-C04F-9929-77D2FFFD945B}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {94367E2E-BAD6-C04F-9929-77D2FFFD945B}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {26876866-6691-1C48-BB6A-2CF14E2E2B16}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {26876866-6691-1C48-BB6A-2CF14E2E2B16}.DebugDLL.Build.0 = DebugDLL|Win32 + {26876866-6691-1C48-BB6A-2CF14E2E2B16}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {26876866-6691-1C48-BB6A-2CF14E2E2B16}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {26876866-6691-1C48-BB6A-2CF14E2E2B16}.DebugLib.ActiveCfg = DebugLib|Win32 + {26876866-6691-1C48-BB6A-2CF14E2E2B16}.DebugLib.Build.0 = DebugLib|Win32 + {26876866-6691-1C48-BB6A-2CF14E2E2B16}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {26876866-6691-1C48-BB6A-2CF14E2E2B16}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {4C672D5A-F87B-C645-8CA2-A9F4BF94525A}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {4C672D5A-F87B-C645-8CA2-A9F4BF94525A}.DebugDLL.Build.0 = DebugDLL|Win32 + {4C672D5A-F87B-C645-8CA2-A9F4BF94525A}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {4C672D5A-F87B-C645-8CA2-A9F4BF94525A}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {4C672D5A-F87B-C645-8CA2-A9F4BF94525A}.DebugLib.ActiveCfg = DebugLib|Win32 + {4C672D5A-F87B-C645-8CA2-A9F4BF94525A}.DebugLib.Build.0 = DebugLib|Win32 + {4C672D5A-F87B-C645-8CA2-A9F4BF94525A}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {4C672D5A-F87B-C645-8CA2-A9F4BF94525A}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {5621B59B-14FB-5741-8F14-90A0865161F8}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {5621B59B-14FB-5741-8F14-90A0865161F8}.DebugDLL.Build.0 = DebugDLL|Win32 + {5621B59B-14FB-5741-8F14-90A0865161F8}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {5621B59B-14FB-5741-8F14-90A0865161F8}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {5621B59B-14FB-5741-8F14-90A0865161F8}.DebugLib.ActiveCfg = DebugLib|Win32 + {5621B59B-14FB-5741-8F14-90A0865161F8}.DebugLib.Build.0 = DebugLib|Win32 + {5621B59B-14FB-5741-8F14-90A0865161F8}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {5621B59B-14FB-5741-8F14-90A0865161F8}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {8C77C726-B2ED-3745-9433-FF91E9D2556F}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {8C77C726-B2ED-3745-9433-FF91E9D2556F}.DebugDLL.Build.0 = DebugDLL|Win32 + {8C77C726-B2ED-3745-9433-FF91E9D2556F}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {8C77C726-B2ED-3745-9433-FF91E9D2556F}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {8C77C726-B2ED-3745-9433-FF91E9D2556F}.DebugLib.ActiveCfg = DebugLib|Win32 + {8C77C726-B2ED-3745-9433-FF91E9D2556F}.DebugLib.Build.0 = DebugLib|Win32 + {8C77C726-B2ED-3745-9433-FF91E9D2556F}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {8C77C726-B2ED-3745-9433-FF91E9D2556F}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {CE00A8A1-848B-9448-9A86-03F518195687}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {CE00A8A1-848B-9448-9A86-03F518195687}.DebugDLL.Build.0 = DebugDLL|Win32 + {CE00A8A1-848B-9448-9A86-03F518195687}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {CE00A8A1-848B-9448-9A86-03F518195687}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {CE00A8A1-848B-9448-9A86-03F518195687}.DebugLib.ActiveCfg = DebugLib|Win32 + {CE00A8A1-848B-9448-9A86-03F518195687}.DebugLib.Build.0 = DebugLib|Win32 + {CE00A8A1-848B-9448-9A86-03F518195687}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {CE00A8A1-848B-9448-9A86-03F518195687}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {441E2B42-D9D5-FD48-872E-1F547FEFEC1D}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {441E2B42-D9D5-FD48-872E-1F547FEFEC1D}.DebugDLL.Build.0 = DebugDLL|Win32 + {441E2B42-D9D5-FD48-872E-1F547FEFEC1D}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {441E2B42-D9D5-FD48-872E-1F547FEFEC1D}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {441E2B42-D9D5-FD48-872E-1F547FEFEC1D}.DebugLib.ActiveCfg = DebugLib|Win32 + {441E2B42-D9D5-FD48-872E-1F547FEFEC1D}.DebugLib.Build.0 = DebugLib|Win32 + {441E2B42-D9D5-FD48-872E-1F547FEFEC1D}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {441E2B42-D9D5-FD48-872E-1F547FEFEC1D}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {658A5390-4A5E-5A48-9A10-B04A53848994}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {658A5390-4A5E-5A48-9A10-B04A53848994}.DebugDLL.Build.0 = DebugDLL|Win32 + {658A5390-4A5E-5A48-9A10-B04A53848994}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {658A5390-4A5E-5A48-9A10-B04A53848994}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {658A5390-4A5E-5A48-9A10-B04A53848994}.DebugLib.ActiveCfg = DebugLib|Win32 + {658A5390-4A5E-5A48-9A10-B04A53848994}.DebugLib.Build.0 = DebugLib|Win32 + {658A5390-4A5E-5A48-9A10-B04A53848994}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {658A5390-4A5E-5A48-9A10-B04A53848994}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {3E62DE94-D6E5-0F42-A99B-CAA0139E7C82}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {3E62DE94-D6E5-0F42-A99B-CAA0139E7C82}.DebugDLL.Build.0 = DebugDLL|Win32 + {3E62DE94-D6E5-0F42-A99B-CAA0139E7C82}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {3E62DE94-D6E5-0F42-A99B-CAA0139E7C82}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {3E62DE94-D6E5-0F42-A99B-CAA0139E7C82}.DebugLib.ActiveCfg = DebugLib|Win32 + {3E62DE94-D6E5-0F42-A99B-CAA0139E7C82}.DebugLib.Build.0 = DebugLib|Win32 + {3E62DE94-D6E5-0F42-A99B-CAA0139E7C82}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {3E62DE94-D6E5-0F42-A99B-CAA0139E7C82}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {94C25B7D-977F-E744-A255-2554C19771A8}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {94C25B7D-977F-E744-A255-2554C19771A8}.DebugDLL.Build.0 = DebugDLL|Win32 + {94C25B7D-977F-E744-A255-2554C19771A8}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {94C25B7D-977F-E744-A255-2554C19771A8}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {94C25B7D-977F-E744-A255-2554C19771A8}.DebugLib.ActiveCfg = DebugLib|Win32 + {94C25B7D-977F-E744-A255-2554C19771A8}.DebugLib.Build.0 = DebugLib|Win32 + {94C25B7D-977F-E744-A255-2554C19771A8}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {94C25B7D-977F-E744-A255-2554C19771A8}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {01532891-8699-8846-9409-0DADE3A53422}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {01532891-8699-8846-9409-0DADE3A53422}.DebugDLL.Build.0 = DebugDLL|Win32 + {01532891-8699-8846-9409-0DADE3A53422}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {01532891-8699-8846-9409-0DADE3A53422}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {01532891-8699-8846-9409-0DADE3A53422}.DebugLib.ActiveCfg = DebugLib|Win32 + {01532891-8699-8846-9409-0DADE3A53422}.DebugLib.Build.0 = DebugLib|Win32 + {01532891-8699-8846-9409-0DADE3A53422}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {01532891-8699-8846-9409-0DADE3A53422}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {9419B36B-EB65-8F4C-9E29-9DE728FEF4BA}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {9419B36B-EB65-8F4C-9E29-9DE728FEF4BA}.DebugDLL.Build.0 = DebugDLL|Win32 + {9419B36B-EB65-8F4C-9E29-9DE728FEF4BA}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {9419B36B-EB65-8F4C-9E29-9DE728FEF4BA}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {9419B36B-EB65-8F4C-9E29-9DE728FEF4BA}.DebugLib.ActiveCfg = DebugLib|Win32 + {9419B36B-EB65-8F4C-9E29-9DE728FEF4BA}.DebugLib.Build.0 = DebugLib|Win32 + {9419B36B-EB65-8F4C-9E29-9DE728FEF4BA}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {9419B36B-EB65-8F4C-9E29-9DE728FEF4BA}.ReleaseLib.Build.0 = ReleaseLib|Win32 + {65028345-CDF4-B74C-B94F-8F4A0493D8C4}.DebugDLL.ActiveCfg = DebugDLL|Win32 + {65028345-CDF4-B74C-B94F-8F4A0493D8C4}.DebugDLL.Build.0 = DebugDLL|Win32 + {65028345-CDF4-B74C-B94F-8F4A0493D8C4}.ReleaseDLL.ActiveCfg = ReleaseDLL|Win32 + {65028345-CDF4-B74C-B94F-8F4A0493D8C4}.ReleaseDLL.Build.0 = ReleaseDLL|Win32 + {65028345-CDF4-B74C-B94F-8F4A0493D8C4}.DebugLib.ActiveCfg = DebugLib|Win32 + {65028345-CDF4-B74C-B94F-8F4A0493D8C4}.DebugLib.Build.0 = DebugLib|Win32 + {65028345-CDF4-B74C-B94F-8F4A0493D8C4}.ReleaseLib.ActiveCfg = ReleaseLib|Win32 + {65028345-CDF4-B74C-B94F-8F4A0493D8C4}.ReleaseLib.Build.0 = ReleaseLib|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/libraries/ode-0.9/build/vs2003/ode.vcproj b/libraries/ode-0.9/build/vs2003/ode.vcproj new file mode 100644 index 0000000000..80bed8ec7d --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/ode.vcproj @@ -0,0 +1,890 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2003/tests.vcproj b/libraries/ode-0.9/build/vs2003/tests.vcproj new file mode 100644 index 0000000000..1010093fc7 --- /dev/null +++ b/libraries/ode-0.9/build/vs2003/tests.vcproj @@ -0,0 +1,322 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/demo_I.vcproj b/libraries/ode-0.9/build/vs2005/demo_I.vcproj new file mode 100644 index 0000000000..106aeded05 --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/demo_I.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/demo_basket.vcproj b/libraries/ode-0.9/build/vs2005/demo_basket.vcproj new file mode 100644 index 0000000000..d19403dd76 --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/demo_basket.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/demo_boxstack.vcproj b/libraries/ode-0.9/build/vs2005/demo_boxstack.vcproj new file mode 100644 index 0000000000..ff91d078c0 --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/demo_boxstack.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/demo_buggy.vcproj b/libraries/ode-0.9/build/vs2005/demo_buggy.vcproj new file mode 100644 index 0000000000..88d5e44d34 --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/demo_buggy.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/demo_chain1.vcproj b/libraries/ode-0.9/build/vs2005/demo_chain1.vcproj new file mode 100644 index 0000000000..daa8ac8123 --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/demo_chain1.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/demo_chain2.vcproj b/libraries/ode-0.9/build/vs2005/demo_chain2.vcproj new file mode 100644 index 0000000000..5549d98813 --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/demo_chain2.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/demo_collision.vcproj b/libraries/ode-0.9/build/vs2005/demo_collision.vcproj new file mode 100644 index 0000000000..d20edf8d6b --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/demo_collision.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/demo_crash.vcproj b/libraries/ode-0.9/build/vs2005/demo_crash.vcproj new file mode 100644 index 0000000000..d8725875c2 --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/demo_crash.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/demo_cyl.vcproj b/libraries/ode-0.9/build/vs2005/demo_cyl.vcproj new file mode 100644 index 0000000000..e6fac4f65e --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/demo_cyl.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/demo_cylvssphere.vcproj b/libraries/ode-0.9/build/vs2005/demo_cylvssphere.vcproj new file mode 100644 index 0000000000..686c830f60 --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/demo_cylvssphere.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/demo_feedback.vcproj b/libraries/ode-0.9/build/vs2005/demo_feedback.vcproj new file mode 100644 index 0000000000..fb949f26f7 --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/demo_feedback.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/demo_friction.vcproj b/libraries/ode-0.9/build/vs2005/demo_friction.vcproj new file mode 100644 index 0000000000..29983a5300 --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/demo_friction.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/demo_heightfield.vcproj b/libraries/ode-0.9/build/vs2005/demo_heightfield.vcproj new file mode 100644 index 0000000000..463ebd0145 --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/demo_heightfield.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/demo_hinge.vcproj b/libraries/ode-0.9/build/vs2005/demo_hinge.vcproj new file mode 100644 index 0000000000..c1ed4e9445 --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/demo_hinge.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/demo_joints.vcproj b/libraries/ode-0.9/build/vs2005/demo_joints.vcproj new file mode 100644 index 0000000000..6fa43d04a1 --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/demo_joints.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/demo_motor.vcproj b/libraries/ode-0.9/build/vs2005/demo_motor.vcproj new file mode 100644 index 0000000000..751c057690 --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/demo_motor.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/demo_moving_trimesh.vcproj b/libraries/ode-0.9/build/vs2005/demo_moving_trimesh.vcproj new file mode 100644 index 0000000000..da66c0f91d --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/demo_moving_trimesh.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/demo_ode.vcproj b/libraries/ode-0.9/build/vs2005/demo_ode.vcproj new file mode 100644 index 0000000000..e9afccd936 --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/demo_ode.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/demo_plane2d.vcproj b/libraries/ode-0.9/build/vs2005/demo_plane2d.vcproj new file mode 100644 index 0000000000..226f51e022 --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/demo_plane2d.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/demo_slider.vcproj b/libraries/ode-0.9/build/vs2005/demo_slider.vcproj new file mode 100644 index 0000000000..16a8dd8ea5 --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/demo_slider.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/demo_space.vcproj b/libraries/ode-0.9/build/vs2005/demo_space.vcproj new file mode 100644 index 0000000000..e65fd64f03 --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/demo_space.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/demo_space_stress.vcproj b/libraries/ode-0.9/build/vs2005/demo_space_stress.vcproj new file mode 100644 index 0000000000..43dd6c1aff --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/demo_space_stress.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/demo_step.vcproj b/libraries/ode-0.9/build/vs2005/demo_step.vcproj new file mode 100644 index 0000000000..37a4cac39e --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/demo_step.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/demo_trimesh.vcproj b/libraries/ode-0.9/build/vs2005/demo_trimesh.vcproj new file mode 100644 index 0000000000..09a1ed8cb3 --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/demo_trimesh.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/drawstuff.vcproj b/libraries/ode-0.9/build/vs2005/drawstuff.vcproj new file mode 100644 index 0000000000..ecbdbed0d0 --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/drawstuff.vcproj @@ -0,0 +1,387 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/ode.sln b/libraries/ode-0.9/build/vs2005/ode.sln new file mode 100644 index 0000000000..a7a623f75d --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/ode.sln @@ -0,0 +1,388 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ode", "./ode.vcproj", "{2A8430BA-889E-EE4A-B1E3-A3231F6816EE}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "drawstuff", "./drawstuff.vcproj", "{B855BC68-59AE-BD44-82BB-88183332A6D9}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_boxstack", "./demo_boxstack.vcproj", "{A71669E5-246A-794A-B2C2-646946E9EE64}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + {B855BC68-59AE-BD44-82BB-88183332A6D9} = {B855BC68-59AE-BD44-82BB-88183332A6D9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_buggy", "./demo_buggy.vcproj", "{081B462D-C222-144C-AF0C-384C47BE98D2}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + {B855BC68-59AE-BD44-82BB-88183332A6D9} = {B855BC68-59AE-BD44-82BB-88183332A6D9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_chain1", "./demo_chain1.vcproj", "{D329C439-EF31-4641-9B34-4DE23174C997}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + {B855BC68-59AE-BD44-82BB-88183332A6D9} = {B855BC68-59AE-BD44-82BB-88183332A6D9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_chain2", "./demo_chain2.vcproj", "{B27B11A1-72EB-8149-ABF2-63A9D7E05CA2}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + {B855BC68-59AE-BD44-82BB-88183332A6D9} = {B855BC68-59AE-BD44-82BB-88183332A6D9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_collision", "./demo_collision.vcproj", "{9C1C9F02-11C4-514C-AF5C-1CB45A31E1A9}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + {B855BC68-59AE-BD44-82BB-88183332A6D9} = {B855BC68-59AE-BD44-82BB-88183332A6D9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_crash", "./demo_crash.vcproj", "{1478BD02-E2D4-1046-AD1C-63E59DD228BC}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + {B855BC68-59AE-BD44-82BB-88183332A6D9} = {B855BC68-59AE-BD44-82BB-88183332A6D9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_feedback", "./demo_feedback.vcproj", "{B8BC0F67-D7F2-7F4E-8314-5EAAECCD671C}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + {B855BC68-59AE-BD44-82BB-88183332A6D9} = {B855BC68-59AE-BD44-82BB-88183332A6D9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_friction", "./demo_friction.vcproj", "{BAD97423-A545-814E-8CCC-32603D25E6D4}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + {B855BC68-59AE-BD44-82BB-88183332A6D9} = {B855BC68-59AE-BD44-82BB-88183332A6D9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_heightfield", "./demo_heightfield.vcproj", "{5DDFAAD0-23AC-9A42-AA5E-31B8E8E68CA0}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + {B855BC68-59AE-BD44-82BB-88183332A6D9} = {B855BC68-59AE-BD44-82BB-88183332A6D9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_hinge", "./demo_hinge.vcproj", "{DFD3F85E-944E-7740-A29F-715891AF8262}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + {B855BC68-59AE-BD44-82BB-88183332A6D9} = {B855BC68-59AE-BD44-82BB-88183332A6D9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_I", "./demo_I.vcproj", "{D03ABAA3-4C58-674E-B545-4AE8E993A57A}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + {B855BC68-59AE-BD44-82BB-88183332A6D9} = {B855BC68-59AE-BD44-82BB-88183332A6D9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_joints", "./demo_joints.vcproj", "{0F6BA7D9-8481-D34C-9CA7-C69AC15DCE4C}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + {B855BC68-59AE-BD44-82BB-88183332A6D9} = {B855BC68-59AE-BD44-82BB-88183332A6D9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_motor", "./demo_motor.vcproj", "{D63DCF21-8421-044C-910F-9758DFF417D0}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + {B855BC68-59AE-BD44-82BB-88183332A6D9} = {B855BC68-59AE-BD44-82BB-88183332A6D9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_ode", "./demo_ode.vcproj", "{B8D35A81-5E45-744C-BABD-BFCAA4CBF36E}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + {B855BC68-59AE-BD44-82BB-88183332A6D9} = {B855BC68-59AE-BD44-82BB-88183332A6D9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_plane2d", "./demo_plane2d.vcproj", "{BCF62E98-514B-254D-95C5-CEBF06A37108}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + {B855BC68-59AE-BD44-82BB-88183332A6D9} = {B855BC68-59AE-BD44-82BB-88183332A6D9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_slider", "./demo_slider.vcproj", "{B8043AEB-91BD-4D49-B580-D480DC1B979F}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + {B855BC68-59AE-BD44-82BB-88183332A6D9} = {B855BC68-59AE-BD44-82BB-88183332A6D9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_space", "./demo_space.vcproj", "{6DCB0D01-0638-0244-BEB9-A313999D14E9}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + {B855BC68-59AE-BD44-82BB-88183332A6D9} = {B855BC68-59AE-BD44-82BB-88183332A6D9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_space_stress", "./demo_space_stress.vcproj", "{29A4883C-6553-4D48-8FFC-10382F07DA72}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + {B855BC68-59AE-BD44-82BB-88183332A6D9} = {B855BC68-59AE-BD44-82BB-88183332A6D9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_step", "./demo_step.vcproj", "{D1B53AFE-F148-194C-B3A1-8386C9B25359}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + {B855BC68-59AE-BD44-82BB-88183332A6D9} = {B855BC68-59AE-BD44-82BB-88183332A6D9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_basket", "./demo_basket.vcproj", "{FE66E49C-CF34-5F4B-B43C-9A0C89185222}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + {B855BC68-59AE-BD44-82BB-88183332A6D9} = {B855BC68-59AE-BD44-82BB-88183332A6D9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_cyl", "./demo_cyl.vcproj", "{EA15C089-307B-8B4A-A598-0E06C82ADB1E}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + {B855BC68-59AE-BD44-82BB-88183332A6D9} = {B855BC68-59AE-BD44-82BB-88183332A6D9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_moving_trimesh", "./demo_moving_trimesh.vcproj", "{BE3117C9-B067-0A4B-920D-7F3C00374BA0}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + {B855BC68-59AE-BD44-82BB-88183332A6D9} = {B855BC68-59AE-BD44-82BB-88183332A6D9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_trimesh", "./demo_trimesh.vcproj", "{13D33F5C-1C2C-D740-A28A-BCFD15616E75}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + {B855BC68-59AE-BD44-82BB-88183332A6D9} = {B855BC68-59AE-BD44-82BB-88183332A6D9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "demo_cylvssphere", "./demo_cylvssphere.vcproj", "{FA871426-5142-F646-B3D2-3AF70E784D68}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + {B855BC68-59AE-BD44-82BB-88183332A6D9} = {B855BC68-59AE-BD44-82BB-88183332A6D9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests", "./tests.vcproj", "{EA829A28-B1B2-1345-98B9-897763B937AF}" + ProjectSection(ProjectDependencies) = postProject + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} = {2A8430BA-889E-EE4A-B1E3-A3231F6816EE} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + DebugDLL|Win32 = DebugDLL|Win32 + ReleaseDLL|Win32 = ReleaseDLL|Win32 + DebugLib|Win32 = DebugLib|Win32 + ReleaseLib|Win32 = ReleaseLib|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {2A8430BA-889E-EE4A-B1E3-A3231F6816EE}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {B855BC68-59AE-BD44-82BB-88183332A6D9}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {B855BC68-59AE-BD44-82BB-88183332A6D9}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {B855BC68-59AE-BD44-82BB-88183332A6D9}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {B855BC68-59AE-BD44-82BB-88183332A6D9}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {B855BC68-59AE-BD44-82BB-88183332A6D9}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {B855BC68-59AE-BD44-82BB-88183332A6D9}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {B855BC68-59AE-BD44-82BB-88183332A6D9}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {B855BC68-59AE-BD44-82BB-88183332A6D9}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {A71669E5-246A-794A-B2C2-646946E9EE64}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {A71669E5-246A-794A-B2C2-646946E9EE64}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {A71669E5-246A-794A-B2C2-646946E9EE64}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {A71669E5-246A-794A-B2C2-646946E9EE64}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {A71669E5-246A-794A-B2C2-646946E9EE64}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {A71669E5-246A-794A-B2C2-646946E9EE64}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {A71669E5-246A-794A-B2C2-646946E9EE64}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {A71669E5-246A-794A-B2C2-646946E9EE64}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {081B462D-C222-144C-AF0C-384C47BE98D2}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {081B462D-C222-144C-AF0C-384C47BE98D2}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {081B462D-C222-144C-AF0C-384C47BE98D2}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {081B462D-C222-144C-AF0C-384C47BE98D2}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {081B462D-C222-144C-AF0C-384C47BE98D2}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {081B462D-C222-144C-AF0C-384C47BE98D2}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {081B462D-C222-144C-AF0C-384C47BE98D2}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {081B462D-C222-144C-AF0C-384C47BE98D2}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {D329C439-EF31-4641-9B34-4DE23174C997}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {D329C439-EF31-4641-9B34-4DE23174C997}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {D329C439-EF31-4641-9B34-4DE23174C997}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {D329C439-EF31-4641-9B34-4DE23174C997}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {D329C439-EF31-4641-9B34-4DE23174C997}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {D329C439-EF31-4641-9B34-4DE23174C997}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {D329C439-EF31-4641-9B34-4DE23174C997}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {D329C439-EF31-4641-9B34-4DE23174C997}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {B27B11A1-72EB-8149-ABF2-63A9D7E05CA2}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {B27B11A1-72EB-8149-ABF2-63A9D7E05CA2}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {B27B11A1-72EB-8149-ABF2-63A9D7E05CA2}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {B27B11A1-72EB-8149-ABF2-63A9D7E05CA2}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {B27B11A1-72EB-8149-ABF2-63A9D7E05CA2}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {B27B11A1-72EB-8149-ABF2-63A9D7E05CA2}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {B27B11A1-72EB-8149-ABF2-63A9D7E05CA2}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {B27B11A1-72EB-8149-ABF2-63A9D7E05CA2}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {9C1C9F02-11C4-514C-AF5C-1CB45A31E1A9}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {9C1C9F02-11C4-514C-AF5C-1CB45A31E1A9}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {9C1C9F02-11C4-514C-AF5C-1CB45A31E1A9}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {9C1C9F02-11C4-514C-AF5C-1CB45A31E1A9}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {9C1C9F02-11C4-514C-AF5C-1CB45A31E1A9}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {9C1C9F02-11C4-514C-AF5C-1CB45A31E1A9}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {9C1C9F02-11C4-514C-AF5C-1CB45A31E1A9}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {9C1C9F02-11C4-514C-AF5C-1CB45A31E1A9}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {1478BD02-E2D4-1046-AD1C-63E59DD228BC}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {1478BD02-E2D4-1046-AD1C-63E59DD228BC}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {1478BD02-E2D4-1046-AD1C-63E59DD228BC}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {1478BD02-E2D4-1046-AD1C-63E59DD228BC}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {1478BD02-E2D4-1046-AD1C-63E59DD228BC}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {1478BD02-E2D4-1046-AD1C-63E59DD228BC}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {1478BD02-E2D4-1046-AD1C-63E59DD228BC}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {1478BD02-E2D4-1046-AD1C-63E59DD228BC}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {B8BC0F67-D7F2-7F4E-8314-5EAAECCD671C}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {B8BC0F67-D7F2-7F4E-8314-5EAAECCD671C}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {B8BC0F67-D7F2-7F4E-8314-5EAAECCD671C}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {B8BC0F67-D7F2-7F4E-8314-5EAAECCD671C}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {B8BC0F67-D7F2-7F4E-8314-5EAAECCD671C}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {B8BC0F67-D7F2-7F4E-8314-5EAAECCD671C}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {B8BC0F67-D7F2-7F4E-8314-5EAAECCD671C}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {B8BC0F67-D7F2-7F4E-8314-5EAAECCD671C}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {BAD97423-A545-814E-8CCC-32603D25E6D4}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {BAD97423-A545-814E-8CCC-32603D25E6D4}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {BAD97423-A545-814E-8CCC-32603D25E6D4}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {BAD97423-A545-814E-8CCC-32603D25E6D4}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {BAD97423-A545-814E-8CCC-32603D25E6D4}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {BAD97423-A545-814E-8CCC-32603D25E6D4}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {BAD97423-A545-814E-8CCC-32603D25E6D4}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {BAD97423-A545-814E-8CCC-32603D25E6D4}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {5DDFAAD0-23AC-9A42-AA5E-31B8E8E68CA0}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {5DDFAAD0-23AC-9A42-AA5E-31B8E8E68CA0}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {5DDFAAD0-23AC-9A42-AA5E-31B8E8E68CA0}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {5DDFAAD0-23AC-9A42-AA5E-31B8E8E68CA0}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {5DDFAAD0-23AC-9A42-AA5E-31B8E8E68CA0}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {5DDFAAD0-23AC-9A42-AA5E-31B8E8E68CA0}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {5DDFAAD0-23AC-9A42-AA5E-31B8E8E68CA0}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {5DDFAAD0-23AC-9A42-AA5E-31B8E8E68CA0}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {DFD3F85E-944E-7740-A29F-715891AF8262}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {DFD3F85E-944E-7740-A29F-715891AF8262}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {DFD3F85E-944E-7740-A29F-715891AF8262}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {DFD3F85E-944E-7740-A29F-715891AF8262}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {DFD3F85E-944E-7740-A29F-715891AF8262}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {DFD3F85E-944E-7740-A29F-715891AF8262}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {DFD3F85E-944E-7740-A29F-715891AF8262}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {DFD3F85E-944E-7740-A29F-715891AF8262}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {D03ABAA3-4C58-674E-B545-4AE8E993A57A}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {D03ABAA3-4C58-674E-B545-4AE8E993A57A}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {D03ABAA3-4C58-674E-B545-4AE8E993A57A}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {D03ABAA3-4C58-674E-B545-4AE8E993A57A}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {D03ABAA3-4C58-674E-B545-4AE8E993A57A}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {D03ABAA3-4C58-674E-B545-4AE8E993A57A}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {D03ABAA3-4C58-674E-B545-4AE8E993A57A}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {D03ABAA3-4C58-674E-B545-4AE8E993A57A}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {0F6BA7D9-8481-D34C-9CA7-C69AC15DCE4C}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {0F6BA7D9-8481-D34C-9CA7-C69AC15DCE4C}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {0F6BA7D9-8481-D34C-9CA7-C69AC15DCE4C}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {0F6BA7D9-8481-D34C-9CA7-C69AC15DCE4C}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {0F6BA7D9-8481-D34C-9CA7-C69AC15DCE4C}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {0F6BA7D9-8481-D34C-9CA7-C69AC15DCE4C}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {0F6BA7D9-8481-D34C-9CA7-C69AC15DCE4C}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {0F6BA7D9-8481-D34C-9CA7-C69AC15DCE4C}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {D63DCF21-8421-044C-910F-9758DFF417D0}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {D63DCF21-8421-044C-910F-9758DFF417D0}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {D63DCF21-8421-044C-910F-9758DFF417D0}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {D63DCF21-8421-044C-910F-9758DFF417D0}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {D63DCF21-8421-044C-910F-9758DFF417D0}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {D63DCF21-8421-044C-910F-9758DFF417D0}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {D63DCF21-8421-044C-910F-9758DFF417D0}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {D63DCF21-8421-044C-910F-9758DFF417D0}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {B8D35A81-5E45-744C-BABD-BFCAA4CBF36E}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {B8D35A81-5E45-744C-BABD-BFCAA4CBF36E}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {B8D35A81-5E45-744C-BABD-BFCAA4CBF36E}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {B8D35A81-5E45-744C-BABD-BFCAA4CBF36E}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {B8D35A81-5E45-744C-BABD-BFCAA4CBF36E}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {B8D35A81-5E45-744C-BABD-BFCAA4CBF36E}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {B8D35A81-5E45-744C-BABD-BFCAA4CBF36E}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {B8D35A81-5E45-744C-BABD-BFCAA4CBF36E}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {BCF62E98-514B-254D-95C5-CEBF06A37108}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {BCF62E98-514B-254D-95C5-CEBF06A37108}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {BCF62E98-514B-254D-95C5-CEBF06A37108}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {BCF62E98-514B-254D-95C5-CEBF06A37108}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {BCF62E98-514B-254D-95C5-CEBF06A37108}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {BCF62E98-514B-254D-95C5-CEBF06A37108}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {BCF62E98-514B-254D-95C5-CEBF06A37108}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {BCF62E98-514B-254D-95C5-CEBF06A37108}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {B8043AEB-91BD-4D49-B580-D480DC1B979F}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {B8043AEB-91BD-4D49-B580-D480DC1B979F}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {B8043AEB-91BD-4D49-B580-D480DC1B979F}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {B8043AEB-91BD-4D49-B580-D480DC1B979F}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {B8043AEB-91BD-4D49-B580-D480DC1B979F}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {B8043AEB-91BD-4D49-B580-D480DC1B979F}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {B8043AEB-91BD-4D49-B580-D480DC1B979F}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {B8043AEB-91BD-4D49-B580-D480DC1B979F}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {6DCB0D01-0638-0244-BEB9-A313999D14E9}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {6DCB0D01-0638-0244-BEB9-A313999D14E9}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {6DCB0D01-0638-0244-BEB9-A313999D14E9}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {6DCB0D01-0638-0244-BEB9-A313999D14E9}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {6DCB0D01-0638-0244-BEB9-A313999D14E9}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {6DCB0D01-0638-0244-BEB9-A313999D14E9}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {6DCB0D01-0638-0244-BEB9-A313999D14E9}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {6DCB0D01-0638-0244-BEB9-A313999D14E9}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {29A4883C-6553-4D48-8FFC-10382F07DA72}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {29A4883C-6553-4D48-8FFC-10382F07DA72}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {29A4883C-6553-4D48-8FFC-10382F07DA72}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {29A4883C-6553-4D48-8FFC-10382F07DA72}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {29A4883C-6553-4D48-8FFC-10382F07DA72}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {29A4883C-6553-4D48-8FFC-10382F07DA72}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {29A4883C-6553-4D48-8FFC-10382F07DA72}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {29A4883C-6553-4D48-8FFC-10382F07DA72}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {D1B53AFE-F148-194C-B3A1-8386C9B25359}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {D1B53AFE-F148-194C-B3A1-8386C9B25359}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {D1B53AFE-F148-194C-B3A1-8386C9B25359}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {D1B53AFE-F148-194C-B3A1-8386C9B25359}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {D1B53AFE-F148-194C-B3A1-8386C9B25359}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {D1B53AFE-F148-194C-B3A1-8386C9B25359}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {D1B53AFE-F148-194C-B3A1-8386C9B25359}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {D1B53AFE-F148-194C-B3A1-8386C9B25359}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {FE66E49C-CF34-5F4B-B43C-9A0C89185222}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {FE66E49C-CF34-5F4B-B43C-9A0C89185222}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {FE66E49C-CF34-5F4B-B43C-9A0C89185222}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {FE66E49C-CF34-5F4B-B43C-9A0C89185222}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {FE66E49C-CF34-5F4B-B43C-9A0C89185222}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {FE66E49C-CF34-5F4B-B43C-9A0C89185222}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {FE66E49C-CF34-5F4B-B43C-9A0C89185222}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {FE66E49C-CF34-5F4B-B43C-9A0C89185222}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {EA15C089-307B-8B4A-A598-0E06C82ADB1E}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {EA15C089-307B-8B4A-A598-0E06C82ADB1E}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {EA15C089-307B-8B4A-A598-0E06C82ADB1E}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {EA15C089-307B-8B4A-A598-0E06C82ADB1E}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {EA15C089-307B-8B4A-A598-0E06C82ADB1E}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {EA15C089-307B-8B4A-A598-0E06C82ADB1E}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {EA15C089-307B-8B4A-A598-0E06C82ADB1E}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {EA15C089-307B-8B4A-A598-0E06C82ADB1E}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {BE3117C9-B067-0A4B-920D-7F3C00374BA0}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {BE3117C9-B067-0A4B-920D-7F3C00374BA0}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {BE3117C9-B067-0A4B-920D-7F3C00374BA0}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {BE3117C9-B067-0A4B-920D-7F3C00374BA0}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {BE3117C9-B067-0A4B-920D-7F3C00374BA0}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {BE3117C9-B067-0A4B-920D-7F3C00374BA0}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {BE3117C9-B067-0A4B-920D-7F3C00374BA0}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {BE3117C9-B067-0A4B-920D-7F3C00374BA0}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {13D33F5C-1C2C-D740-A28A-BCFD15616E75}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {13D33F5C-1C2C-D740-A28A-BCFD15616E75}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {13D33F5C-1C2C-D740-A28A-BCFD15616E75}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {13D33F5C-1C2C-D740-A28A-BCFD15616E75}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {13D33F5C-1C2C-D740-A28A-BCFD15616E75}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {13D33F5C-1C2C-D740-A28A-BCFD15616E75}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {13D33F5C-1C2C-D740-A28A-BCFD15616E75}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {13D33F5C-1C2C-D740-A28A-BCFD15616E75}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {FA871426-5142-F646-B3D2-3AF70E784D68}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {FA871426-5142-F646-B3D2-3AF70E784D68}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {FA871426-5142-F646-B3D2-3AF70E784D68}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {FA871426-5142-F646-B3D2-3AF70E784D68}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {FA871426-5142-F646-B3D2-3AF70E784D68}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {FA871426-5142-F646-B3D2-3AF70E784D68}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {FA871426-5142-F646-B3D2-3AF70E784D68}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {FA871426-5142-F646-B3D2-3AF70E784D68}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + {EA829A28-B1B2-1345-98B9-897763B937AF}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {EA829A28-B1B2-1345-98B9-897763B937AF}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {EA829A28-B1B2-1345-98B9-897763B937AF}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {EA829A28-B1B2-1345-98B9-897763B937AF}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {EA829A28-B1B2-1345-98B9-897763B937AF}.DebugLib|Win32.ActiveCfg = DebugLib|Win32 + {EA829A28-B1B2-1345-98B9-897763B937AF}.DebugLib|Win32.Build.0 = DebugLib|Win32 + {EA829A28-B1B2-1345-98B9-897763B937AF}.ReleaseLib|Win32.ActiveCfg = ReleaseLib|Win32 + {EA829A28-B1B2-1345-98B9-897763B937AF}.ReleaseLib|Win32.Build.0 = ReleaseLib|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/libraries/ode-0.9/build/vs2005/ode.vcproj b/libraries/ode-0.9/build/vs2005/ode.vcproj new file mode 100644 index 0000000000..147bb6fd3c --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/ode.vcproj @@ -0,0 +1,1017 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/build/vs2005/tests.vcproj b/libraries/ode-0.9/build/vs2005/tests.vcproj new file mode 100644 index 0000000000..e772e8c902 --- /dev/null +++ b/libraries/ode-0.9/build/vs2005/tests.vcproj @@ -0,0 +1,442 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/config.guess b/libraries/ode-0.9/config.guess new file mode 100755 index 0000000000..396482d6cb --- /dev/null +++ b/libraries/ode-0.9/config.guess @@ -0,0 +1,1500 @@ +#! /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 Free Software Foundation, +# Inc. + +timestamp='2006-07-02' + +# 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 +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 ;; + *) 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.*:*) + echo i386-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:*:[45]) + 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 ;; + i*: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 ;; + x86:Interix*:[3456]*) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T:Interix*:[3456]*) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + [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:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + 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 ;; + 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 ;; + 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 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + 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 ;; + 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 ;; + 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: diff --git a/libraries/ode-0.9/config.sub b/libraries/ode-0.9/config.sub new file mode 100755 index 0000000000..fab0aa3556 --- /dev/null +++ b/libraries/ode-0.9/config.sub @@ -0,0 +1,1616 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. + +timestamp='2006-09-20' + +# 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 +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 \ + | 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 \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | 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) + 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-* | 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-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | 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-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # 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 + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + 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 + ;; + cr16c) + basic_machine=cr16c-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 + ;; + 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 + ;; + 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 + ;; + 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 + ;; + 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 + ;; + 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 + ;; + 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 + ;; + 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* \ + | -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*) + # 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 + ;; + -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 + ;; + 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: diff --git a/libraries/ode-0.9/configure b/libraries/ode-0.9/configure new file mode 100755 index 0000000000..3785f0fefe --- /dev/null +++ b/libraries/ode-0.9/configure @@ -0,0 +1,14308 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.61 for ODE 0.9.0. +# +# Report bugs to . +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006 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=: + # 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 + + + + +# 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 + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +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.) +as_nl=' +' +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 + 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. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# 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 || +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=: + # 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 + + +: +_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=: + # 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 + + +: +(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 autoconf@gnu.org about your system, + echo including any error possibly output before this + echo message +} + + + + 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" || + { 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 +fi +echo >conf$$.file +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 +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 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.9.0' +PACKAGE_STRING='ODE 0.9.0' +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" + +ac_subst_vars='SHELL +PATH_SEPARATOR +PACKAGE_NAME +PACKAGE_TARNAME +PACKAGE_VERSION +PACKAGE_STRING +PACKAGE_BUGREPORT +exec_prefix +prefix +program_transform_name +bindir +sbindir +libexecdir +datarootdir +datadir +sysconfdir +sharedstatedir +localstatedir +includedir +oldincludedir +docdir +infodir +htmldir +dvidir +pdfdir +psdir +libdir +localedir +mandir +DEFS +ECHO_C +ECHO_N +ECHO_T +LIBS +build_alias +host_alias +target_alias +build +build_cpu +build_vendor +build_os +host +host_cpu +host_vendor +host_os +target +target_cpu +target_vendor +target_os +INSTALL_PROGRAM +INSTALL_SCRIPT +INSTALL_DATA +am__isrc +CYGPATH_W +PACKAGE +VERSION +ACLOCAL +AUTOCONF +AUTOMAKE +AUTOHEADER +MAKEINFO +install_sh +STRIP +INSTALL_STRIP_PROGRAM +mkdir_p +AWK +SET_MAKE +am__leading_dot +AMTAR +am__tar +am__untar +CC +CFLAGS +LDFLAGS +CPPFLAGS +ac_ct_CC +EXEEXT +OBJEXT +DEPDIR +am__include +am__quote +AMDEP_TRUE +AMDEP_FALSE +AMDEPBACKSLASH +CCDEPMODE +am__fastdepCC_TRUE +am__fastdepCC_FALSE +CPP +GREP +EGREP +XMKMF +X_CFLAGS +X_PRE_LIBS +X_LIBS +X_EXTRA_LIBS +ODE_CURRENT +ODE_REVISION +ODE_AGE +ODE_RELEASE +ODE_SONAME +CXX +CXXFLAGS +ac_ct_CXX +CXXDEPMODE +am__fastdepCXX_TRUE +am__fastdepCXX_FALSE +WINDRES +ac_ct_WINDRES +RANLIB +USE_SONAME_TRUE +USE_SONAME_FALSE +ENABLE_DEMOS_TRUE +ENABLE_DEMOS_FALSE +ARCHFLAGS +OPCODE_TRUE +OPCODE_FALSE +GIMPACT_TRUE +GIMPACT_FALSE +TRIMESH_TRUE +TRIMESH_FALSE +X86_64_SYSTEM_TRUE +X86_64_SYSTEM_FALSE +WIN32_TRUE +WIN32_FALSE +X11_TRUE +X11_FALSE +OSX_TRUE +OSX_FALSE +DRAWSTUFF +so_ext +SHARED_LDFLAGS +GL_LIBS +TOPDIR +ALLOCA +LIBOBJS +LTLIBOBJS' +ac_subst_files='' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP +XMKMF +CXX +CXXFLAGS +CCC' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# 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_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=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_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=\$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_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=\$ac_optarg ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=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 ;; + + -*) { 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 && + { 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. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + 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'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute directory names. +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 + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { 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 + 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 .` || + { echo "$as_me: error: Working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { 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 -- "$0" || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X"$0" | + 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 .." + { 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" || { 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.9.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/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] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of ODE 0.9.0:";; + esac + cat <<\_ACEOF + +Optional Features: + --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-soname Configure ODE shared library to set the soname field + on ELF files + --enable-demos build tests + --disable-gyroscopic Configure ODE to work without gyroscopic term (may + improve stability) + --enable-double-precision + Configure ODE to work with double precision, if not + specified, single precision is used + --enable-release build a release library with -fomit-frame-pointer + and -ffast-math + --enable-debug Add debug symbols to the library with -g + --enable-gprof enable profiling with gprof + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-x use the X Window System + --with-arch=arch build for $arch, where arch is any of the -march + flags passed to gcc, without the -march, for example + --with-arch=pentium3 + --with-trimesh=opcode|gimpact|none + use the specified system for trimesh support. + +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 + XMKMF Path to xmkmf, Makefile generator for X Window System + CXX C++ compiler command + CXXFLAGS C++ compiler flags + +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" || continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`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 + 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.9.0 +generated by GNU Autoconf 2.61 + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006 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.9.0, which was +generated by GNU Autoconf 2.61. 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=. + 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=`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_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $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=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + 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=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + 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 && + echo "$as_me: caught signal $ac_signal" + 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 explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + set x "$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + set x "$prefix/share/config.site" "$prefix/etc/config.site" +else + set x "$ac_default_prefix/share/config.site" \ + "$ac_default_prefix/etc/config.site" +fi +shift +for ac_site_file +do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +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 + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +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,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +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 + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`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 + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +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 + + + +ODE_CURRENT=0 +ODE_REVISION=9 +ODE_AGE=0 +ODE_RELEASE=$ODE_CURRENT.$ODE_REVISION.$ODE_AGE +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 + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 +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 || + { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 +echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} + { (exit 1); exit 1; }; } + +{ echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6; } +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +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` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 +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 + + +{ echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6; } +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 +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 + + +{ echo "$as_me:$LINENO: checking target system type" >&5 +echo $ECHO_N "checking target system type... $ECHO_C" >&6; } +if test "${ac_cv_target+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "x$target_alias" = x; then + ac_cv_target=$ac_cv_host +else + ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_target" >&5 +echo "${ECHO_T}$ac_cv_target" >&6; } +case $ac_cv_target in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical target" >&5 +echo "$as_me: error: invalid value of canonical target" >&2;} + { (exit 1); exit 1; }; };; +esac +target=$ac_cv_target +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_target +shift +target_cpu=$1 +target_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +target_os=$* +IFS=$ac_save_IFS +case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + +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. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +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 +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$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' + +{ echo "$as_me:$LINENO: checking whether build environment is sane" >&5 +echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&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". + { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&5 +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 + { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! +Check your system clock" >&5 +echo "$as_me: error: newly created file is older than distributed files! +Check your system clock" >&2;} + { (exit 1); exit 1; }; } +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}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 $. echo might interpret backslashes. +# By default was `s,x,x', remove it if useless. +cat <<\_ACEOF >conftest.sed +s/[\\$]/&&/g;s/;s,x,x,$// +_ACEOF +program_transform_name=`echo $program_transform_name | sed -f conftest.sed` +rm -f conftest.sed + +# 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= + { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 +echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +{ echo "$as_me:$LINENO: checking for a thread-safe mkdir -p" >&5 +echo $ECHO_N "checking for a thread-safe mkdir -p... $ECHO_C" >&6; } +if test -z "$MKDIR_P"; then + if test "${ac_cv_path_mkdir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 +{ echo "$as_me:$LINENO: result: $MKDIR_P" >&5 +echo "${ECHO_T}$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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_AWK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + 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 + { echo "$as_me:$LINENO: result: $AWK" >&5 +echo "${ECHO_T}$AWK" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } +set x ${MAKE-make}; ac_make=`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 + echo $ECHO_N "(cached) $ECHO_C" >&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 + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + SET_MAKE= +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 + { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 +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=$ODE_RELEASE + + +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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + 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 + { echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + 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 + { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&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 include/ode/config.h" + +CFLAGS= +CXXFLAGS= +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. +{ echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 +echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&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 + + +{ echo "$as_me:$LINENO: result: $_am_result" >&5 +echo "${ECHO_T}$_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 + + +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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + 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 + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + 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 + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + 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 + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + 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 + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + 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 + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + 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 + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +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. +echo "$as_me:$LINENO: checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + 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.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. +{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +# +# List of possible output files, starting from the most likely. +# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) +# only as a last resort. b.out is created by i960 compilers. +ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' +# +# The IRIX 6 linker writes into existing files which may not be +# executable, retaining their permissions. Remove them first so a +# subsequent execution test works. +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + 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 | *.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 + +{ echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6; } +if test -z "$ac_file"; then + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +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. +{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + 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 + { { 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 +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 +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +rm -f a.out 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. +{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6; } + +{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + 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 | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +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 +{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + 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 ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +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 +{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 +{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$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 +{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 + 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) + { echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6; } ;; + xno) + { echo "$as_me:$LINENO: result: unsupported" >&5 +echo "${ECHO_T}unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +echo "${ECHO_T}$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= + +{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 +{ echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&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 + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 +{ echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +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 + + +{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Extract the first word of "grep ggrep" to use in msg output +if test -z "$GREP"; then +set dummy grep ggrep; ac_prog_name=$2 +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + 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 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'GREP' >> "conftest.nl" + "$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 + + +fi + +GREP="$ac_cv_path_GREP" +if test -z "$GREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_GREP=$GREP +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +echo "${ECHO_T}$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + # Extract the first word of "egrep" to use in msg output +if test -z "$EGREP"; then +set dummy egrep; ac_prog_name=$2 +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + 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 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + 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 + + +fi + +EGREP="$ac_cv_path_EGREP" +if test -z "$EGREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name 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 +{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$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=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +{ echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 +echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6; } +if test "${ac_cv_c_bigendian+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # 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 "echo \"\$as_me:$LINENO: $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 + 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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # It does not; compile a test program. +if test "$cross_compiling" = yes; then + # try to guess the endianness by grepping values into an object file + ac_cv_c_bigendian=unknown + 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 }; +void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } +short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; +short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; +void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } +int +main () +{ + _ascii (); _ebcdic (); + ; + 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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_bigendian=no +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 +echo "${ECHO_T}$ac_cv_c_bigendian" >&6; } +case $ac_cv_c_bigendian in + yes) + +cat >>confdefs.h <<\_ACEOF +#define WORDS_BIGENDIAN 1 +_ACEOF + ;; + no) + ;; + *) + { { echo "$as_me:$LINENO: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&5 +echo "$as_me: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} + { (exit 1); exit 1; }; } ;; +esac + +{ echo "$as_me:$LINENO: checking for X" >&5 +echo $ECHO_N "checking for X... $ECHO_C" >&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 #( + *\'*) { { echo "$as_me:$LINENO: error: Cannot use X directory names containing '" >&5 +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 + echo $ECHO_N "(cached) $ECHO_C" >&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; 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 | /lib) ;; + *) 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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 "echo \"\$as_me:$LINENO: $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 + 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 && + $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 + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + LIBS=$ac_save_LIBS +for ac_dir in `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; do + if test -r "$ac_dir/libX11.$ac_extension"; then + ac_x_libraries=$ac_dir + break 2 + fi + done +done +fi + +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 + { echo "$as_me:$LINENO: result: $have_x" >&5 +echo "${ECHO_T}$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'" + { echo "$as_me:$LINENO: result: libraries $x_libraries, headers $x_includes" >&5 +echo "${ECHO_T}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 . . . . + { echo "$as_me:$LINENO: checking whether -R must be followed by a space" >&5 +echo $ECHO_N "checking whether -R must be followed by a space... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + X_LIBS="$X_LIBS -R$x_libraries" +else + 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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + X_LIBS="$X_LIBS -R $x_libraries" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: result: neither works" >&5 +echo "${ECHO_T}neither works" >&6; } +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi + +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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + { echo "$as_me:$LINENO: checking for dnet_ntoa in -ldnet" >&5 +echo $ECHO_N "checking for dnet_ntoa in -ldnet... $ECHO_C" >&6; } +if test "${ac_cv_lib_dnet_dnet_ntoa+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_dnet_dnet_ntoa=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dnet_dnet_ntoa=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_dnet_dnet_ntoa" >&5 +echo "${ECHO_T}$ac_cv_lib_dnet_dnet_ntoa" >&6; } +if test $ac_cv_lib_dnet_dnet_ntoa = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" +fi + + if test $ac_cv_lib_dnet_dnet_ntoa = no; then + { echo "$as_me:$LINENO: checking for dnet_ntoa in -ldnet_stub" >&5 +echo $ECHO_N "checking for dnet_ntoa in -ldnet_stub... $ECHO_C" >&6; } +if test "${ac_cv_lib_dnet_stub_dnet_ntoa+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_dnet_stub_dnet_ntoa=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_dnet_stub_dnet_ntoa=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5 +echo "${ECHO_T}$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; } +if test $ac_cv_lib_dnet_stub_dnet_ntoa = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" +fi + + fi +fi + +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. + { echo "$as_me:$LINENO: checking for gethostbyname" >&5 +echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6; } +if test "${ac_cv_func_gethostbyname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_func_gethostbyname=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_gethostbyname=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5 +echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6; } + + if test $ac_cv_func_gethostbyname = no; then + { echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5 +echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6; } +if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_nsl_gethostbyname=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_nsl_gethostbyname=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5 +echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6; } +if test $ac_cv_lib_nsl_gethostbyname = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" +fi + + if test $ac_cv_lib_nsl_gethostbyname = no; then + { echo "$as_me:$LINENO: checking for gethostbyname in -lbsd" >&5 +echo $ECHO_N "checking for gethostbyname in -lbsd... $ECHO_C" >&6; } +if test "${ac_cv_lib_bsd_gethostbyname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_bsd_gethostbyname=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_bsd_gethostbyname=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_bsd_gethostbyname" >&5 +echo "${ECHO_T}$ac_cv_lib_bsd_gethostbyname" >&6; } +if test $ac_cv_lib_bsd_gethostbyname = 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. + { echo "$as_me:$LINENO: checking for connect" >&5 +echo $ECHO_N "checking for connect... $ECHO_C" >&6; } +if test "${ac_cv_func_connect+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_func_connect=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_connect=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5 +echo "${ECHO_T}$ac_cv_func_connect" >&6; } + + if test $ac_cv_func_connect = no; then + { echo "$as_me:$LINENO: checking for connect in -lsocket" >&5 +echo $ECHO_N "checking for connect in -lsocket... $ECHO_C" >&6; } +if test "${ac_cv_lib_socket_connect+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_socket_connect=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_socket_connect=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_socket_connect" >&5 +echo "${ECHO_T}$ac_cv_lib_socket_connect" >&6; } +if test $ac_cv_lib_socket_connect = yes; then + X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" +fi + + fi + + # Guillermo Gomez says -lposix is necessary on A/UX. + { echo "$as_me:$LINENO: checking for remove" >&5 +echo $ECHO_N "checking for remove... $ECHO_C" >&6; } +if test "${ac_cv_func_remove+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_func_remove=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_remove=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_remove" >&5 +echo "${ECHO_T}$ac_cv_func_remove" >&6; } + + if test $ac_cv_func_remove = no; then + { echo "$as_me:$LINENO: checking for remove in -lposix" >&5 +echo $ECHO_N "checking for remove in -lposix... $ECHO_C" >&6; } +if test "${ac_cv_lib_posix_remove+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_posix_remove=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_posix_remove=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_posix_remove" >&5 +echo "${ECHO_T}$ac_cv_lib_posix_remove" >&6; } +if test $ac_cv_lib_posix_remove = yes; then + X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" +fi + + fi + + # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. + { echo "$as_me:$LINENO: checking for shmat" >&5 +echo $ECHO_N "checking for shmat... $ECHO_C" >&6; } +if test "${ac_cv_func_shmat+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_func_shmat=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_shmat=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_shmat" >&5 +echo "${ECHO_T}$ac_cv_func_shmat" >&6; } + + if test $ac_cv_func_shmat = no; then + { echo "$as_me:$LINENO: checking for shmat in -lipc" >&5 +echo $ECHO_N "checking for shmat in -lipc... $ECHO_C" >&6; } +if test "${ac_cv_lib_ipc_shmat+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_ipc_shmat=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_ipc_shmat=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_ipc_shmat" >&5 +echo "${ECHO_T}$ac_cv_lib_ipc_shmat" >&6; } +if test $ac_cv_lib_ipc_shmat = 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 + { echo "$as_me:$LINENO: checking for IceConnectionNumber in -lICE" >&5 +echo $ECHO_N "checking for IceConnectionNumber in -lICE... $ECHO_C" >&6; } +if test "${ac_cv_lib_ICE_IceConnectionNumber+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_ICE_IceConnectionNumber=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_ICE_IceConnectionNumber=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5 +echo "${ECHO_T}$ac_cv_lib_ICE_IceConnectionNumber" >&6; } +if test $ac_cv_lib_ICE_IceConnectionNumber = yes; then + X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" +fi + + LDFLAGS=$ac_save_LDFLAGS + +fi + + +ODE_SONAME=libode.so.$ODE_CURRENT + + + + + + + +{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } +set x ${MAKE-make}; ac_make=`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 + echo $ECHO_N "(cached) $ECHO_C" >&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 + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + SET_MAKE= +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + 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 + { echo "$as_me:$LINENO: result: $CXX" >&5 +echo "${ECHO_T}$CXX" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + 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 + { echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 +echo "${ECHO_T}$ac_ct_CXX" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C++ compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +{ echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6; } +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 +{ echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6; } +GXX=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 +echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cxx_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 +echo "${ECHO_T}$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= + +{ echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } +if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 +{ echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 +echo "${ECHO_T}$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 + + +# 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. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +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 +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$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 + 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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_WINDRES+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + 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 + { echo "$as_me:$LINENO: result: $WINDRES" >&5 +echo "${ECHO_T}$WINDRES" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_WINDRES+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + 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 + { echo "$as_me:$LINENO: result: $ac_ct_WINDRES" >&5 +echo "${ECHO_T}$ac_ct_WINDRES" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + WINDRES=$ac_ct_WINDRES + fi +fi + +{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; } +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 +{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for inline" >&5 +echo $ECHO_N "checking for inline... $ECHO_C" >&6; } +if test "${ac_cv_c_inline+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 +{ echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 +echo "${ECHO_T}$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 + +{ echo "$as_me:$LINENO: checking for working volatile" >&5 +echo $ECHO_N "checking for working volatile... $ECHO_C" >&6; } +if test "${ac_cv_c_volatile+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 +{ echo "$as_me:$LINENO: result: $ac_cv_c_volatile" >&5 +echo "${ECHO_T}$ac_cv_c_volatile" >&6; } +if test $ac_cv_c_volatile = no; then + +cat >>confdefs.h <<\_ACEOF +#define volatile +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking for stdbool.h that conforms to C99" >&5 +echo $ECHO_N "checking for stdbool.h that conforms to C99... $ECHO_C" >&6; } +if test "${ac_cv_header_stdbool_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 }; + _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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdbool_h" >&5 +echo "${ECHO_T}$ac_cv_header_stdbool_h" >&6; } +{ echo "$as_me:$LINENO: checking for _Bool" >&5 +echo $ECHO_N "checking for _Bool... $ECHO_C" >&6; } +if test "${ac_cv_type__Bool+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 +typedef _Bool ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + 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 "echo \"\$as_me:$LINENO: $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 + 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_type__Bool=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type__Bool=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type__Bool" >&5 +echo "${ECHO_T}$ac_cv_type__Bool" >&6; } +if test $ac_cv_type__Bool = 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 + +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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + 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 + { echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}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 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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" + 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 + { echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +{ echo "$as_me:$LINENO: checking for size_t" >&5 +echo $ECHO_N "checking for size_t... $ECHO_C" >&6; } +if test "${ac_cv_type_size_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 +typedef size_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + 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 "echo \"\$as_me:$LINENO: $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 + 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_type_size_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_size_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 +echo "${ECHO_T}$ac_cv_type_size_t" >&6; } +if test $ac_cv_type_size_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + + +{ echo "$as_me:$LINENO: checking if a soname should be set" >&5 +echo $ECHO_N "checking if a soname should be set... $ECHO_C" >&6; } +# Check whether --enable-soname was given. +if test "${enable_soname+set}" = set; then + enableval=$enable_soname; use_soname=$enableval +else + use_soname=no +fi + +{ echo "$as_me:$LINENO: result: $use_soname" >&5 +echo "${ECHO_T}$use_soname" >&6; } + if test x$use_soname = xyes; then + USE_SONAME_TRUE= + USE_SONAME_FALSE='#' +else + USE_SONAME_TRUE='#' + USE_SONAME_FALSE= +fi + + + +{ echo "$as_me:$LINENO: checking if tests should be built" >&5 +echo $ECHO_N "checking if tests should be built... $ECHO_C" >&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 + +{ echo "$as_me:$LINENO: result: $enable_demos" >&5 +echo "${ECHO_T}$enable_demos" >&6; } + if test x$enable_demos = xyes; then + ENABLE_DEMOS_TRUE= + ENABLE_DEMOS_FALSE='#' +else + ENABLE_DEMOS_TRUE='#' + ENABLE_DEMOS_FALSE= +fi + + + + +# Check whether --with-arch was given. +if test "${with_arch+set}" = set; then + withval=$with_arch; arch=$withval +else + arch=no +fi + +ARCHFLAGS="" +if test "x$arch" != xno +then + ARCHFLAGS="-march=$arch" +fi + + +case "$arch" in + pentium3 | pentium4 | athlon* ) + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SSE +_ACEOF + + ;; +esac + + + + + + + + + + + + + +for ac_header in alloca.h ieeefp.h stdio.h stdlib.h math.h string.h stdarg.h malloc.h values.h float.h time.h sys/time.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +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 +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `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 + + + +{ echo "$as_me:$LINENO: checking if gyroscopic term should be used" >&5 +echo $ECHO_N "checking if gyroscopic term should be used... $ECHO_C" >&6; } +# Check whether --enable-gyroscopic was given. +if test "${enable_gyroscopic+set}" = set; then + enableval=$enable_gyroscopic; gyroscopic=$enableval +else + gyroscopic=yes +fi + +{ echo "$as_me:$LINENO: result: $gyroscopic" >&5 +echo "${ECHO_T}$gyroscopic" >&6; } +if test x"$gyroscopic" = xyes +then + +cat >>confdefs.h <<\_ACEOF +#define dGYROSCOPIC +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking if double precision is requested" >&5 +echo $ECHO_N "checking if double precision is requested... $ECHO_C" >&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 + +if test "$precision" != no +then + +cat >>confdefs.h <<\_ACEOF +#define dDOUBLE +_ACEOF + +if test "$build_os" == "$target_os" +then +if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#define dInfinity 1e20 +int main() +{ +if (dInfinity > 1e10 && -dInfinity < -1e10 && -dInfinity < dInfinity) +return 0; +else return -1; +} + +_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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + dinfinity=1e20 +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#define dInfinity 1.7976931348623157e+308 +int main() +{ +if (dInfinity > 1e10 && -dInfinity < -1e10 && -dInfinity < dInfinity) +return 0; +else return -1; +} + +_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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + dinfinity=1.7976931348623157e+308 +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#define dInfinity HUGE_VAL +int main() +{ +if (dInfinity > 1e10 && -dInfinity < -1e10 && -dInfinity < dInfinity) +return 0; +else return -1; +} + +_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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + dinfinity=HUGE_VAL +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#define dInfinity DBL_MAX +int main() +{ +if (dInfinity > 1e10 && -dInfinity < -1e10 && -dInfinity < dInfinity) +return 0; +else return -1; +} + +_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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + dinfinity=DBL_MAX +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +else +#cross-compiling, use a reasonable value. We should add an option for setting this. +dinfinity=DBL_MAX +fi +else + +cat >>confdefs.h <<\_ACEOF +#define dSINGLE +_ACEOF + +if test "$build_os" == "$target_os" +then +if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#define dInfinity 1e20f +int main() +{ +if (dInfinity > 1e10f && -dInfinity < -1e10f && -dInfinity < dInfinity) +return 0; +else return -1; +} + +_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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + dinfinity=1e20f +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#define dInfinity 3.402823466e+38F +int main() +{ +if (dInfinity > 1e10f && -dInfinity < -1e10f && -dInfinity < dInfinity) +return 0; +else return -1; +} + +_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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + dinfinity=3.402823466e+38F +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#define dInfinity HUGE_VALF +int main() +{ +if (dInfinity > 1e10f && -dInfinity < -1e10f && -dInfinity < dInfinity) +return 0; +else return -1; +} + +_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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + dinfinity=HUGE_VALF +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#define dInfinity FLT_MAX +int main() +{ +if (dInfinity > 1e10f && -dInfinity < -1e10f && -dInfinity < dInfinity) +return 0; +else return -1; +} + +_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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + dinfinity=FLT_MAX +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +#cross-compiling, use a reasonable value. We should add an option for setting this. +dinfinity=FLT_MAX +fi +fi +{ echo "$as_me:$LINENO: result: $precision" >&5 +echo "${ECHO_T}$precision" >&6; } + +cat >>confdefs.h <<_ACEOF +#define dInfinity ${dinfinity} +_ACEOF + +{ echo "$as_me:$LINENO: checking for appropriate dInfinity constant" >&5 +echo $ECHO_N "checking for appropriate dInfinity constant... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $dinfinity" >&5 +echo "${ECHO_T}$dinfinity" >&6; } + +if test "${ac_cv_header_float_h+set}" = set; then + { echo "$as_me:$LINENO: checking for float.h" >&5 +echo $ECHO_N "checking for float.h... $ECHO_C" >&6; } +if test "${ac_cv_header_float_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5 +echo "${ECHO_T}$ac_cv_header_float_h" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking float.h usability" >&5 +echo $ECHO_N "checking float.h usability... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking float.h presence" >&5 +echo $ECHO_N "checking float.h presence... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: float.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: float.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: float.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: float.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: float.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: float.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: float.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: float.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: float.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: float.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: float.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: float.h: 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 +{ echo "$as_me:$LINENO: checking for float.h" >&5 +echo $ECHO_N "checking for float.h... $ECHO_C" >&6; } +if test "${ac_cv_header_float_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_float_h=$ac_header_preproc +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5 +echo "${ECHO_T}$ac_cv_header_float_h" >&6; } + +fi +if test $ac_cv_header_float_h = yes; then + have_float_h=yes +else + have_float_h=no +fi + + +{ echo "$as_me:$LINENO: checking for appropriate dEpsilon constant" >&5 +echo $ECHO_N "checking for appropriate dEpsilon constant... $ECHO_C" >&6; } +if test "x$have_float_h" == xyes +then +if test $precision == yes +then +dEpsilon=DBL_EPSILON +else +dEpsilon=FLT_EPSILON +fi +else +if test $precision == yes +then +dEpsilon=2.2204460492503131e-16 +else +dEpsilon=1.19209290e-07f +fi +fi + +cat >>confdefs.h <<_ACEOF +#define dEpsilon ${dEpsilon} +_ACEOF + +{ echo "$as_me:$LINENO: result: $dEpsilon" >&5 +echo "${ECHO_T}$dEpsilon" >&6; } + + +if test "$build_os" == "$target_os" +then +{ echo "$as_me:$LINENO: checking for a Pentium CPU" >&5 +echo $ECHO_N "checking for a Pentium CPU... $ECHO_C" >&6; } +if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +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() +{ +asm ("mov \$0,%%eax;\n" + "cpuid\n" : : : "%eax"); +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + pentium=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +pentium=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +else +pentium=no +fi +if test "x$pentium" == xyes +then + +cat >>confdefs.h <<\_ACEOF +#define PENTIUM 1 +_ACEOF + +fi +{ echo "$as_me:$LINENO: result: $pentium" >&5 +echo "${ECHO_T}$pentium" >&6; } + +{ echo "$as_me:$LINENO: checking for a x86-64 CPU" >&5 +echo $ECHO_N "checking for a x86-64 CPU... $ECHO_C" >&6; } +if test "$build_os" == "$target_os" +then +if test "$cross_compiling" = yes; then + { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run test program while cross compiling +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +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() +{ +int a = 0; +int * pa = &a; +asm ("mov %0,%%rax\n" + "movl (%%rax),%%eax\n" + : : "r"(pa) : "%rax"); +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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cpu64=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +cpu64=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +else +cpu64=no +fi +if test "x$cpu64" == xyes +then + +cat >>confdefs.h <<\_ACEOF +#define X86_64_SYSTEM 1 +_ACEOF + +fi +{ echo "$as_me:$LINENO: result: $cpu64" >&5 +echo "${ECHO_T}$cpu64" >&6; } + if test x$cpu64 = xyes; then + X86_64_SYSTEM_TRUE= + X86_64_SYSTEM_FALSE='#' +else + X86_64_SYSTEM_TRUE='#' + X86_64_SYSTEM_FALSE= +fi + + +{ echo "$as_me:$LINENO: checking if building a release library" >&5 +echo $ECHO_N "checking if building a release library... $ECHO_C" >&6; } +# Check whether --enable-release was given. +if test "${enable_release+set}" = set; then + enableval=$enable_release; release=$enableval +else + release=no +fi + +if test "x$release" == xyes +then + CFLAGS="$CFLAGS -fomit-frame-pointer -ffast-math" + CPPFLAGS="$CPPFLAGS -fomit-frame-pointer -ffast-math" + CXXFLAGS="$CXXFLAGS -fomit-frame-pointer -ffast-math" + +cat >>confdefs.h <<\_ACEOF +#define dNODEBUG +_ACEOF + +fi +{ echo "$as_me:$LINENO: result: $release" >&5 +echo "${ECHO_T}$release" >&6; } + +{ echo "$as_me:$LINENO: checking if building a debug library" >&5 +echo $ECHO_N "checking if building a debug library... $ECHO_C" >&6; } +# Check whether --enable-debug was given. +if test "${enable_debug+set}" = set; then + enableval=$enable_debug; debug=$enableval +else + debug=yes +fi + +if test "x$debug" == xyes +then + CFLAGS="$CFLAGS -g" + CPPFLAGS="$CPPFLAGS -g" + CXXFLAGS="$CXXFLAGS -g" +fi +{ echo "$as_me:$LINENO: result: $debug" >&5 +echo "${ECHO_T}$debug" >&6; } + + +{ echo "$as_me:$LINENO: checking for char" >&5 +echo $ECHO_N "checking for char... $ECHO_C" >&6; } +if test "${ac_cv_type_char+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 +typedef char ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + 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 "echo \"\$as_me:$LINENO: $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 + 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_type_char=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_char=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_char" >&5 +echo "${ECHO_T}$ac_cv_type_char" >&6; } + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ echo "$as_me:$LINENO: checking size of char" >&5 +echo $ECHO_N "checking size of char... $ECHO_C" >&6; } +if test "${ac_cv_sizeof_char+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +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 + typedef char ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_lo=0 ac_mid=0 + while :; 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 + typedef char ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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 + typedef char ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_hi=-1 ac_mid=-1 + while :; 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 + typedef char ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo= ac_hi= +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + 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 + typedef char ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr '(' $ac_mid ')' + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_char=$ac_lo;; +'') if test "$ac_cv_type_char" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (char) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (char) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_char=0 + fi ;; +esac +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 + typedef char ac__type_sizeof_; +static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } +static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (((long int) (sizeof (ac__type_sizeof_))) < 0) + { + long int i = longval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%ld\n", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%lu\n", i); + } + return ferror (f) || fclose (f) != 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_char=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +if test "$ac_cv_type_char" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (char) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (char) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_char=0 + fi +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.val +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_char" >&5 +echo "${ECHO_T}$ac_cv_sizeof_char" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_CHAR $ac_cv_sizeof_char +_ACEOF + + +{ echo "$as_me:$LINENO: checking for int" >&5 +echo $ECHO_N "checking for int... $ECHO_C" >&6; } +if test "${ac_cv_type_int+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 +typedef int ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + 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 "echo \"\$as_me:$LINENO: $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 + 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_type_int=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_int=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5 +echo "${ECHO_T}$ac_cv_type_int" >&6; } + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ echo "$as_me:$LINENO: checking size of int" >&5 +echo $ECHO_N "checking size of int... $ECHO_C" >&6; } +if test "${ac_cv_sizeof_int+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +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 + typedef int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_lo=0 ac_mid=0 + while :; 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 + typedef int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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 + typedef int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_hi=-1 ac_mid=-1 + while :; 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 + typedef int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo= ac_hi= +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + 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 + typedef int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr '(' $ac_mid ')' + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_int=$ac_lo;; +'') if test "$ac_cv_type_int" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (int) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (int) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_int=0 + fi ;; +esac +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 + typedef int ac__type_sizeof_; +static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } +static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (((long int) (sizeof (ac__type_sizeof_))) < 0) + { + long int i = longval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%ld\n", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%lu\n", i); + } + return ferror (f) || fclose (f) != 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_int=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +if test "$ac_cv_type_int" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (int) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (int) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_int=0 + fi +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.val +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5 +echo "${ECHO_T}$ac_cv_sizeof_int" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_INT $ac_cv_sizeof_int +_ACEOF + + +{ echo "$as_me:$LINENO: checking for short" >&5 +echo $ECHO_N "checking for short... $ECHO_C" >&6; } +if test "${ac_cv_type_short+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 +typedef short ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + 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 "echo \"\$as_me:$LINENO: $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 + 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_type_short=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_short=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_short" >&5 +echo "${ECHO_T}$ac_cv_type_short" >&6; } + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ echo "$as_me:$LINENO: checking size of short" >&5 +echo $ECHO_N "checking size of short... $ECHO_C" >&6; } +if test "${ac_cv_sizeof_short+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +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 + typedef short ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_lo=0 ac_mid=0 + while :; 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 + typedef short ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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 + typedef short ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_hi=-1 ac_mid=-1 + while :; 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 + typedef short ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo= ac_hi= +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + 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 + typedef short ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr '(' $ac_mid ')' + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_short=$ac_lo;; +'') if test "$ac_cv_type_short" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (short) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (short) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_short=0 + fi ;; +esac +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 + typedef short ac__type_sizeof_; +static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } +static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (((long int) (sizeof (ac__type_sizeof_))) < 0) + { + long int i = longval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%ld\n", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%lu\n", i); + } + return ferror (f) || fclose (f) != 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_short=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +if test "$ac_cv_type_short" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (short) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (short) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_short=0 + fi +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.val +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_short" >&5 +echo "${ECHO_T}$ac_cv_sizeof_short" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_SHORT $ac_cv_sizeof_short +_ACEOF + + +{ echo "$as_me:$LINENO: checking for long int" >&5 +echo $ECHO_N "checking for long int... $ECHO_C" >&6; } +if test "${ac_cv_type_long_int+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 +typedef long int ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + 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 "echo \"\$as_me:$LINENO: $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 + 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_type_long_int=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_long_int=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_long_int" >&5 +echo "${ECHO_T}$ac_cv_type_long_int" >&6; } + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ echo "$as_me:$LINENO: checking size of long int" >&5 +echo $ECHO_N "checking size of long int... $ECHO_C" >&6; } +if test "${ac_cv_sizeof_long_int+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +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 + typedef long int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_lo=0 ac_mid=0 + while :; 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 + typedef long int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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 + typedef long int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_hi=-1 ac_mid=-1 + while :; 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 + typedef long int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo= ac_hi= +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + 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 + typedef long int ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr '(' $ac_mid ')' + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_long_int=$ac_lo;; +'') if test "$ac_cv_type_long_int" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (long int) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (long int) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_long_int=0 + fi ;; +esac +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 + typedef long int ac__type_sizeof_; +static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } +static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (((long int) (sizeof (ac__type_sizeof_))) < 0) + { + long int i = longval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%ld\n", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%lu\n", i); + } + return ferror (f) || fclose (f) != 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_long_int=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +if test "$ac_cv_type_long_int" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (long int) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (long int) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_long_int=0 + fi +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.val +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_long_int" >&5 +echo "${ECHO_T}$ac_cv_sizeof_long_int" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG_INT $ac_cv_sizeof_long_int +_ACEOF + + +{ echo "$as_me:$LINENO: checking for void*" >&5 +echo $ECHO_N "checking for void*... $ECHO_C" >&6; } +if test "${ac_cv_type_voidp+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 +typedef void* ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + 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 "echo \"\$as_me:$LINENO: $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 + 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_type_voidp=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_voidp=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_voidp" >&5 +echo "${ECHO_T}$ac_cv_type_voidp" >&6; } + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ echo "$as_me:$LINENO: checking size of void*" >&5 +echo $ECHO_N "checking size of void*... $ECHO_C" >&6; } +if test "${ac_cv_sizeof_voidp+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +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 + typedef void* ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= 0)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_lo=0 ac_mid=0 + while :; 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 + typedef void* ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_hi=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr $ac_mid + 1` + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + 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 + typedef void* ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) < 0)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_hi=-1 ac_mid=-1 + while :; 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 + typedef void* ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) >= $ac_mid)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_lo=$ac_mid; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_hi=`expr '(' $ac_mid ')' - 1` + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + ac_mid=`expr 2 '*' $ac_mid` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo= ac_hi= +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` + 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 + typedef void* ac__type_sizeof_; +int +main () +{ +static int test_array [1 - 2 * !(((long int) (sizeof (ac__type_sizeof_))) <= $ac_mid)]; +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 "echo \"\$as_me:$LINENO: $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 + 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_hi=$ac_mid +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_lo=`expr '(' $ac_mid ')' + 1` +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in +?*) ac_cv_sizeof_voidp=$ac_lo;; +'') if test "$ac_cv_type_voidp" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (void*) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (void*) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_voidp=0 + fi ;; +esac +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 + typedef void* ac__type_sizeof_; +static long int longval () { return (long int) (sizeof (ac__type_sizeof_)); } +static unsigned long int ulongval () { return (long int) (sizeof (ac__type_sizeof_)); } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (((long int) (sizeof (ac__type_sizeof_))) < 0) + { + long int i = longval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%ld\n", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ((long int) (sizeof (ac__type_sizeof_)))) + return 1; + fprintf (f, "%lu\n", i); + } + return ferror (f) || fclose (f) != 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sizeof_voidp=`cat conftest.val` +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +if test "$ac_cv_type_voidp" = yes; then + { { echo "$as_me:$LINENO: error: cannot compute sizeof (void*) +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute sizeof (void*) +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } + else + ac_cv_sizeof_voidp=0 + fi +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.val +fi +{ echo "$as_me:$LINENO: result: $ac_cv_sizeof_voidp" >&5 +echo "${ECHO_T}$ac_cv_sizeof_voidp" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_VOIDP $ac_cv_sizeof_voidp +_ACEOF + + + +case "$host_os" in + cygwin* | mingw*) + so_ext=".dll" + DLLDEFINE="-DODE_DLL" + SHARED_LDFLAGS="-shared" + drawstuff="Win32" # if in a Windows enviroment + ;; + *apple* | *darwin*) # For Mac OS X + so_ext=".dylib" + DLLDEFINE="" + SHARED_LDFLAGS="-dynamiclib" + drawstuff="OSX" + CC="$CXX" + LINK="$CXXLINK" + ;; + *) + drawstuff="X11" # if anything else default to X11 + if test x$use_soname = xyes; then + so_ext=".so.$ODE_RELEASE" + else + so_ext=".so" + fi + DLLDEFINE="" + SHARED_LDFLAGS="-shared" + ;; +esac + 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 + +{ echo "$as_me:$LINENO: checking which drawstuff lib to build" >&5 +echo $ECHO_N "checking which drawstuff lib to build... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $drawstuff" >&5 +echo "${ECHO_T}$drawstuff" >&6; } + +{ echo "$as_me:$LINENO: checking for the suffix of shared libraries" >&5 +echo $ECHO_N "checking for the suffix of shared libraries... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $so_ext" >&5 +echo "${ECHO_T}$so_ext" >&6; } + +cat >>confdefs.h <<_ACEOF +#define SO_EXT "$so_ext" +_ACEOF + + + + +if test "X$x_includes" != "XNONE"; then + CFLAGS="$CFLAGS -I$x_includes" + CXXFLAGS="$CXXFLAGS -I$x_includes" +fi +if test "X$x_libraries" != "XNONE"; then + CFLAGS="$CFLAGS -L$x_libraries" + CXXFLAGS="$CXXFLAGS -L$x_libraries" +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 + + + +for ac_header in GL/gl.h GL/glu.h GL/glext.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&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 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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + { echo "$as_me:$LINENO: checking for main in -lGL" >&5 +echo $ECHO_N "checking for main in -lGL... $ECHO_C" >&6; } +if test "${ac_cv_lib_GL_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_GL_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_GL_main=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_GL_main" >&5 +echo "${ECHO_T}$ac_cv_lib_GL_main" >&6; } +if test $ac_cv_lib_GL_main = yes; then + GL_LIBS="$GL_LIBS -lGL" +fi + + TEMP_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $GL_LIBS" + { echo "$as_me:$LINENO: checking for main in -lGLU" >&5 +echo $ECHO_N "checking for main in -lGLU... $ECHO_C" >&6; } +if test "${ac_cv_lib_GLU_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lGLU $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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_GLU_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_GLU_main=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_GLU_main" >&5 +echo "${ECHO_T}$ac_cv_lib_GLU_main" >&6; } +if test $ac_cv_lib_GLU_main = yes; then + GL_LIBS="$GL_LIBS -lGLU" +fi + + LDFLAGS="$TEMP_LDFLAGS" + { echo "$as_me:$LINENO: checking for main in -lopengl32" >&5 +echo $ECHO_N "checking for main in -lopengl32... $ECHO_C" >&6; } +if test "${ac_cv_lib_opengl32_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_opengl32_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_opengl32_main=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_opengl32_main" >&5 +echo "${ECHO_T}$ac_cv_lib_opengl32_main" >&6; } +if test $ac_cv_lib_opengl32_main = yes; then + GL_LIBS="$GL_LIBS -lopengl32" +fi + + { echo "$as_me:$LINENO: checking for main in -lglu32" >&5 +echo $ECHO_N "checking for main in -lglu32... $ECHO_C" >&6; } +if test "${ac_cv_lib_glu32_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lglu32 $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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_glu32_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_glu32_main=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_glu32_main" >&5 +echo "${ECHO_T}$ac_cv_lib_glu32_main" >&6; } +if test $ac_cv_lib_glu32_main = yes; then + GL_LIBS="$GL_LIBS -lglu32" +fi + + { echo "$as_me:$LINENO: checking for main in -lXmu" >&5 +echo $ECHO_N "checking for main in -lXmu... $ECHO_C" >&6; } +if test "${ac_cv_lib_Xmu_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXmu $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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_Xmu_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_Xmu_main=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_Xmu_main" >&5 +echo "${ECHO_T}$ac_cv_lib_Xmu_main" >&6; } +if test $ac_cv_lib_Xmu_main = yes; then + GL_LIBS="$GL_LIBS -lXmu" +fi + + { echo "$as_me:$LINENO: checking for main in -lXi" >&5 +echo $ECHO_N "checking for main in -lXi... $ECHO_C" >&6; } +if test "${ac_cv_lib_Xi_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXi $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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_Xi_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_Xi_main=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_Xi_main" >&5 +echo "${ECHO_T}$ac_cv_lib_Xi_main" >&6; } +if test $ac_cv_lib_Xi_main = yes; then + GL_LIBS="$GL_LIBS -lXi" +fi + + { echo "$as_me:$LINENO: checking for main in -lX" >&5 +echo $ECHO_N "checking for main in -lX... $ECHO_C" >&6; } +if test "${ac_cv_lib_X_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lX $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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_X_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_X_main=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_X_main" >&5 +echo "${ECHO_T}$ac_cv_lib_X_main" >&6; } +if test $ac_cv_lib_X_main = yes; then + GL_LIBS="$GL_LIBS -lX" +fi + + { echo "$as_me:$LINENO: checking for main in -lX11" >&5 +echo $ECHO_N "checking for main in -lX11... $ECHO_C" >&6; } +if test "${ac_cv_lib_X11_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_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. */ + + +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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_X11_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_X11_main=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_X11_main" >&5 +echo "${ECHO_T}$ac_cv_lib_X11_main" >&6; } +if test $ac_cv_lib_X11_main = yes; then + GL_LIBS="$GL_LIBS -lX11" +fi + +fi + + +{ echo "$as_me:$LINENO: checking for main in -lcomctl32" >&5 +echo $ECHO_N "checking for main in -lcomctl32... $ECHO_C" >&6; } +if test "${ac_cv_lib_comctl32_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcomctl32 $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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_comctl32_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_comctl32_main=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_comctl32_main" >&5 +echo "${ECHO_T}$ac_cv_lib_comctl32_main" >&6; } +if test $ac_cv_lib_comctl32_main = yes; then + LIBS="$LIBS -lcomctl32" +fi + +{ echo "$as_me:$LINENO: checking for main in -lkernel32" >&5 +echo $ECHO_N "checking for main in -lkernel32... $ECHO_C" >&6; } +if test "${ac_cv_lib_kernel32_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lkernel32 $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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_kernel32_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_kernel32_main=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_kernel32_main" >&5 +echo "${ECHO_T}$ac_cv_lib_kernel32_main" >&6; } +if test $ac_cv_lib_kernel32_main = yes; then + LIBS="$LIBS -lkernel32" +fi + +{ echo "$as_me:$LINENO: checking for main in -luser32" >&5 +echo $ECHO_N "checking for main in -luser32... $ECHO_C" >&6; } +if test "${ac_cv_lib_user32_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-luser32 $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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_user32_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_user32_main=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_user32_main" >&5 +echo "${ECHO_T}$ac_cv_lib_user32_main" >&6; } +if test $ac_cv_lib_user32_main = yes; then + LIBS="$LIBS -luser32" +fi + +{ echo "$as_me:$LINENO: checking for main in -lgdi32" >&5 +echo $ECHO_N "checking for main in -lgdi32... $ECHO_C" >&6; } +if test "${ac_cv_lib_gdi32_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lgdi32 $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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_gdi32_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_gdi32_main=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_gdi32_main" >&5 +echo "${ECHO_T}$ac_cv_lib_gdi32_main" >&6; } +if test $ac_cv_lib_gdi32_main = yes; then + LIBS="$LIBS -lgdi32" +fi + +{ echo "$as_me:$LINENO: checking for main in -lwinmm" >&5 +echo $ECHO_N "checking for main in -lwinmm... $ECHO_C" >&6; } +if test "${ac_cv_lib_winmm_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lwinmm $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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_winmm_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_winmm_main=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_winmm_main" >&5 +echo "${ECHO_T}$ac_cv_lib_winmm_main" >&6; } +if test $ac_cv_lib_winmm_main = yes; then + LIBS="$LIBS -lwinmm" +fi + + +{ echo "$as_me:$LINENO: checking for main in -lstdc++" >&5 +echo $ECHO_N "checking for main in -lstdc++... $ECHO_C" >&6; } +if test "${ac_cv_lib_stdcpp_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_stdcpp_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_stdcpp_main=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_stdcpp_main" >&5 +echo "${ECHO_T}$ac_cv_lib_stdcpp_main" >&6; } +if test $ac_cv_lib_stdcpp_main = yes; then + LIBS="$LIBS -lstdc++" +fi + +{ echo "$as_me:$LINENO: checking for main in -lm" >&5 +echo $ECHO_N "checking for main in -lm... $ECHO_C" >&6; } +if test "${ac_cv_lib_m_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_m_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_m_main=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_m_main" >&5 +echo "${ECHO_T}$ac_cv_lib_m_main" >&6; } +if test $ac_cv_lib_m_main = yes; then + LIBS="$LIBS -lm" +fi + +{ echo "$as_me:$LINENO: checking for main in -lpthread" >&5 +echo $ECHO_N "checking for main in -lpthread... $ECHO_C" >&6; } +if test "${ac_cv_lib_pthread_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_pthread_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_pthread_main=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_main" >&5 +echo "${ECHO_T}$ac_cv_lib_pthread_main" >&6; } +if test $ac_cv_lib_pthread_main = yes; then + LIBS="$LIBS -lpthread" +fi + + + +TOPDIR=`cd $srcdir;pwd` + + +{ echo "$as_me:$LINENO: checking for gprof" >&5 +echo $ECHO_N "checking for gprof... $ECHO_C" >&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" + CPPFLAGS="-pg $CPPFLAGS" + CXXFLAGS="-pg $CXXFLAGS" + { echo "$as_me:$LINENO: checking for main in -lgmon" >&5 +echo $ECHO_N "checking for main in -lgmon... $ECHO_C" >&6; } +if test "${ac_cv_lib_gmon_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_gmon_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_gmon_main=no +fi + +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 +{ echo "$as_me:$LINENO: result: $ac_cv_lib_gmon_main" >&5 +echo "${ECHO_T}$ac_cv_lib_gmon_main" >&6; } +if test $ac_cv_lib_gmon_main = yes; then + LIBS="$LIBS -lgmon" +fi + + { echo "$as_me:$LINENO: result: enabled" >&5 +echo "${ECHO_T}enabled" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +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=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +if test "$build_os" == "$target_os" +then +# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works +# for constant arguments. Useless! +{ echo "$as_me:$LINENO: checking for working alloca.h" >&5 +echo $ECHO_N "checking for working alloca.h... $ECHO_C" >&6; } +if test "${ac_cv_working_alloca_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_working_alloca_h=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_working_alloca_h=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5 +echo "${ECHO_T}$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 + +{ echo "$as_me:$LINENO: checking for alloca" >&5 +echo $ECHO_N "checking for alloca... $ECHO_C" >&6; } +if test "${ac_cv_func_alloca_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_func_alloca_works=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_alloca_works=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5 +echo "${ECHO_T}$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 + + +{ echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5 +echo $ECHO_N "checking whether \`alloca.c' needs Cray hooks... $ECHO_C" >&6; } +if test "${ac_cv_os_cray+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 +{ echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5 +echo "${ECHO_T}$ac_cv_os_cray" >&6; } +if test $ac_cv_os_cray = yes; then + for ac_func in _getb67 GETB67 getb67; do + as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + +cat >>confdefs.h <<_ACEOF +#define CRAY_STACKSEG_END $ac_func +_ACEOF + + break +fi + + done +fi + +{ echo "$as_me:$LINENO: checking stack direction for C alloca" >&5 +echo $ECHO_N "checking stack direction for C alloca... $ECHO_C" >&6; } +if test "${ac_cv_c_stack_direction+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_stack_direction=1 +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_c_stack_direction=-1 +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5 +echo "${ECHO_T}$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=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +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 +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +{ echo "$as_me:$LINENO: checking for GNU libc compatible malloc" >&5 +echo $ECHO_N "checking for GNU libc compatible malloc... $ECHO_C" >&6; } +if test "${ac_cv_func_malloc_0_nonnull+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_malloc_0_nonnull=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +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 -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_malloc_0_nonnull" >&5 +echo "${ECHO_T}$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 + + + +{ echo "$as_me:$LINENO: checking for obstacks" >&5 +echo $ECHO_N "checking for obstacks... $ECHO_C" >&6; } +if test "${ac_cv_func_obstack+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_func_obstack=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func_obstack=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_obstack" >&5 +echo "${ECHO_T}$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=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +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 +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +{ echo "$as_me:$LINENO: checking for GNU libc compatible realloc" >&5 +echo $ECHO_N "checking for GNU libc compatible realloc... $ECHO_C" >&6; } +if test "${ac_cv_func_realloc_0_nonnull+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + 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 "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_realloc_0_nonnull=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +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 -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_realloc_0_nonnull" >&5 +echo "${ECHO_T}$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=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +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 +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +{ echo "$as_me:$LINENO: checking types of arguments for select" >&5 +echo $ECHO_N "checking types of arguments for select... $ECHO_C" >&6; } +if test "${ac_cv_func_select_args+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 + 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 +{ echo "$as_me:$LINENO: result: $ac_cv_func_select_args" >&5 +echo "${ECHO_T}$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=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +{ echo "$as_me:$LINENO: checking for _doprnt" >&5 +echo $ECHO_N "checking for _doprnt... $ECHO_C" >&6; } +if test "${ac_cv_func__doprnt+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&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 "echo \"\$as_me:$LINENO: $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 + 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 && + $as_test_x conftest$ac_exeext; then + ac_cv_func__doprnt=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_func__doprnt=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5 +echo "${ECHO_T}$ac_cv_func__doprnt" >&6; } +if test $ac_cv_func__doprnt = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DOPRNT 1 +_ACEOF + +fi + +fi +done + + +fi + + + + + + + +ac_config_files="$ac_config_files Makefile include/Makefile include/ode/Makefile ode/Makefile ode/src/Makefile drawstuff/Makefile drawstuff/src/Makefile drawstuff/dstest/Makefile ode/demo/Makefile tests/Makefile tests/CppTestHarness/Makefile ode-config" + +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_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $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" && + { echo "$as_me:$LINENO: updating cache $cache_file" >&5 +echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +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=`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 + { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +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 + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +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 + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +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 "${USE_SONAME_TRUE}" && test -z "${USE_SONAME_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"USE_SONAME\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"USE_SONAME\" 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 + { { echo "$as_me:$LINENO: error: conditional \"ENABLE_DEMOS\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +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 "${OPCODE_TRUE}" && test -z "${OPCODE_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"OPCODE\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +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 + { { echo "$as_me:$LINENO: error: conditional \"GIMPACT\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +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 + { { echo "$as_me:$LINENO: error: conditional \"TRIMESH\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +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 "${X86_64_SYSTEM_TRUE}" && test -z "${X86_64_SYSTEM_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"X86_64_SYSTEM\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +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 "${WIN32_TRUE}" && test -z "${WIN32_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"WIN32\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +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 + { { echo "$as_me:$LINENO: error: conditional \"X11\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +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 + { { echo "$as_me:$LINENO: error: conditional \"OSX\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"OSX\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $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 +## --------------------- ## +## 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=: + # 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 + + + + +# 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 + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +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.) +as_nl=' +' +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 + 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. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# 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 || +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" || + { 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 +fi +echo >conf$$.file +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 +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.9.0, which was +generated by GNU Autoconf 2.61. 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 + +cat >>$CONFIG_STATUS <<_ACEOF +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet 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_cs_version="\\ +ODE config.status 0.9.0 +configured by $0, generated by GNU Autoconf 2.61, + with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2006 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' +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +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 ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + { echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + 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. + -*) { 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 +if \$ac_cs_recheck; then + echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=$SHELL + export CONFIG_SHELL + exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "include/ode/config.h") CONFIG_HEADERS="$CONFIG_HEADERS include/ode/config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;; + "include/ode/Makefile") CONFIG_FILES="$CONFIG_FILES include/ode/Makefile" ;; + "ode/Makefile") CONFIG_FILES="$CONFIG_FILES ode/Makefile" ;; + "ode/src/Makefile") CONFIG_FILES="$CONFIG_FILES ode/src/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" ;; + "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; + "tests/CppTestHarness/Makefile") CONFIG_FILES="$CONFIG_FILES tests/CppTestHarness/Makefile" ;; + "ode-config") CONFIG_FILES="$CONFIG_FILES ode-config" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +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") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +_ACEOF + + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +SHELL!$SHELL$ac_delim +PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim +PACKAGE_NAME!$PACKAGE_NAME$ac_delim +PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim +PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim +PACKAGE_STRING!$PACKAGE_STRING$ac_delim +PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim +exec_prefix!$exec_prefix$ac_delim +prefix!$prefix$ac_delim +program_transform_name!$program_transform_name$ac_delim +bindir!$bindir$ac_delim +sbindir!$sbindir$ac_delim +libexecdir!$libexecdir$ac_delim +datarootdir!$datarootdir$ac_delim +datadir!$datadir$ac_delim +sysconfdir!$sysconfdir$ac_delim +sharedstatedir!$sharedstatedir$ac_delim +localstatedir!$localstatedir$ac_delim +includedir!$includedir$ac_delim +oldincludedir!$oldincludedir$ac_delim +docdir!$docdir$ac_delim +infodir!$infodir$ac_delim +htmldir!$htmldir$ac_delim +dvidir!$dvidir$ac_delim +pdfdir!$pdfdir$ac_delim +psdir!$psdir$ac_delim +libdir!$libdir$ac_delim +localedir!$localedir$ac_delim +mandir!$mandir$ac_delim +DEFS!$DEFS$ac_delim +ECHO_C!$ECHO_C$ac_delim +ECHO_N!$ECHO_N$ac_delim +ECHO_T!$ECHO_T$ac_delim +LIBS!$LIBS$ac_delim +build_alias!$build_alias$ac_delim +host_alias!$host_alias$ac_delim +target_alias!$target_alias$ac_delim +build!$build$ac_delim +build_cpu!$build_cpu$ac_delim +build_vendor!$build_vendor$ac_delim +build_os!$build_os$ac_delim +host!$host$ac_delim +host_cpu!$host_cpu$ac_delim +host_vendor!$host_vendor$ac_delim +host_os!$host_os$ac_delim +target!$target$ac_delim +target_cpu!$target_cpu$ac_delim +target_vendor!$target_vendor$ac_delim +target_os!$target_os$ac_delim +INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim +INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim +INSTALL_DATA!$INSTALL_DATA$ac_delim +am__isrc!$am__isrc$ac_delim +CYGPATH_W!$CYGPATH_W$ac_delim +PACKAGE!$PACKAGE$ac_delim +VERSION!$VERSION$ac_delim +ACLOCAL!$ACLOCAL$ac_delim +AUTOCONF!$AUTOCONF$ac_delim +AUTOMAKE!$AUTOMAKE$ac_delim +AUTOHEADER!$AUTOHEADER$ac_delim +MAKEINFO!$MAKEINFO$ac_delim +install_sh!$install_sh$ac_delim +STRIP!$STRIP$ac_delim +INSTALL_STRIP_PROGRAM!$INSTALL_STRIP_PROGRAM$ac_delim +mkdir_p!$mkdir_p$ac_delim +AWK!$AWK$ac_delim +SET_MAKE!$SET_MAKE$ac_delim +am__leading_dot!$am__leading_dot$ac_delim +AMTAR!$AMTAR$ac_delim +am__tar!$am__tar$ac_delim +am__untar!$am__untar$ac_delim +CC!$CC$ac_delim +CFLAGS!$CFLAGS$ac_delim +LDFLAGS!$LDFLAGS$ac_delim +CPPFLAGS!$CPPFLAGS$ac_delim +ac_ct_CC!$ac_ct_CC$ac_delim +EXEEXT!$EXEEXT$ac_delim +OBJEXT!$OBJEXT$ac_delim +DEPDIR!$DEPDIR$ac_delim +am__include!$am__include$ac_delim +am__quote!$am__quote$ac_delim +AMDEP_TRUE!$AMDEP_TRUE$ac_delim +AMDEP_FALSE!$AMDEP_FALSE$ac_delim +AMDEPBACKSLASH!$AMDEPBACKSLASH$ac_delim +CCDEPMODE!$CCDEPMODE$ac_delim +am__fastdepCC_TRUE!$am__fastdepCC_TRUE$ac_delim +am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim +CPP!$CPP$ac_delim +GREP!$GREP$ac_delim +EGREP!$EGREP$ac_delim +XMKMF!$XMKMF$ac_delim +X_CFLAGS!$X_CFLAGS$ac_delim +X_PRE_LIBS!$X_PRE_LIBS$ac_delim +X_LIBS!$X_LIBS$ac_delim +X_EXTRA_LIBS!$X_EXTRA_LIBS$ac_delim +ODE_CURRENT!$ODE_CURRENT$ac_delim +ODE_REVISION!$ODE_REVISION$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +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 + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF +CEOF$ac_eof +_ACEOF + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +ODE_AGE!$ODE_AGE$ac_delim +ODE_RELEASE!$ODE_RELEASE$ac_delim +ODE_SONAME!$ODE_SONAME$ac_delim +CXX!$CXX$ac_delim +CXXFLAGS!$CXXFLAGS$ac_delim +ac_ct_CXX!$ac_ct_CXX$ac_delim +CXXDEPMODE!$CXXDEPMODE$ac_delim +am__fastdepCXX_TRUE!$am__fastdepCXX_TRUE$ac_delim +am__fastdepCXX_FALSE!$am__fastdepCXX_FALSE$ac_delim +WINDRES!$WINDRES$ac_delim +ac_ct_WINDRES!$ac_ct_WINDRES$ac_delim +RANLIB!$RANLIB$ac_delim +USE_SONAME_TRUE!$USE_SONAME_TRUE$ac_delim +USE_SONAME_FALSE!$USE_SONAME_FALSE$ac_delim +ENABLE_DEMOS_TRUE!$ENABLE_DEMOS_TRUE$ac_delim +ENABLE_DEMOS_FALSE!$ENABLE_DEMOS_FALSE$ac_delim +ARCHFLAGS!$ARCHFLAGS$ac_delim +OPCODE_TRUE!$OPCODE_TRUE$ac_delim +OPCODE_FALSE!$OPCODE_FALSE$ac_delim +GIMPACT_TRUE!$GIMPACT_TRUE$ac_delim +GIMPACT_FALSE!$GIMPACT_FALSE$ac_delim +TRIMESH_TRUE!$TRIMESH_TRUE$ac_delim +TRIMESH_FALSE!$TRIMESH_FALSE$ac_delim +X86_64_SYSTEM_TRUE!$X86_64_SYSTEM_TRUE$ac_delim +X86_64_SYSTEM_FALSE!$X86_64_SYSTEM_FALSE$ac_delim +WIN32_TRUE!$WIN32_TRUE$ac_delim +WIN32_FALSE!$WIN32_FALSE$ac_delim +X11_TRUE!$X11_TRUE$ac_delim +X11_FALSE!$X11_FALSE$ac_delim +OSX_TRUE!$OSX_TRUE$ac_delim +OSX_FALSE!$OSX_FALSE$ac_delim +DRAWSTUFF!$DRAWSTUFF$ac_delim +so_ext!$so_ext$ac_delim +SHARED_LDFLAGS!$SHARED_LDFLAGS$ac_delim +GL_LIBS!$GL_LIBS$ac_delim +TOPDIR!$TOPDIR$ac_delim +ALLOCA!$ALLOCA$ac_delim +LIBOBJS!$LIBOBJS$ac_delim +LTLIBOBJS!$LTLIBOBJS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 39; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +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 + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF +:end +s/|#_!!_#|//g +CEOF$ac_eof +_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 +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +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 || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + 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 "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + 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 || +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=`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 || +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" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +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=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`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 +# 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= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + 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 + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;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 +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out + +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"; } && + { 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 +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 + ;; + :H) + # + # CONFIG_HEADER + # +_ACEOF + +# Transform confdefs.h into a sed script `conftest.defines', that +# substitutes the proper values into config.h.in to produce config.h. +rm -f conftest.defines conftest.tail +# First, append a space to every undef/define line, to ease matching. +echo 's/$/ /' >conftest.defines +# Then, protect against being on the right side of a sed subst, or in +# an unquoted here document, in config.status. If some macros were +# called several times there might be several #defines for the same +# symbol, which is useless. But do not sort them, since the last +# AC_DEFINE must be honored. +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where +# NAME is the cpp macro being defined, VALUE is the value it is being given. +# PARAMS is the parameter list in the macro definition--in most cases, it's +# just an empty string. +ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' +ac_dB='\\)[ (].*,\\1define\\2' +ac_dC=' ' +ac_dD=' ,' + +uniq confdefs.h | + sed -n ' + t rset + :rset + s/^[ ]*#[ ]*define[ ][ ]*// + t ok + d + :ok + s/[\\&,]/\\&/g + s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p + s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p + ' >>conftest.defines + +# Remove the space that was appended to ease matching. +# Then 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. +# (The regexp can be short, since the line contains either #define or #undef.) +echo 's/ $// +s,^[ #]*u.*,/* & */,' >>conftest.defines + +# Break up conftest.defines: +ac_max_sed_lines=50 + +# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" +# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" +# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" +# et cetera. +ac_in='$ac_file_inputs' +ac_out='"$tmp/out1"' +ac_nxt='"$tmp/out2"' + +while : +do + # Write a here document: + cat >>$CONFIG_STATUS <<_ACEOF + # First, check the format of the line: + cat >"\$tmp/defines.sed" <<\\CEOF +/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def +/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def +b +:def +_ACEOF + sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS + ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in + sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail + grep . conftest.tail >/dev/null || break + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines conftest.tail + +echo "ac_result=$ac_in" >>$CONFIG_STATUS +cat >>$CONFIG_STATUS <<\_ACEOF + if test x"$ac_file" != x-; then + echo "/* $configure_input */" >"$tmp/config.h" + cat "$ac_result" >>"$tmp/config.h" + if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f $ac_file + mv "$tmp/config.h" $ac_file + fi + else + echo "/* $configure_input */" + cat "$ac_result" + fi + rm -f "$tmp/out12" +# Compute $ac_file's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $ac_file | $ac_file:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $ac_file" >`$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 || +echo X$ac_file | + 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) { echo "$as_me:$LINENO: executing $ac_file commands" >&5 +echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; 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 10q "$mf" | grep '^#.*generated by automake' > /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 || +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 || +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=`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 || +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" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done + ;; + + esac +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# 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 + + +chmod +x ode-config + +echo "Configuration:" +echo " Target system type: $target" +echo " Build system type: $build" +echo " Host system type: $host" +echo " Use double precision: $precision" +echo " Use OPCODE: $opcode" +echo " Use GIMPACT: $gimpact" +echo " Use gyroscopic term: $gyroscopic" +echo " Is this a Pentium: $pentium" +echo " Is the CPU x86-64: $cpu64" +echo " Is this a release build: $release" +echo " Adding debug symbols: $debug" +echo " Using SONAME: $use_soname" +echo " Headers will be installed in $prefix/include/ode" +echo " Libraries will be installed in $prefix/lib" + +if test $gimpact = yes -a $precision = yes +then + echo "WARNING! Double precision not yet supported for GIMPACT" +fi + diff --git a/libraries/ode-0.9/configure.in b/libraries/ode-0.9/configure.in new file mode 100644 index 0000000000..96eea67787 --- /dev/null +++ b/libraries/ode-0.9/configure.in @@ -0,0 +1,580 @@ +dnl Initial configure.in by Rodrigo Hernandez +dnl Modified in 26/10/2005 by Rodrigo Hernandez + +dnl AC_INIT does not take a macro as a version nr: set it separately! - Bram +AC_INIT(ODE,0.9.0,ode@ode.org) + +dnl When upgrading version nr, also change the AC_INIT line! - Bram +ODE_CURRENT=0 +ODE_REVISION=9 +ODE_AGE=0 +ODE_RELEASE=[$ODE_CURRENT].[$ODE_REVISION].[$ODE_AGE] +AC_CANONICAL_HOST +AC_CANONICAL_TARGET + +AM_INIT_AUTOMAKE(ODE,[$ODE_RELEASE]) +AM_CONFIG_HEADER(include/ode/config.h) +dnl Set CFLAGS to zero, so that we avoid getting the gratis -g -O2 +CFLAGS= +CXXFLAGS= +AC_C_BIGENDIAN +AC_PATH_X +AC_PATH_XTRA + +ODE_SONAME=libode.so.[$ODE_CURRENT] + +AC_SUBST(ODE_CURRENT) +AC_SUBST(ODE_REVISION) +AC_SUBST(ODE_AGE) +AC_SUBST(ODE_RELEASE) +AC_SUBST(ODE_SONAME) + +dnl This is needed because we have subdirectories +AC_PROG_MAKE_SET + +AC_PROG_CXX +AC_PROG_INSTALL +AC_CHECK_TOOLS([WINDRES], [windres]) +AC_C_CONST +AC_C_INLINE +AC_C_VOLATILE +AC_HEADER_STDBOOL +AC_PROG_RANLIB +AC_TYPE_SIZE_T + +dnl Check if using sonames is requested +dnl THIS IS TEMPORARY! +AC_MSG_CHECKING(if a soname should be set) +AC_ARG_ENABLE(soname,AC_HELP_STRING([--enable-soname], +[Configure ODE shared library to set the soname field on ELF files]), +use_soname=$enableval,use_soname=no) +AC_MSG_RESULT($use_soname) +AM_CONDITIONAL(USE_SONAME, test x$use_soname = xyes) + + +dnl Check if we want to build demos +AC_MSG_CHECKING(if tests should be built) +AC_ARG_ENABLE(demos,AC_HELP_STRING([--enable-demos], [build tests]), enable_demos=$enableval,enable_demos=yes) +AC_MSG_RESULT($enable_demos) +AM_CONDITIONAL(ENABLE_DEMOS, test x$enable_demos = xyes) + + +AC_ARG_WITH(arch,AC_HELP_STRING([--with-arch=[arch]], +[build for $arch, where arch is any of the -march flags passed to gcc, without the -march, for example --with-arch=pentium3]), +arch=$withval,arch=no) +ARCHFLAGS="" +if test "x$arch" != xno +then + ARCHFLAGS="-march=$arch" +fi +AC_SUBST(ARCHFLAGS) + +dnl Decide whether or not SSE is available +dnl Why dont we compile and run programs like we do to find out if +dnl this is a Pentium machine further down? simple! +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. +case "$arch" in + pentium3 | pentium4 | athlon* ) + AC_DEFINE(HAVE_SSE,,[Use SSE Optimizations]) + ;; +dnl this space available for other architectures specific extensions and/or +dnl other Intel based extensions such as 3DNow, SSE2, MMX, etc. +esac + +dnl check for required headers +AC_CHECK_HEADERS( alloca.h ieeefp.h stdio.h stdlib.h math.h string.h stdarg.h malloc.h values.h float.h time.h sys/time.h ) + + +opcode=no +gimpact=no +AC_ARG_WITH(trimesh,AC_HELP_STRING([--with-trimesh=[opcode|gimpact|none]], +[use the specified system for trimesh support.]), +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 gyroscopic term should be used) +AC_ARG_ENABLE(gyroscopic,AC_HELP_STRING([--disable-gyroscopic], +[Configure ODE to work without gyroscopic term (may improve stability)]), +gyroscopic=$enableval,gyroscopic=yes) +AC_MSG_RESULT($gyroscopic) +if test x"$gyroscopic" = xyes +then +AC_DEFINE(dGYROSCOPIC,,[Use gyroscopic terms]) +fi + +dnl Check Precision, define the dInfinity constant--------------------------/ +AC_MSG_CHECKING(if double precision is requested) +AC_ARG_ENABLE(double-precision,AC_HELP_STRING([--enable-double-precision], +[Configure ODE to work with double precision, if not specified, single precision is used]), +precision=$enableval,precision=no) +if test "$precision" != no +then +dnl DOUBLE was chosen +AC_DEFINE(dDOUBLE,,[Use double precision]) +dnl Check from lest likelly to more likelly. +if test "$build_os" == "$target_os" +then +AC_TRY_RUN([ +#define dInfinity 1e20 +int main() +{ +if (dInfinity > 1e10 && -dInfinity < -1e10 && -dInfinity < dInfinity) +return 0; +else return -1; +} +],dinfinity=1e20,,) +AC_TRY_RUN([ +#define dInfinity 1.7976931348623157e+308 +int main() +{ +if (dInfinity > 1e10 && -dInfinity < -1e10 && -dInfinity < dInfinity) +return 0; +else return -1; +} +],dinfinity=1.7976931348623157e+308,,) +AC_TRY_RUN([ +#include +#define dInfinity HUGE_VAL +int main() +{ +if (dInfinity > 1e10 && -dInfinity < -1e10 && -dInfinity < dInfinity) +return 0; +else return -1; +} +],dinfinity=HUGE_VAL,,) +AC_TRY_RUN([ +#include +#define dInfinity DBL_MAX +int main() +{ +if (dInfinity > 1e10 && -dInfinity < -1e10 && -dInfinity < dInfinity) +return 0; +else return -1; +} +],dinfinity=DBL_MAX,,) +else +#cross-compiling, use a reasonable value. We should add an option for setting this. +dinfinity=DBL_MAX +fi +else +dnl default to SINGLE. +AC_DEFINE(dSINGLE,,[Use single precision]) +dnl Check from lest likelly to more likelly. +if test "$build_os" == "$target_os" +then +AC_TRY_RUN([ +#define dInfinity 1e20f +int main() +{ +if (dInfinity > 1e10f && -dInfinity < -1e10f && -dInfinity < dInfinity) +return 0; +else return -1; +} +],dinfinity=1e20f,,) +AC_TRY_RUN([ +#define dInfinity 3.402823466e+38F +int main() +{ +if (dInfinity > 1e10f && -dInfinity < -1e10f && -dInfinity < dInfinity) +return 0; +else return -1; +} +],dinfinity=3.402823466e+38F,,) +AC_TRY_RUN([ +#include +#define dInfinity HUGE_VALF +int main() +{ +if (dInfinity > 1e10f && -dInfinity < -1e10f && -dInfinity < dInfinity) +return 0; +else return -1; +} +],dinfinity=HUGE_VALF,,) +AC_TRY_RUN([ +#include +#define dInfinity FLT_MAX +int main() +{ +if (dInfinity > 1e10f && -dInfinity < -1e10f && -dInfinity < dInfinity) +return 0; +else return -1; +} +],dinfinity=FLT_MAX,,) +#cross-compiling, use a reasonable value. We should add an option for setting this. +dinfinity=FLT_MAX +fi +fi +AC_MSG_RESULT($precision) +AC_DEFINE_UNQUOTED(dInfinity,${dinfinity},[dInfinity Constant]) +AC_MSG_CHECKING(for appropriate dInfinity constant) +AC_MSG_RESULT($dinfinity) +dnl --------------------------------------------------------------------------/ + +dnl Define dEpsilon +AC_CHECK_HEADER(float.h,[have_float_h=yes],[have_float_h=no]) +AC_MSG_CHECKING(for appropriate dEpsilon constant) +if test "x$have_float_h" == xyes +then +if test $precision == yes +then +dEpsilon=DBL_EPSILON +else +dEpsilon=FLT_EPSILON +fi +else +if test $precision == yes +then +dEpsilon=2.2204460492503131e-16 +else +dEpsilon=1.19209290e-07f +fi +fi +AC_DEFINE_UNQUOTED(dEpsilon,${dEpsilon},[dEpsilon Constant]) +AC_MSG_RESULT($dEpsilon) + + +dnl Check for PENTIUM +if test "$build_os" == "$target_os" +then +AC_MSG_CHECKING(for a Pentium CPU) +AC_TRY_RUN([ +int main() +{ +asm ("mov \$0,%%eax;\n" + "cpuid\n" : : : "%eax"); +return 0; +}; +],pentium=yes,pentium=no,) +else +pentium=no +fi +if test "x$pentium" == xyes +then +AC_DEFINE(PENTIUM,1,[is this a pentium on a gcc-based platform?]) +fi +AC_MSG_RESULT($pentium) + +dnl Check for 64bit CPU +AC_MSG_CHECKING(for a x86-64 CPU) +if test "$build_os" == "$target_os" +then +AC_TRY_RUN([ +int main() +{ +int a = 0; +int * pa = &a; +asm ("mov %0,%%rax\n" + "movl (%%rax),%%eax\n" + : : "r"(pa) : "%rax"); +return 0; +}; +],cpu64=yes,cpu64=no,) +else +cpu64=no +fi +if test "x$cpu64" == xyes +then +AC_DEFINE(X86_64_SYSTEM,1,[is this a X86_64 system on a gcc-based platform?]) +fi +AC_MSG_RESULT($cpu64) +AM_CONDITIONAL(X86_64_SYSTEM, test x$cpu64 = xyes) + +AC_MSG_CHECKING(if building a release library) +AC_ARG_ENABLE(release,AC_HELP_STRING([--enable-release], +[build a release library with -fomit-frame-pointer and -ffast-math]), +release=$enableval,release=no) +if test "x$release" == xyes +then + CFLAGS="$CFLAGS -fomit-frame-pointer -ffast-math" + CPPFLAGS="$CPPFLAGS -fomit-frame-pointer -ffast-math" + CXXFLAGS="$CXXFLAGS -fomit-frame-pointer -ffast-math" + AC_DEFINE(dNODEBUG,,[Disable debug output]) +fi +AC_MSG_RESULT($release) + +AC_MSG_CHECKING(if building a debug library) +AC_ARG_ENABLE(debug,AC_HELP_STRING([--enable-debug], +[Add debug symbols to the library with -g]), +debug=$enableval,debug=yes) +if test "x$debug" == xyes +then + CFLAGS="$CFLAGS -g" + CPPFLAGS="$CPPFLAGS -g" + CXXFLAGS="$CXXFLAGS -g" +fi +AC_MSG_RESULT($debug) + + +dnl Check variable type sizes +AC_CHECK_SIZEOF(char) +AC_CHECK_SIZEOF(int) +AC_CHECK_SIZEOF(short) +AC_CHECK_SIZEOF(long int) +AC_CHECK_SIZEOF(void*) + +dnl Set some Platform Specific Variables +case "$host_os" in + cygwin* | mingw*) + so_ext=".dll" + DLLDEFINE="-DODE_DLL" + SHARED_LDFLAGS="-shared" + drawstuff="Win32" # if in a Windows enviroment + ;; + *apple* | *darwin*) # For Mac OS X + so_ext=".dylib" + DLLDEFINE="" + SHARED_LDFLAGS="-dynamiclib" + drawstuff="OSX" + 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" + ;; + *) + drawstuff="X11" # if anything else default to X11 + if test x$use_soname = xyes; then + so_ext=".so.$ODE_RELEASE" + else + so_ext=".so" + fi + DLLDEFINE="" + SHARED_LDFLAGS="-shared" + ;; +esac +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) +AC_SUBST(DRAWSTUFF) +dnl Set shared library variables +AC_MSG_CHECKING(for the suffix of shared libraries) +AC_MSG_RESULT($so_ext) +AC_DEFINE_UNQUOTED(SO_EXT,"$so_ext",[The extension for shared libraries.]) +AC_SUBST(so_ext) +AC_SUBST(SHARED_LDFLAGS) + +dnl Check for AC_PATH_X variables +if test "X$x_includes" != "XNONE"; then + CFLAGS="$CFLAGS -I$x_includes" + CXXFLAGS="$CXXFLAGS -I$x_includes" +fi +if test "X$x_libraries" != "XNONE"; then + CFLAGS="$CFLAGS -L$x_libraries" + CXXFLAGS="$CXXFLAGS -L$x_libraries" +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 + AC_CHECK_HEADERS(GL/gl.h GL/glu.h GL/glext.h,,, + [[#if HAVE_GL_GL_H + #include + #endif + #if HAVE_GL_GLU_H + #include + #endif + ]]) + AC_CHECK_LIB(GL, main,[GL_LIBS="$GL_LIBS -lGL"]) + TEMP_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $GL_LIBS" + AC_CHECK_LIB(GLU, main,[GL_LIBS="$GL_LIBS -lGLU"]) + LDFLAGS="$TEMP_LDFLAGS" + AC_CHECK_LIB(opengl32, main,[GL_LIBS="$GL_LIBS -lopengl32"]) + AC_CHECK_LIB(glu32, main,[GL_LIBS="$GL_LIBS -lglu32"]) + AC_CHECK_LIB(Xmu, main,[GL_LIBS="$GL_LIBS -lXmu"]) + AC_CHECK_LIB(Xi, main,[GL_LIBS="$GL_LIBS -lXi"]) + AC_CHECK_LIB(X, main,[GL_LIBS="$GL_LIBS -lX"]) + AC_CHECK_LIB(X11, main,[GL_LIBS="$GL_LIBS -lX11"]) +fi +AC_SUBST(GL_LIBS) + +dnl Add some Windows libraries if found +AC_CHECK_LIB(comctl32,main,[LIBS="$LIBS -lcomctl32"]) +AC_CHECK_LIB(kernel32,main,[LIBS="$LIBS -lkernel32"]) +AC_CHECK_LIB(user32,main,[LIBS="$LIBS -luser32"]) +AC_CHECK_LIB(gdi32,main,[LIBS="$LIBS -lgdi32"]) +AC_CHECK_LIB(winmm,main,[LIBS="$LIBS -lwinmm"]) + +dnl Add math and standard c++ lib just in case +AC_CHECK_LIB(stdc++,main,[LIBS="$LIBS -lstdc++"]) +AC_CHECK_LIB(m,main,[LIBS="$LIBS -lm"]) +AC_CHECK_LIB(pthread,main,[LIBS="$LIBS -lpthread"]) + + +TOPDIR=`cd $srcdir;pwd` +AC_SUBST(TOPDIR) + +dnl Check if the user wants to profile ODE using gprof +AC_MSG_CHECKING(for gprof) +AC_ARG_ENABLE(gprof, +AC_HELP_STRING([--enable-gprof],[enable profiling with gprof]), +gprof=$enableval,gprof=no) +if test "$gprof" != no +then + CFLAGS="-pg $CFLAGS" + CPPFLAGS="-pg $CPPFLAGS" + CXXFLAGS="-pg $CXXFLAGS" + AC_CHECK_LIB(gmon, main,[LIBS="$LIBS -lgmon"]) + AC_MSG_RESULT(enabled) +else + AC_MSG_RESULT(no) +fi + +dnl Check for autoscan sugested functions +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]) +if test "$build_os" == "$target_os" +then +AC_FUNC_ALLOCA +AC_FUNC_MALLOC +AC_FUNC_OBSTACK +AC_FUNC_REALLOC +AC_FUNC_SELECT_ARGTYPES +AC_FUNC_VPRINTF +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 +#if defined(HAVE_IEEEFP_H) && !defined(__CYGWIN__) +// This header creates conflicts with math.h in Cygwin. +#include +#endif +#ifdef HAVE_STDIO_H +#include +#endif +#ifdef HAVE_STDLIB_H +#include +#endif +#ifdef HAVE_MATH_H +#include +#endif +#ifdef HAVE_STRING_H +#include +#endif +#ifdef HAVE_STDARG_H +#include +#endif +#ifdef HAVE_MALLOC_H +#include +#endif +#ifdef HAVE_VALUES_H +#include +#endif +#ifdef HAVE_FLOAT_H +#include +#endif +#if SIZEOF_CHAR == 1 +typedef char int8; +typedef unsigned char uint8; +#else +#error "expecting sizeof(char) == 1" +#endif +#if SIZEOF_SHORT == 2 +typedef short int16; +typedef unsigned short uint16; +#else +#error "can not find 2 byte integer type" +#endif +/* integer types (we assume int >= 32 bits) */ +#if SIZEOF_INT == 4 +typedef short int32; +typedef unsigned short uint32; +#else +#error "can not find 4 byte integer type" +#endif +/* an integer type that we can safely cast a pointer to and + * from without loss of bits. + */ +#if SIZEOF_SHORT == SIZEOF_VOIDP +typedef unsigned short intP; +#elif SIZEOF_INT == SIZEOF_VOIDP +typedef unsigned int intP; +#elif SIZEOF_LONG_INT == SIZEOF_VOIDP +typedef unsigned long int intP; +#endif + +/* +Handle Windows DLL odities +Its easier to export all symbols using the -shared flag +for MinGW than differentiating with declspec, +so only do it for MSVC +*/ +#if defined(ODE_DLL) && defined(WIN32) && defined(_MSC_VER) +#define ODE_API __declspec( dllexport ) +#elif !defined(ODE_DLL) && defined(WIN32) && defined(MSC_VER) +#define ODE_API __declspec( dllimport ) +#else +#define ODE_API +#endif + +#endif /* #define ODE_CONFIG_H */ +]) + + +dnl Finally write our Makefiles +AC_OUTPUT([ + Makefile + include/Makefile + include/ode/Makefile + ode/Makefile + ode/src/Makefile + drawstuff/Makefile + drawstuff/src/Makefile + drawstuff/dstest/Makefile + ode/demo/Makefile + tests/Makefile + tests/CppTestHarness/Makefile + ode-config + ]) + +chmod +x ode-config + +dnl Print some useful information +echo "Configuration:" +echo " Target system type: $target" +echo " Build system type: $build" +echo " Host system type: $host" +echo " Use double precision: $precision" +echo " Use OPCODE: $opcode" +echo " Use GIMPACT: $gimpact" +echo " Use gyroscopic term: $gyroscopic" +echo " Is this a Pentium: $pentium" +echo " Is the CPU x86-64: $cpu64" +echo " Is this a release build: $release" +echo " Adding debug symbols: $debug" +echo " Using SONAME: $use_soname" +echo " Headers will be installed in $prefix/include/ode" +echo " Libraries will be installed in $prefix/lib" + +if test $gimpact = yes -a $precision = yes +then + echo "WARNING! Double precision not yet supported for GIMPACT" +fi + diff --git a/libraries/ode-0.9/contrib/BreakableJoints/README.txt b/libraries/ode-0.9/contrib/BreakableJoints/README.txt new file mode 100644 index 0000000000..e996816fde --- /dev/null +++ b/libraries/ode-0.9/contrib/BreakableJoints/README.txt @@ -0,0 +1,110 @@ +Breakable Joints + +================================================================================ + +Description: +This is a small addition to ODE that makes joints breakable. Breakable means +that if a force on a joint is to high it wil break. I have included a modified +version of test_buggy.cpp (test_breakable.cpp) so you can see it for your self. +Just drive your buggy into an obstacle and enjoy! + +================================================================================ + +Installation instructions: +- copy joint.h, joint.cpp, ode.cpp and step.cpp to the ode/src/ directory +- copy common.h and object.h to the include/ directory +- copy test_breakable.cpp to the ode/test/ directory +- add test_breakable.cpp to the ODE_TEST_SRC_CPP object in the makefile. +- make ode-lib +- make ode-test +You can also use the diffs. The above files will quickly go out of sync with the +rest of ODE but the diffs wil remain valid longer. + +================================================================================ + +Functions: +dJointSetBreakable (dJointID joint, int b) + If b is 1 the joint is made breakable. If b is 0 the joint is made + unbreakable. + +void dJointSetBreakCallback (dJointID joint, dJointBreakCallback *callbackFunc) + Sets the callback function for this joint. If a funtion is set it will be + called if the joint is broken but before it is actually detached or deleted. + +void dJointSetBreakMode (dJointID joint, int mode) + Use this functions to set some flags. These flags can be ORred ( | ) + together; ie. dJointSetBreakMode (someJoint, +dJOINT_BREAK_AT_B1_FORCE|dJOINT_DELETE_ON_BREAK) + dJOINT_DELETE_ON_BREAK - If the joint breaks it wil be deleted. + dJOINT_BREAK_AT_B1_FORCE - If the force on body 1 is to high the joint will + break + dJOINT_BREAK_AT_B1_TORQUE - If the torque on body 1 is to high the joint will + break + dJOINT_BREAK_AT_B2_FORCE - If the force on body 2 is to high the joint will + break + dJOINT_BREAK_AT_B2_TORQUE - If the torque on body 2 is to high the joint will + break + +void dJointSetBreakForce (dJointID joint, int body, dReal x, dReal y, dReal z) + With this function you can set the maximum force for a body connected to this + joint. A value of 0 for body means body 1, 1 means body 2. The force is + relative to the bodies rotation. + +void dJointSetBreakTorque (dJointID joint, int body, dReal x, dReal y, dReal z) + With this function you can set the maximum torque for a body connected to this + joint. A value of 0 for body means body 1, 1 means body 2. The torque is + relative to the bodies rotation. + +int dJointIsBreakable (dJointID joint) + Returns 1 if this joint is breakable, 0 otherwise. + +int dJointGetBreakMode (dJointID joint) + Returns the breakmode flag. + +void dJointGetBreakForce (dJointID joint, int body, dReal *force) + Returns the force at what this joint will break. A value of 0 for body means + body 1, 1 means body 2. force must have enough space for 3 dReal values. + +void dJointGetBreakTorque (dJointID joint, int body, dReal *torque) + Returns the torque at what this joint will break. A value of 0 for body + means body 1, 1 means body 2. force must have enough space for 3 dReal + values. + +================================================================================ + +The callback function is defined like this (in common.h): +void dJointBreakCallback (dJointID); + +================================================================================ + +Problems, known bugs & other issues: +- If the timestep is very small then joints get a lot weaker. They can even fall + apart! +- I have tested all this with the latest checkout from CVS (at the time of + writing ofcourse). I haven't tested it with earlier versions of ODE. +- I have modified the code that fills the jointfeedback struct. I haven't tested + if it still works. +- I'm not sure if the forces are really relative to the connected bodies. +- There are some memory leaks in the test_breakable.cpp example. + +================================================================================ + +Bugfixes and changes: +09/08/2003 +- I fixed a bug when there where 0 joints in the simulation + +06/12/2003 +- dJointGetBreakMode() added, by vadim_mcagon@hotmail.com + +11/03/2004 +- Updated files to work with latest CVS checkout. +- Added support for dWorldStepFast1() +- Added separate test_breakable.cpp example. +- Updated the code that breaks and destroys a joint. + +================================================================================ + +Send me an e-mail if you have any suggestions, ideas, bugs, bug-fixes, anything! +e-mail: roelvandijk@home.nl + +Roel van Dijk - 11/03/2004 diff --git a/libraries/ode-0.9/contrib/BreakableJoints/common.h b/libraries/ode-0.9/contrib/BreakableJoints/common.h new file mode 100644 index 0000000000..bc4272dbb1 --- /dev/null +++ b/libraries/ode-0.9/contrib/BreakableJoints/common.h @@ -0,0 +1,337 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without 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 + +#ifdef __cplusplus +extern "C" { +#endif + + +/* configuration stuff */ + +/* 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. + */ +#define EFFICIENT_ALIGNMENT 16 + + +/* 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 +#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()", __FUNCTION__); +#else +#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)") + +/* floating point data type, vector, matrix and quaternion types */ + +#if defined(dSINGLE) +typedef float dReal; +#elif defined(dDOUBLE) +typedef double dReal; +#else +#error You must #define dSINGLE or dDOUBLE +#endif + + +/* 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) ((float)(1.0f/(x))) /* reciprocal */ +#define dSqrt(x) ((float)sqrt(x)) /* square root */ +#define dRecipSqrt(x) ((float)(1.0f/sqrt(x))) /* reciprocal square root */ +#define dSin(x) ((float)sin(x)) /* sine */ +#define dCos(x) ((float)cos(x)) /* cosine */ +#define dFabs(x) ((float)fabs(x)) /* absolute value */ +#define dAtan2(y,x) ((float)atan2((y),(x))) /* arc tangent with 2 args */ + +#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)) + +#else +#error You must #define dSINGLE or dDOUBLE +#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(((int)(alloca((n)+(EFFICIENT_ALIGNMENT-1)))))) + + +/* 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 */ + +enum { + dJointTypeNone = 0, /* or "unknown" */ + dJointTypeBall, + dJointTypeHinge, + dJointTypeSlider, + dJointTypeContact, + dJointTypeUniversal, + dJointTypeHinge2, + dJointTypeFixed, + dJointTypeNull, + dJointTypeAMotor +}; + +/******************** breakable joint contribution ***********************/ +/* joint break callback function */ +typedef void dJointBreakCallback (dJointID joint); + +/* joint break modes */ +enum { + // if this flag is set, the joint wil break + dJOINT_BROKEN = 0x0001, + // if this flag is set, the joint wil be deleted when it breaks + dJOINT_DELETE_ON_BREAK = 0x0002, + // if this flag is set, the joint can break at a certain force on body 1 + dJOINT_BREAK_AT_B1_FORCE = 0x0004, + // if this flag is set, the joint can break at a certain torque on body 1 + dJOINT_BREAK_AT_B1_TORQUE = 0x0008, + // if this flag is set, the joint can break at a certain force on body 2 + dJOINT_BREAK_AT_B2_FORCE = 0x0010, + // if this flag is set, the joint can break at a certain torque on body 2 + dJOINT_BREAK_AT_B2_TORQUE = 0x0020 +}; +/*************************************************************************/ + +/* 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, + +#define D_ALL_PARAM_NAMES_X(start,x) \ + /* 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, + +enum { + D_ALL_PARAM_NAMES(0) + 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); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/ode-0.9/contrib/BreakableJoints/diff/common.h.diff b/libraries/ode-0.9/contrib/BreakableJoints/diff/common.h.diff new file mode 100644 index 0000000000..24415a1468 --- /dev/null +++ b/libraries/ode-0.9/contrib/BreakableJoints/diff/common.h.diff @@ -0,0 +1,21 @@ +208,227d207 +< /******************** breakable joint contribution ***********************/ +< /* joint break callback function */ +< typedef void dJointBreakCallback (dJointID joint); +< +< /* joint break modes */ +< enum { +< // if this flag is set, the joint wil break +< dJOINT_BROKEN = 0x0001, +< // if this flag is set, the joint wil be deleted when it breaks +< dJOINT_DELETE_ON_BREAK = 0x0002, +< // if this flag is set, the joint can break at a certain force on body 1 +< dJOINT_BREAK_AT_B1_FORCE = 0x0004, +< // if this flag is set, the joint can break at a certain torque on body 1 +< dJOINT_BREAK_AT_B1_TORQUE = 0x0008, +< // if this flag is set, the joint can break at a certain force on body 2 +< dJOINT_BREAK_AT_B2_FORCE = 0x0010, +< // if this flag is set, the joint can break at a certain torque on body 2 +< dJOINT_BREAK_AT_B2_TORQUE = 0x0020 +< }; +< /*************************************************************************/ diff --git a/libraries/ode-0.9/contrib/BreakableJoints/diff/joint.cpp.diff b/libraries/ode-0.9/contrib/BreakableJoints/diff/joint.cpp.diff new file mode 100644 index 0000000000..80397f0e5d --- /dev/null +++ b/libraries/ode-0.9/contrib/BreakableJoints/diff/joint.cpp.diff @@ -0,0 +1,148 @@ +2659,2804d2658 +< +< /******************** breakable joint contribution ***********************/ +< extern "C" void dJointSetBreakable (dxJoint *joint, int b) { +< dAASSERT(joint); +< if (b) { +< // we want this joint to be breakable but we must first check if it +< // was already breakable +< if (!joint->breakInfo) { +< // allocate a dxJointBreakInfo struct +< joint->breakInfo = new dxJointBreakInfo; +< joint->breakInfo->flags = 0; +< for (int i = 0; i < 3; i++) { +< joint->breakInfo->b1MaxF[0] = 0; +< joint->breakInfo->b1MaxT[0] = 0; +< joint->breakInfo->b2MaxF[0] = 0; +< joint->breakInfo->b2MaxT[0] = 0; +< } +< joint->breakInfo->callback = 0; +< } +< else { +< // the joint was already breakable +< return; +< } +< } +< else { +< // we want this joint to be unbreakable mut we must first check if +< // it is alreay unbreakable +< if (joint->breakInfo) { +< // deallocate the dxJointBreakInfo struct +< delete joint->breakInfo; +< joint->breakInfo = 0; +< } +< else { +< // the joint was already unbreakable +< return; +< } +< } +< } +< +< extern "C" void dJointSetBreakCallback (dxJoint *joint, dJointBreakCallback *callbackFunc) { +< dAASSERT(joint); +< # ifndef dNODEBUG +< // only works for a breakable joint +< if (!joint->breakInfo) { +< dDebug (0, "dJointSetBreakCallback called on unbreakable joint"); +< } +< # endif +< joint->breakInfo->callback = callbackFunc; +< } +< +< extern "C" void dJointSetBreakMode (dxJoint *joint, int mode) { +< dAASSERT(joint); +< # ifndef dNODEBUG +< // only works for a breakable joint +< if (!joint->breakInfo) { +< dDebug (0, "dJointSetBreakMode called on unbreakable joint"); +< } +< # endif +< joint->breakInfo->flags = mode; +< } +< +< extern "C" int dJointGetBreakMode (dxJoint *joint) { +< dAASSERT(joint); +< # ifndef dNODEBUG +< // only works for a breakable joint +< if (!joint->breakInfo) { +< dDebug (0, "dJointGetBreakMode called on unbreakable joint"); +< } +< # endif +< return joint->breakInfo->flags; +< } +< +< extern "C" void dJointSetBreakForce (dxJoint *joint, int body, dReal x, dReal y, dReal z) { +< dAASSERT(joint); +< # ifndef dNODEBUG +< // only works for a breakable joint +< if (!joint->breakInfo) { +< dDebug (0, "dJointSetBreakForce called on unbreakable joint"); +< } +< # endif +< if (body) { +< joint->breakInfo->b2MaxF[0] = x; +< joint->breakInfo->b2MaxF[1] = y; +< joint->breakInfo->b2MaxF[2] = z; +< } +< else { +< joint->breakInfo->b1MaxF[0] = x; +< joint->breakInfo->b1MaxF[1] = y; +< joint->breakInfo->b1MaxF[2] = z; +< } +< } +< +< extern "C" void dJointSetBreakTorque (dxJoint *joint, int body, dReal x, dReal y, dReal z) { +< dAASSERT(joint); +< # ifndef dNODEBUG +< // only works for a breakable joint +< if (!joint->breakInfo) { +< dDebug (0, "dJointSetBreakTorque called on unbreakable joint"); +< } +< # endif +< if (body) { +< joint->breakInfo->b2MaxT[0] = x; +< joint->breakInfo->b2MaxT[1] = y; +< joint->breakInfo->b2MaxT[2] = z; +< } +< else { +< joint->breakInfo->b1MaxT[0] = x; +< joint->breakInfo->b1MaxT[1] = y; +< joint->breakInfo->b1MaxT[2] = z; +< } +< } +< +< extern "C" int dJointIsBreakable (dxJoint *joint) { +< dAASSERT(joint); +< return joint->breakInfo != 0; +< } +< +< extern "C" void dJointGetBreakForce (dxJoint *joint, int body, dReal *force) { +< dAASSERT(joint); +< # ifndef dNODEBUG +< // only works for a breakable joint +< if (!joint->breakInfo) { +< dDebug (0, "dJointGetBreakForce called on unbreakable joint"); +< } +< # endif +< if (body) +< for (int i=0; i<3; i++) force[i]=joint->breakInfo->b2MaxF[i]; +< else +< for (int i=0; i<3; i++) force[i]=joint->breakInfo->b1MaxF[i]; +< } +< +< extern "C" void dJointGetBreakTorque (dxJoint *joint, int body, dReal *torque) { +< dAASSERT(joint); +< # ifndef dNODEBUG +< // only works for a breakable joint +< if (!joint->breakInfo) { +< dDebug (0, "dJointGetBreakTorque called on unbreakable joint"); +< } +< # endif +< if (body) +< for (int i=0; i<3; i++) torque[i]=joint->breakInfo->b2MaxT[i]; +< else +< for (int i=0; i<3; i++) torque[i]=joint->breakInfo->b1MaxT[i]; +< } +< /*************************************************************************/ +< +\ No newline at end of file diff --git a/libraries/ode-0.9/contrib/BreakableJoints/diff/joint.h.diff b/libraries/ode-0.9/contrib/BreakableJoints/diff/joint.h.diff new file mode 100644 index 0000000000..eed3c244df --- /dev/null +++ b/libraries/ode-0.9/contrib/BreakableJoints/diff/joint.h.diff @@ -0,0 +1,18 @@ +61,70d60 +< /******************** breakable joint contribution ***********************/ +< struct dxJointBreakInfo : public dBase { +< int flags; +< dReal b1MaxF[3]; // maximum force on body 1 +< dReal b1MaxT[3]; // maximum torque on body 1 +< dReal b2MaxF[3]; // maximum force on body 2 +< dReal b2MaxT[3]; // maximum torque on body 2 +< dJointBreakCallback *callback; // function that is called when this joint breaks +< }; +< /*************************************************************************/ +135,140d124 +< +< /******************** breakable joint contribution ***********************/ +< // optional break info structure. if this is not NULL the the joint is +< // breakable. +< dxJointBreakInfo *breakInfo; +< /*************************************************************************/ diff --git a/libraries/ode-0.9/contrib/BreakableJoints/diff/objects.h.diff b/libraries/ode-0.9/contrib/BreakableJoints/diff/objects.h.diff new file mode 100644 index 0000000000..fd2129e7e7 --- /dev/null +++ b/libraries/ode-0.9/contrib/BreakableJoints/diff/objects.h.diff @@ -0,0 +1,13 @@ +168,179d167 +< /******************** breakable joint contribution ***********************/ +< void dJointSetBreakable (dJointID, int b); +< void dJointSetBreakCallback (dJointID, dJointBreakCallback *callbackFunc); +< void dJointSetBreakMode (dJointID, int mode); +< int dJointGetBreakMode (dJointID); +< void dJointSetBreakForce (dJointID, int body, dReal x, dReal y, dReal z); +< void dJointSetBreakTorque (dJointID, int body, dReal x, dReal y, dReal z); +< int dJointIsBreakable (dJointID); +< void dJointGetBreakForce (dJointID, int body, dReal *force); +< void dJointGetBreakTorque (dJointID, int body, dReal *torque); +< /*************************************************************************/ +< diff --git a/libraries/ode-0.9/contrib/BreakableJoints/diff/ode.cpp.diff b/libraries/ode-0.9/contrib/BreakableJoints/diff/ode.cpp.diff new file mode 100644 index 0000000000..761b7be2e3 --- /dev/null +++ b/libraries/ode-0.9/contrib/BreakableJoints/diff/ode.cpp.diff @@ -0,0 +1,28 @@ +212,230d211 +< /******************** breakable joint contribution ***********************/ +< dxJoint* nextJ; +< if (!world->firstjoint) +< nextJ = 0; +< else +< nextJ = (dxJoint*)world->firstjoint->next; +< for (j=world->firstjoint; j; j=nextJ) { +< nextJ = (dxJoint*)j->next; +< // check if joint is breakable and broken +< if (j->breakInfo && j->breakInfo->flags & dJOINT_BROKEN) { +< // detach (break) the joint +< dJointAttach (j, 0, 0); +< // call the callback function if it is set +< if (j->breakInfo->callback) j->breakInfo->callback (j); +< // finally destroy the joint if the dJOINT_DELETE_ON_BREAK is set +< if (j->breakInfo->flags & dJOINT_DELETE_ON_BREAK) dJointDestroy (j); +< } +< } +< /*************************************************************************/ +931,933d911 +< /******************** breakable joint contribution ***********************/ +< j->breakInfo = 0; +< /*************************************************************************/ +1011,1013d988 +< /******************** breakable joint contribution ***********************/ +< if (j->breakInfo) delete j->breakInfo; +< /*************************************************************************/ diff --git a/libraries/ode-0.9/contrib/BreakableJoints/diff/step.cpp.diff b/libraries/ode-0.9/contrib/BreakableJoints/diff/step.cpp.diff new file mode 100644 index 0000000000..dfc8c2f87b --- /dev/null +++ b/libraries/ode-0.9/contrib/BreakableJoints/diff/step.cpp.diff @@ -0,0 +1,130 @@ +966,1066c966,989 +< /******************** breakable joint contribution ***********************/ +< // this saves us a few dereferences +< dxJointBreakInfo *jBI = joint[i]->breakInfo; +< // we need joint feedback if the joint is breakable or if the user +< // requested feedback. +< if (jBI||fb) { +< // we need 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. +< dJointFeedback temp_fb; // temporary storage for joint feedback +< dReal data1[8],data2[8]; +< Multiply1_8q1 (data1, JJ, lambda+ofs[i], info[i].m); +< dReal *cf1 = cforce + 8*b1->tag; +< cf1[0] += (temp_fb.f1[0] = data1[0]); +< cf1[1] += (temp_fb.f1[1] = data1[1]); +< cf1[2] += (temp_fb.f1[2] = data1[2]); +< cf1[4] += (temp_fb.t1[0] = data1[4]); +< cf1[5] += (temp_fb.t1[1] = data1[5]); +< cf1[6] += (temp_fb.t1[2] = data1[6]); +< if (b2) { +< Multiply1_8q1 (data2, JJ + 8*info[i].m, lambda+ofs[i], info[i].m); +< dReal *cf2 = cforce + 8*b2->tag; +< cf2[0] += (temp_fb.f2[0] = data2[0]); +< cf2[1] += (temp_fb.f2[1] = data2[1]); +< cf2[2] += (temp_fb.f2[2] = data2[2]); +< cf2[4] += (temp_fb.t2[0] = data2[4]); +< cf2[5] += (temp_fb.t2[1] = data2[5]); +< cf2[6] += (temp_fb.t2[2] = data2[6]); +< } +< // if the user requested so we must copy the feedback information to +< // the feedback struct that the user suplied. +< if (fb) { +< // copy temp_fb to fb +< fb->f1[0] = temp_fb.f1[0]; +< fb->f1[1] = temp_fb.f1[1]; +< fb->f1[2] = temp_fb.f1[2]; +< fb->t1[0] = temp_fb.t1[0]; +< fb->t1[1] = temp_fb.t1[1]; +< fb->t1[2] = temp_fb.t1[2]; +< if (b2) { +< fb->f2[0] = temp_fb.f2[0]; +< fb->f2[1] = temp_fb.f2[1]; +< fb->f2[2] = temp_fb.f2[2]; +< fb->t2[0] = temp_fb.t2[0]; +< fb->t2[1] = temp_fb.t2[1]; +< fb->t2[2] = temp_fb.t2[2]; +< } +< } +< // if the joint is breakable we need to check the breaking conditions +< if (jBI) { +< dReal relCF1[3]; +< dReal relCT1[3]; +< // multiply the force and torque vectors by the rotation matrix of body 1 +< dMULTIPLY1_331 (&relCF1[0],b1->R,&temp_fb.f1[0]); +< dMULTIPLY1_331 (&relCT1[0],b1->R,&temp_fb.t1[0]); +< if (jBI->flags & dJOINT_BREAK_AT_B1_FORCE) { +< // check if the force is to high +< for (int i = 0; i < 3; i++) { +< if (relCF1[i] > jBI->b1MaxF[i]) { +< jBI->flags |= dJOINT_BROKEN; +< goto doneCheckingBreaks; +< } +< } +< } +< if (jBI->flags & dJOINT_BREAK_AT_B1_TORQUE) { +< // check if the torque is to high +< for (int i = 0; i < 3; i++) { +< if (relCT1[i] > jBI->b1MaxT[i]) { +< jBI->flags |= dJOINT_BROKEN; +< goto doneCheckingBreaks; +< } +< } +< } +< if (b2) { +< dReal relCF2[3]; +< dReal relCT2[3]; +< // multiply the force and torque vectors by the rotation matrix of body 2 +< dMULTIPLY1_331 (&relCF2[0],b2->R,&temp_fb.f2[0]); +< dMULTIPLY1_331 (&relCT2[0],b2->R,&temp_fb.t2[0]); +< if (jBI->flags & dJOINT_BREAK_AT_B2_FORCE) { +< // check if the force is to high +< for (int i = 0; i < 3; i++) { +< if (relCF2[i] > jBI->b2MaxF[i]) { +< jBI->flags |= dJOINT_BROKEN; +< goto doneCheckingBreaks; +< } +< } +< } +< if (jBI->flags & dJOINT_BREAK_AT_B2_TORQUE) { +< // check if the torque is to high +< for (int i = 0; i < 3; i++) { +< if (relCT2[i] > jBI->b2MaxT[i]) { +< jBI->flags |= dJOINT_BROKEN; +< goto doneCheckingBreaks; +< } +< } +< } +< } +< doneCheckingBreaks: +< ; +--- +> 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]; +> Multiply1_8q1 (data1, JJ, lambda+ofs[i], info[i].m); +> dReal *cf1 = cforce + 8*b1->tag; +> 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 (b2){ +> Multiply1_8q1 (data2, JJ + 8*info[i].m, lambda+ofs[i], info[i].m); +> dReal *cf2 = cforce + 8*b2->tag; +> 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]); +> } +1068,1069d990 +< } +< /*************************************************************************/ diff --git a/libraries/ode-0.9/contrib/BreakableJoints/diff/stepfast.cpp.diff b/libraries/ode-0.9/contrib/BreakableJoints/diff/stepfast.cpp.diff new file mode 100644 index 0000000000..ed64cbaec9 --- /dev/null +++ b/libraries/ode-0.9/contrib/BreakableJoints/diff/stepfast.cpp.diff @@ -0,0 +1,143 @@ +587,598c587,593 +< /******************** breakable joint contribution ***********************/ +< // this saves us a few dereferences +< dxJointBreakInfo *jBI = joint->breakInfo; +< // we need joint feedback if the joint is breakable or if the user +< // requested feedback. +< if (jBI||fb) { +< // we need 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. +< dJointFeedback temp_fb; // temporary storage for joint feedback +< dReal data1[8],data2[8]; +--- +> 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]; +603,608c598,603 +< cf1[0] = (temp_fb.f1[0] = data1[0]); +< cf1[1] = (temp_fb.f1[1] = data1[1]); +< cf1[2] = (temp_fb.f1[2] = data1[2]); +< cf1[4] = (temp_fb.t1[0] = data1[4]); +< cf1[5] = (temp_fb.t1[1] = data1[5]); +< cf1[6] = (temp_fb.t1[2] = data1[6]); +--- +> 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]); +614,691c609,614 +< cf2[0] = (temp_fb.f2[0] = data2[0]); +< cf2[1] = (temp_fb.f2[1] = data2[1]); +< cf2[2] = (temp_fb.f2[2] = data2[2]); +< cf2[4] = (temp_fb.t2[0] = data2[4]); +< cf2[5] = (temp_fb.t2[1] = data2[5]); +< cf2[6] = (temp_fb.t2[2] = data2[6]); +< } +< // if the user requested so we must copy the feedback information to +< // the feedback struct that the user suplied. +< if (fb) { +< // copy temp_fb to fb +< fb->f1[0] = temp_fb.f1[0]; +< fb->f1[1] = temp_fb.f1[1]; +< fb->f1[2] = temp_fb.f1[2]; +< fb->t1[0] = temp_fb.t1[0]; +< fb->t1[1] = temp_fb.t1[1]; +< fb->t1[2] = temp_fb.t1[2]; +< if (body[1]) { +< fb->f2[0] = temp_fb.f2[0]; +< fb->f2[1] = temp_fb.f2[1]; +< fb->f2[2] = temp_fb.f2[2]; +< fb->t2[0] = temp_fb.t2[0]; +< fb->t2[1] = temp_fb.t2[1]; +< fb->t2[2] = temp_fb.t2[2]; +< } +< } +< // if the joint is breakable we need to check the breaking conditions +< if (jBI) { +< dReal relCF1[3]; +< dReal relCT1[3]; +< // multiply the force and torque vectors by the rotation matrix of body 1 +< dMULTIPLY1_331 (&relCF1[0],body[0]->R,&temp_fb.f1[0]); +< dMULTIPLY1_331 (&relCT1[0],body[0]->R,&temp_fb.t1[0]); +< if (jBI->flags & dJOINT_BREAK_AT_B1_FORCE) { +< // check if the force is to high +< for (int i = 0; i < 3; i++) { +< if (relCF1[i] > jBI->b1MaxF[i]) { +< jBI->flags |= dJOINT_BROKEN; +< goto doneCheckingBreaks; +< } +< } +< } +< if (jBI->flags & dJOINT_BREAK_AT_B1_TORQUE) { +< // check if the torque is to high +< for (int i = 0; i < 3; i++) { +< if (relCT1[i] > jBI->b1MaxT[i]) { +< jBI->flags |= dJOINT_BROKEN; +< goto doneCheckingBreaks; +< } +< } +< } +< if (body[1]) { +< dReal relCF2[3]; +< dReal relCT2[3]; +< // multiply the force and torque vectors by the rotation matrix of body 2 +< dMULTIPLY1_331 (&relCF2[0],body[1]->R,&temp_fb.f2[0]); +< dMULTIPLY1_331 (&relCT2[0],body[1]->R,&temp_fb.t2[0]); +< if (jBI->flags & dJOINT_BREAK_AT_B2_FORCE) { +< // check if the force is to high +< for (int i = 0; i < 3; i++) { +< if (relCF2[i] > jBI->b2MaxF[i]) { +< jBI->flags |= dJOINT_BROKEN; +< goto doneCheckingBreaks; +< } +< } +< } +< if (jBI->flags & dJOINT_BREAK_AT_B2_TORQUE) { +< // check if the torque is to high +< for (int i = 0; i < 3; i++) { +< if (relCT2[i] > jBI->b2MaxT[i]) { +< jBI->flags |= dJOINT_BROKEN; +< goto doneCheckingBreaks; +< } +< } +< } +< } +< doneCheckingBreaks: +< ; +--- +> 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]); +694d616 +< /*************************************************************************/ +1178,1196d1099 +< /******************** breakable joint contribution ***********************/ +< dxJoint* nextJ; +< if (!world->firstjoint) +< nextJ = 0; +< else +< nextJ = (dxJoint*)world->firstjoint->next; +< for (j=world->firstjoint; j; j=nextJ) { +< nextJ = (dxJoint*)j->next; +< // check if joint is breakable and broken +< if (j->breakInfo && j->breakInfo->flags & dJOINT_BROKEN) { +< // detach (break) the joint +< dJointAttach (j, 0, 0); +< // call the callback function if it is set +< if (j->breakInfo->callback) j->breakInfo->callback (j); +< // finally destroy the joint if the dJOINT_DELETE_ON_BREAK is set +< if (j->breakInfo->flags & dJOINT_DELETE_ON_BREAK) dJointDestroy (j); +< } +< } +< /*************************************************************************/ diff --git a/libraries/ode-0.9/contrib/BreakableJoints/diff/test_buggy.cpp.diff b/libraries/ode-0.9/contrib/BreakableJoints/diff/test_buggy.cpp.diff new file mode 100644 index 0000000000..65770da88c --- /dev/null +++ b/libraries/ode-0.9/contrib/BreakableJoints/diff/test_buggy.cpp.diff @@ -0,0 +1,16 @@ +266,270d265 +< +< // breakable joints contribution +< dJointSetBreakable (joint[i], 1); +< dJointSetBreakMode (joint[i], dJOINT_BREAK_AT_FORCE); +< dJointSetBreakForce (joint[i], 0.5); +298c293 +< ground_box = dCreateBox (space,2,1.5,5); +--- +> ground_box = dCreateBox (space,2,1.5,1); +300,301c295,296 +< dRFromAxisAndAngle (R,0,1,0,-0.85); +< dGeomSetPosition (ground_box,5,0,-1); +--- +> dRFromAxisAndAngle (R,0,1,0,-0.15); +> dGeomSetPosition (ground_box,2,0,-0.34); diff --git a/libraries/ode-0.9/contrib/BreakableJoints/joint.cpp b/libraries/ode-0.9/contrib/BreakableJoints/joint.cpp new file mode 100644 index 0000000000..2c724f84e7 --- /dev/null +++ b/libraries/ode-0.9/contrib/BreakableJoints/joint.cpp @@ -0,0 +1,2803 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without 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 "joint.h" + +//**************************************************************************** +// 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. + +static inline 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->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->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->pos[j] - + a1[j] - joint->node[0].body->pos[j]); + } + } + else { + for (int j=0; j<3; j++) { + info->c[j] = k * (anchor2[j] - a1[j] - + joint->node[0].body->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. + +static inline 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->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->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->pos[i]; + if (joint->node[1].body) { + for (i=0; i<3; i++) a2[i] += joint->node[1].body->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. + +static 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->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 + +static 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->pos[0]; + q[1] = y - j->node[0].body->pos[1]; + q[2] = z - j->node[0].body->pos[2]; + q[3] = 0; + dMULTIPLY1_331 (anchor1,j->node[0].body->R,q); + if (j->node[1].body) { + q[0] = x - j->node[1].body->pos[0]; + q[1] = y - j->node[1].body->pos[1]; + q[2] = z - j->node[1].body->pos[2]; + q[3] = 0; + dMULTIPLY1_331 (anchor2,j->node[1].body->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. + +static 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->R,q); + axis1[3] = 0; + } + if (axis2) { + if (j->node[1].body) { + dMULTIPLY1_331 (axis2,j->node[1].body->R,q); + } + else { + axis2[0] = x; + axis2[1] = y; + axis2[2] = z; + } + axis2[3] = 0; + } + } +} + + +static void getAnchor (dxJoint *j, dVector3 result, dVector3 anchor1) +{ + if (j->node[0].body) { + dMULTIPLY0_331 (result,j->node[0].body->R,anchor1); + result[0] += j->node[0].body->pos[0]; + result[1] += j->node[0].body->pos[1]; + result[2] += j->node[0].body->pos[2]; + } +} + + +static void getAnchor2 (dxJoint *j, dVector3 result, dVector3 anchor2) +{ + if (j->node[1].body) { + dMULTIPLY0_331 (result,j->node[1].body->R,anchor2); + result[0] += j->node[1].body->pos[0]; + result[1] += j->node[1].body->pos[1]; + result[2] += j->node[1].body->pos[2]; + } + else { + result[0] = anchor2[0]; + result[1] = anchor2[1]; + result[2] = anchor2[2]; + } +} + + +static void getAxis (dxJoint *j, dVector3 result, dVector3 axis1) +{ + if (j->node[0].body) { + dMULTIPLY0_331 (result,j->node[0].body->R,axis1); + } +} + + +static void getAxis2 (dxJoint *j, dVector3 result, dVector3 axis2) +{ + if (j->node[1].body) { + dMULTIPLY0_331 (result,j->node[1].body->R,axis2); + } + else { + result[0] = axis2[0]; + result[1] = axis2[1]; + result[2] = axis2[2]; + } +} + + +static 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 -= 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. + +static 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: + if (value <= histop) lostop = value; + break; + case dParamHiStop: + if (value >= lostop) 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, + 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; // Linear Torque Decoupling vector (a torque) + if (!rotational && joint->node[1].body) { + dVector3 c; + c[0]=REAL(0.5)*(joint->node[1].body->pos[0]-joint->node[0].body->pos[0]); + c[1]=REAL(0.5)*(joint->node[1].body->pos[1]-joint->node[0].body->pos[1]); + c[2]=REAL(0.5)*(joint->node[1].body->pos[2]-joint->node[0].body->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) 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; +} + +//**************************************************************************** +// ball and socket + +static void ballInit (dxJointBall *j) +{ + dSetZero (j->anchor1,4); + dSetZero (j->anchor2,4); +} + + +static void ballGetInfo1 (dxJointBall *j, dxJoint::Info1 *info) +{ + info->m = 3; + info->nub = 3; +} + + +static void ballGetInfo2 (dxJointBall *joint, dxJoint::Info2 *info) +{ + setBall (joint,info,joint->anchor1,joint->anchor2); +} + + +extern "C" void dJointSetBallAnchor (dxJointBall *joint, + dReal x, dReal y, dReal z) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__dball_vtable,"joint is not a ball"); + setAnchors (joint,x,y,z,joint->anchor1,joint->anchor2); +} + + +extern "C" void dJointGetBallAnchor (dxJointBall *joint, dVector3 result) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(result,"bad result argument"); + dUASSERT(joint->vtable == &__dball_vtable,"joint is not a ball"); + if (joint->flags & dJOINT_REVERSE) + getAnchor2 (joint,result,joint->anchor2); + else + getAnchor (joint,result,joint->anchor1); +} + + +extern "C" void dJointGetBallAnchor2 (dxJointBall *joint, dVector3 result) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(result,"bad result argument"); + dUASSERT(joint->vtable == &__dball_vtable,"joint is not a ball"); + if (joint->flags & dJOINT_REVERSE) + getAnchor (joint,result,joint->anchor1); + else + getAnchor2 (joint,result,joint->anchor2); +} + + +dxJoint::Vtable __dball_vtable = { + sizeof(dxJointBall), + (dxJoint::init_fn*) ballInit, + (dxJoint::getInfo1_fn*) ballGetInfo1, + (dxJoint::getInfo2_fn*) ballGetInfo2, + dJointTypeBall}; + +//**************************************************************************** +// hinge + +static void hingeInit (dxJointHinge *j) +{ + dSetZero (j->anchor1,4); + dSetZero (j->anchor2,4); + dSetZero (j->axis1,4); + j->axis1[0] = 1; + dSetZero (j->axis2,4); + j->axis2[0] = 1; + dSetZero (j->qrel,4); + j->limot.init (j->world); +} + + +static void hingeGetInfo1 (dxJointHinge *j, dxJoint::Info1 *info) +{ + info->nub = 5; + + // see if joint is powered + if (j->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 ((j->limot.lostop >= -M_PI || j->limot.histop <= M_PI) && + j->limot.lostop <= j->limot.histop) { + dReal angle = getHingeAngle (j->node[0].body,j->node[1].body,j->axis1, + j->qrel); + if (j->limot.testRotationalLimit (angle)) info->m = 6; + } +} + + +static void hingeGetInfo2 (dxJointHinge *joint, dxJoint::Info2 *info) +{ + // set the three ball-and-socket rows + setBall (joint,info,joint->anchor1,joint->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,joint->node[0].body->R,joint->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 (joint->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 (joint->node[1].body) { + dMULTIPLY0_331 (ax2,joint->node[1].body->R,joint->axis2); + } + else { + ax2[0] = joint->axis2[0]; + ax2[1] = joint->axis2[1]; + ax2[2] = joint->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 + joint->limot.addLimot (joint,info,5,ax1,1); +} + + +// compute initial relative rotation body1 -> body2, or env -> body1 + +static void hingeComputeInitialRelativeRotation (dxJointHinge *joint) +{ + if (joint->node[0].body) { + if (joint->node[1].body) { + dQMultiply1 (joint->qrel,joint->node[0].body->q,joint->node[1].body->q); + } + else { + // set joint->qrel to the transpose of the first body q + joint->qrel[0] = joint->node[0].body->q[0]; + for (int i=1; i<4; i++) joint->qrel[i] = -joint->node[0].body->q[i]; + } + } +} + + +extern "C" void dJointSetHingeAnchor (dxJointHinge *joint, + dReal x, dReal y, dReal z) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a hinge"); + setAnchors (joint,x,y,z,joint->anchor1,joint->anchor2); + hingeComputeInitialRelativeRotation (joint); +} + + +extern "C" void dJointSetHingeAxis (dxJointHinge *joint, + dReal x, dReal y, dReal z) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a hinge"); + setAxes (joint,x,y,z,joint->axis1,joint->axis2); + hingeComputeInitialRelativeRotation (joint); +} + + +extern "C" void dJointGetHingeAnchor (dxJointHinge *joint, dVector3 result) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(result,"bad result argument"); + dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a hinge"); + if (joint->flags & dJOINT_REVERSE) + getAnchor2 (joint,result,joint->anchor2); + else + getAnchor (joint,result,joint->anchor1); +} + + +extern "C" void dJointGetHingeAnchor2 (dxJointHinge *joint, dVector3 result) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(result,"bad result argument"); + dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a hinge"); + if (joint->flags & dJOINT_REVERSE) + getAnchor (joint,result,joint->anchor1); + else + getAnchor2 (joint,result,joint->anchor2); +} + + +extern "C" void dJointGetHingeAxis (dxJointHinge *joint, dVector3 result) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(result,"bad result argument"); + dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a hinge"); + getAxis (joint,result,joint->axis1); +} + + +extern "C" void dJointSetHingeParam (dxJointHinge *joint, + int parameter, dReal value) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a hinge"); + joint->limot.set (parameter,value); +} + + +extern "C" dReal dJointGetHingeParam (dxJointHinge *joint, int parameter) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a hinge"); + return joint->limot.get (parameter); +} + + +extern "C" dReal dJointGetHingeAngle (dxJointHinge *joint) +{ + dAASSERT(joint); + dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a 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; +} + + +extern "C" dReal dJointGetHingeAngleRate (dxJointHinge *joint) +{ + dAASSERT(joint); + dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a Hinge"); + if (joint->node[0].body) { + dVector3 axis; + dMULTIPLY0_331 (axis,joint->node[0].body->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; +} + + +extern "C" void dJointAddHingeTorque (dxJointHinge *joint, dReal torque) +{ + dVector3 axis; + dAASSERT(joint); + dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a 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]); +} + + +dxJoint::Vtable __dhinge_vtable = { + sizeof(dxJointHinge), + (dxJoint::init_fn*) hingeInit, + (dxJoint::getInfo1_fn*) hingeGetInfo1, + (dxJoint::getInfo2_fn*) hingeGetInfo2, + dJointTypeHinge}; + +//**************************************************************************** +// slider + +static void sliderInit (dxJointSlider *j) +{ + dSetZero (j->axis1,4); + j->axis1[0] = 1; + dSetZero (j->qrel,4); + dSetZero (j->offset,4); + j->limot.init (j->world); +} + + +extern "C" dReal dJointGetSliderPosition (dxJointSlider *joint) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__dslider_vtable,"joint is not a slider"); + + // get axis1 in global coordinates + dVector3 ax1,q; + dMULTIPLY0_331 (ax1,joint->node[0].body->R,joint->axis1); + + if (joint->node[1].body) { + // get body2 + offset point in global coordinates + dMULTIPLY0_331 (q,joint->node[1].body->R,joint->offset); + for (int i=0; i<3; i++) q[i] = joint->node[0].body->pos[i] - q[i] - + joint->node[1].body->pos[i]; + } + else { + for (int i=0; i<3; i++) q[i] = joint->node[0].body->pos[i] - + joint->offset[i]; + + } + return dDOT(ax1,q); +} + + +extern "C" dReal dJointGetSliderPositionRate (dxJointSlider *joint) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__dslider_vtable,"joint is not a slider"); + + // get axis1 in global coordinates + dVector3 ax1; + dMULTIPLY0_331 (ax1,joint->node[0].body->R,joint->axis1); + + if (joint->node[1].body) { + return dDOT(ax1,joint->node[0].body->lvel) - + dDOT(ax1,joint->node[1].body->lvel); + } + else { + return dDOT(ax1,joint->node[0].body->lvel); + } +} + + +static void sliderGetInfo1 (dxJointSlider *j, dxJoint::Info1 *info) +{ + info->nub = 5; + + // see if joint is powered + if (j->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. + j->limot.limit = 0; + if ((j->limot.lostop > -dInfinity || j->limot.histop < dInfinity) && + j->limot.lostop <= j->limot.histop) { + // measure joint position + dReal pos = dJointGetSliderPosition (j); + if (pos <= j->limot.lostop) { + j->limot.limit = 1; + j->limot.limit_err = pos - j->limot.lostop; + info->m = 6; + } + else if (pos >= j->limot.histop) { + j->limot.limit = 2; + j->limot.limit_err = pos - j->limot.histop; + info->m = 6; + } + } +} + + +static void sliderGetInfo2 (dxJointSlider *joint, dxJoint::Info2 *info) +{ + int i,s = info->rowskip; + int s2=2*s,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 = joint->node[0].body->pos; + R1 = joint->node[0].body->R; + if (joint->node[1].body) { + pos2 = joint->node[1].body->pos; + R2 = joint->node[1].body->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(joint, info, joint->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,joint->axis1); + dPlaneSpace (ax1,p,q); + if (joint->node[1].body) { + dVector3 tmp; + dCROSS (tmp, = REAL(0.5) * ,c,p); + for (i=0; i<3; i++) info->J2a[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->J2a[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 (joint->node[1].body) { + dVector3 ofs; // offset point in global coordinates + dMULTIPLY0_331 (ofs,R2,joint->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] = joint->offset[i] - pos1[i]; + info->c[3] = k * dDOT(p,ofs); + info->c[4] = k * dDOT(q,ofs); + } + + // if the slider is powered, or has joint limits, add in the extra row + joint->limot.addLimot (joint,info,5,ax1,0); +} + + +extern "C" void dJointSetSliderAxis (dxJointSlider *joint, + dReal x, dReal y, dReal z) +{ + int i; + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__dslider_vtable,"joint is not a slider"); + setAxes (joint,x,y,z,joint->axis1,0); + + // compute initial relative rotation body1 -> body2, or env -> body1 + // also compute center of body1 w.r.t body 2 + if (joint->node[1].body) { + dQMultiply1 (joint->qrel,joint->node[0].body->q,joint->node[1].body->q); + dVector3 c; + for (i=0; i<3; i++) + c[i] = joint->node[0].body->pos[i] - joint->node[1].body->pos[i]; + dMULTIPLY1_331 (joint->offset,joint->node[1].body->R,c); + } + else { + // set joint->qrel to the transpose of the first body's q + joint->qrel[0] = joint->node[0].body->q[0]; + for (i=1; i<4; i++) joint->qrel[i] = -joint->node[0].body->q[i]; + for (i=0; i<3; i++) joint->offset[i] = joint->node[0].body->pos[i]; + } +} + + +extern "C" void dJointGetSliderAxis (dxJointSlider *joint, dVector3 result) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(result,"bad result argument"); + dUASSERT(joint->vtable == &__dslider_vtable,"joint is not a slider"); + getAxis (joint,result,joint->axis1); +} + + +extern "C" void dJointSetSliderParam (dxJointSlider *joint, + int parameter, dReal value) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__dslider_vtable,"joint is not a slider"); + joint->limot.set (parameter,value); +} + + +extern "C" dReal dJointGetSliderParam (dxJointSlider *joint, int parameter) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__dslider_vtable,"joint is not a slider"); + return joint->limot.get (parameter); +} + + +extern "C" void dJointAddSliderForce (dxJointSlider *joint, dReal force) +{ + dVector3 axis; + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__dslider_vtable,"joint is not a 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]); +} + + +dxJoint::Vtable __dslider_vtable = { + sizeof(dxJointSlider), + (dxJoint::init_fn*) sliderInit, + (dxJoint::getInfo1_fn*) sliderGetInfo1, + (dxJoint::getInfo2_fn*) sliderGetInfo2, + dJointTypeSlider}; + +//**************************************************************************** +// contact + +static void contactInit (dxJointContact *j) +{ + // default frictionless contact. hmmm, this info gets overwritten straight + // away anyway, so why bother? +#if 0 /* so don't bother ;) */ + j->contact.surface.mode = 0; + j->contact.surface.mu = 0; + dSetZero (j->contact.geom.pos,4); + dSetZero (j->contact.geom.normal,4); + j->contact.geom.depth = 0; +#endif +} + + +static void contactGetInfo1 (dxJointContact *j, 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 (j->contact.surface.mu < 0) j->contact.surface.mu = 0; + if (j->contact.surface.mode & dContactMu2) { + if (j->contact.surface.mu > 0) m++; + if (j->contact.surface.mu2 < 0) j->contact.surface.mu2 = 0; + if (j->contact.surface.mu2 > 0) m++; + if (j->contact.surface.mu == dInfinity) nub ++; + if (j->contact.surface.mu2 == dInfinity) nub ++; + } + else { + if (j->contact.surface.mu > 0) m += 2; + if (j->contact.surface.mu == dInfinity) nub += 2; + } + + j->the_m = m; + info->m = m; + info->nub = nub; +} + + +static void contactGetInfo2 (dxJointContact *j, dxJoint::Info2 *info) +{ + int i,s = info->rowskip; + int s2 = 2*s; + + // get normal, with sign adjusted for body1/body2 polarity + dVector3 normal; + if (j->flags & dJOINT_REVERSE) { + normal[0] = - j->contact.geom.normal[0]; + normal[1] = - j->contact.geom.normal[1]; + normal[2] = - j->contact.geom.normal[2]; + } + else { + normal[0] = j->contact.geom.normal[0]; + normal[1] = j->contact.geom.normal[1]; + normal[2] = j->contact.geom.normal[2]; + } + normal[3] = 0; // @@@ hmmm + + // c1,c2 = contact points with respect to body PORs + dVector3 c1,c2; + for (i=0; i<3; i++) c1[i] = j->contact.geom.pos[i] - j->node[0].body->pos[i]; + + // 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 (j->node[1].body) { + for (i=0; i<3; i++) c2[i] = j->contact.geom.pos[i] - + j->node[1].body->pos[i]; + 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 (j->contact.surface.mode & dContactSoftERP) + erp = j->contact.surface.soft_erp; + dReal k = info->fps * erp; + info->c[0] = k*j->contact.geom.depth; + if (j->contact.surface.mode & dContactSoftCFM) + info->cfm[0] = j->contact.surface.soft_cfm; + + // deal with bounce + if (j->contact.surface.mode & dContactBounce) { + // calculate outgoing velocity (-ve for incoming contact) + dReal outgoing = dDOT(info->J1l,j->node[0].body->lvel) + + dDOT(info->J1a,j->node[0].body->avel); + if (j->node[1].body) { + outgoing += dDOT(info->J2l,j->node[1].body->lvel) + + dDOT(info->J2a,j->node[1].body->avel); + } + // only apply bounce if the outgoing velocity is greater than the + // threshold, and if the resulting c[0] exceeds what we already have. + if (j->contact.surface.bounce_vel >= 0 && + (-outgoing) > j->contact.surface.bounce_vel) { + dReal newc = - j->contact.surface.bounce * outgoing; + 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 (j->the_m >= 2) { + if (j->contact.surface.mode & dContactFDir1) { // use fdir1 ? + t1[0] = j->contact.fdir1[0]; + t1[1] = j->contact.fdir1[1]; + t1[2] = j->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 (j->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 (j->contact.surface.mode & dContactMotion1) { + info->c[1] = j->contact.surface.motion1; + } + // set LCP bounds and friction index. this depends on the approximation + // mode + info->lo[1] = -j->contact.surface.mu; + info->hi[1] = j->contact.surface.mu; + if (j->contact.surface.mode & dContactApprox1_1) info->findex[1] = 0; + + // set slip (constraint force mixing) + if (j->contact.surface.mode & dContactSlip1) + info->cfm[1] = j->contact.surface.slip1; + } + + // second friction direction + if (j->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 (j->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 (j->contact.surface.mode & dContactMotion2) { + info->c[2] = j->contact.surface.motion2; + } + // set LCP bounds and friction index. this depends on the approximation + // mode + if (j->contact.surface.mode & dContactMu2) { + info->lo[2] = -j->contact.surface.mu2; + info->hi[2] = j->contact.surface.mu2; + } + else { + info->lo[2] = -j->contact.surface.mu; + info->hi[2] = j->contact.surface.mu; + } + if (j->contact.surface.mode & dContactApprox1_2) info->findex[2] = 0; + + // set slip (constraint force mixing) + if (j->contact.surface.mode & dContactSlip2) + info->cfm[2] = j->contact.surface.slip2; + } +} + + +dxJoint::Vtable __dcontact_vtable = { + sizeof(dxJointContact), + (dxJoint::init_fn*) contactInit, + (dxJoint::getInfo1_fn*) contactGetInfo1, + (dxJoint::getInfo2_fn*) contactGetInfo2, + dJointTypeContact}; + +//**************************************************************************** +// hinge 2. note that this joint must be attached to two bodies for it to work + +static dReal measureHinge2Angle (dxJointHinge2 *joint) +{ + dVector3 a1,a2; + dMULTIPLY0_331 (a1,joint->node[1].body->R,joint->axis2); + dMULTIPLY1_331 (a2,joint->node[0].body->R,a1); + dReal x = dDOT(joint->v1,a2); + dReal y = dDOT(joint->v2,a2); + return -dAtan2 (y,x); +} + + +static void hinge2Init (dxJointHinge2 *j) +{ + dSetZero (j->anchor1,4); + dSetZero (j->anchor2,4); + dSetZero (j->axis1,4); + j->axis1[0] = 1; + dSetZero (j->axis2,4); + j->axis2[1] = 1; + j->c0 = 0; + j->s0 = 0; + + dSetZero (j->v1,4); + j->v1[0] = 1; + dSetZero (j->v2,4); + j->v2[1] = 1; + + j->limot1.init (j->world); + j->limot2.init (j->world); + + j->susp_erp = j->world->global_erp; + j->susp_cfm = j->world->global_cfm; + + j->flags |= dJOINT_TWOBODIES; +} + + +static void hinge2GetInfo1 (dxJointHinge2 *j, dxJoint::Info1 *info) +{ + info->m = 4; + info->nub = 4; + + // see if we're powered or at a joint limit for axis 1 + int atlimit=0; + if ((j->limot1.lostop >= -M_PI || j->limot1.histop <= M_PI) && + j->limot1.lostop <= j->limot1.histop) { + dReal angle = measureHinge2Angle (j); + if (j->limot1.testRotationalLimit (angle)) atlimit = 1; + } + if (atlimit || j->limot1.fmax > 0) info->m++; + + // see if we're powering axis 2 (we currently never limit this axis) + j->limot2.limit = 0; + if (j->limot2.fmax > 0) info->m++; +} + + +// macro 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. + +#define HINGE2_GET_AXIS_INFO(axis,sin_angle,cos_angle) \ + dVector3 ax1,ax2; \ + dMULTIPLY0_331 (ax1,joint->node[0].body->R,joint->axis1); \ + dMULTIPLY0_331 (ax2,joint->node[1].body->R,joint->axis2); \ + dCROSS (axis,=,ax1,ax2); \ + sin_angle = dSqrt (axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]); \ + cos_angle = dDOT (ax1,ax2); + + +static void hinge2GetInfo2 (dxJointHinge2 *joint, dxJoint::Info2 *info) +{ + // get information we need to set the hinge row + dReal s,c; + dVector3 q; + HINGE2_GET_AXIS_INFO (q,s,c); + dNormalize3 (q); // @@@ quicker: divide q by s ? + + // set the three ball-and-socket rows (aligned to the suspension axis ax1) + setBall2 (joint,info,joint->anchor1,joint->anchor2,ax1,joint->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 * (joint->c0 * s - joint->s0 * c); + + // if the axis1 hinge is powered, or has joint limits, add in more stuff + int row = 4 + joint->limot1.addLimot (joint,info,4,ax1,1); + + // if the axis2 hinge is powered, add in more stuff + joint->limot2.addLimot (joint,info,row,ax2,1); + + // set parameter for the suspension + info->cfm[0] = joint->susp_cfm; +} + + +// compute vectors v1 and v2 (embedded in body1), used to measure angle +// between body 1 and body 2 + +static void makeHinge2V1andV2 (dxJointHinge2 *joint) +{ + if (joint->node[0].body) { + // get axis 1 and 2 in global coords + dVector3 ax1,ax2,v; + dMULTIPLY0_331 (ax1,joint->node[0].body->R,joint->axis1); + dMULTIPLY0_331 (ax2,joint->node[1].body->R,joint->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 (joint->v1,joint->node[0].body->R,ax2); + dMULTIPLY1_331 (joint->v2,joint->node[0].body->R,v); + } +} + + +extern "C" void dJointSetHinge2Anchor (dxJointHinge2 *joint, + dReal x, dReal y, dReal z) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2"); + setAnchors (joint,x,y,z,joint->anchor1,joint->anchor2); + makeHinge2V1andV2 (joint); +} + + +extern "C" void dJointSetHinge2Axis1 (dxJointHinge2 *joint, + dReal x, dReal y, dReal z) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2"); + if (joint->node[0].body) { + dReal q[4]; + q[0] = x; + q[1] = y; + q[2] = z; + q[3] = 0; + dNormalize3 (q); + dMULTIPLY1_331 (joint->axis1,joint->node[0].body->R,q); + joint->axis1[3] = 0; + + // compute the sin and cos of the angle between axis 1 and axis 2 + dVector3 ax; + HINGE2_GET_AXIS_INFO(ax,joint->s0,joint->c0); + } + makeHinge2V1andV2 (joint); +} + + +extern "C" void dJointSetHinge2Axis2 (dxJointHinge2 *joint, + dReal x, dReal y, dReal z) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2"); + if (joint->node[1].body) { + dReal q[4]; + q[0] = x; + q[1] = y; + q[2] = z; + q[3] = 0; + dNormalize3 (q); + dMULTIPLY1_331 (joint->axis2,joint->node[1].body->R,q); + joint->axis1[3] = 0; + + // compute the sin and cos of the angle between axis 1 and axis 2 + dVector3 ax; + HINGE2_GET_AXIS_INFO(ax,joint->s0,joint->c0); + } + makeHinge2V1andV2 (joint); +} + + +extern "C" void dJointSetHinge2Param (dxJointHinge2 *joint, + int parameter, dReal value) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a 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); + } +} + + +extern "C" void dJointGetHinge2Anchor (dxJointHinge2 *joint, dVector3 result) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(result,"bad result argument"); + dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2"); + if (joint->flags & dJOINT_REVERSE) + getAnchor2 (joint,result,joint->anchor2); + else + getAnchor (joint,result,joint->anchor1); +} + + +extern "C" void dJointGetHinge2Anchor2 (dxJointHinge2 *joint, dVector3 result) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(result,"bad result argument"); + dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2"); + if (joint->flags & dJOINT_REVERSE) + getAnchor (joint,result,joint->anchor1); + else + getAnchor2 (joint,result,joint->anchor2); +} + + +extern "C" void dJointGetHinge2Axis1 (dxJointHinge2 *joint, dVector3 result) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(result,"bad result argument"); + dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2"); + if (joint->node[0].body) { + dMULTIPLY0_331 (result,joint->node[0].body->R,joint->axis1); + } +} + + +extern "C" void dJointGetHinge2Axis2 (dxJointHinge2 *joint, dVector3 result) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(result,"bad result argument"); + dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2"); + if (joint->node[1].body) { + dMULTIPLY0_331 (result,joint->node[1].body->R,joint->axis2); + } +} + + +extern "C" dReal dJointGetHinge2Param (dxJointHinge2 *joint, int parameter) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a 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); + } +} + + +extern "C" dReal dJointGetHinge2Angle1 (dxJointHinge2 *joint) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2"); + if (joint->node[0].body) return measureHinge2Angle (joint); + else return 0; +} + + +extern "C" dReal dJointGetHinge2Angle1Rate (dxJointHinge2 *joint) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2"); + if (joint->node[0].body) { + dVector3 axis; + dMULTIPLY0_331 (axis,joint->node[0].body->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; +} + + +extern "C" dReal dJointGetHinge2Angle2Rate (dxJointHinge2 *joint) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2"); + if (joint->node[0].body && joint->node[1].body) { + dVector3 axis; + dMULTIPLY0_331 (axis,joint->node[1].body->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; +} + + +extern "C" void dJointAddHinge2Torques (dxJointHinge2 *joint, dReal torque1, dReal torque2) +{ + dVector3 axis1, axis2; + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2"); + + if (joint->node[0].body && joint->node[1].body) { + dMULTIPLY0_331 (axis1,joint->node[0].body->R,joint->axis1); + dMULTIPLY0_331 (axis2,joint->node[1].body->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]); + } +} + + +dxJoint::Vtable __dhinge2_vtable = { + sizeof(dxJointHinge2), + (dxJoint::init_fn*) hinge2Init, + (dxJoint::getInfo1_fn*) hinge2GetInfo1, + (dxJoint::getInfo2_fn*) hinge2GetInfo2, + dJointTypeHinge2}; + +//**************************************************************************** +// 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). + +static void universalInit (dxJointUniversal *j) +{ + dSetZero (j->anchor1,4); + dSetZero (j->anchor2,4); + dSetZero (j->axis1,4); + j->axis1[0] = 1; + dSetZero (j->axis2,4); + j->axis2[1] = 1; + dSetZero(j->qrel1,4); + dSetZero(j->qrel2,4); + j->limot1.init (j->world); + j->limot2.init (j->world); +} + + +static void getUniversalAxes(dxJointUniversal *joint, dVector3 ax1, dVector3 ax2) +{ + // This says "ax1 = joint->node[0].body->R * joint->axis1" + dMULTIPLY0_331 (ax1,joint->node[0].body->R,joint->axis1); + + if (joint->node[1].body) { + dMULTIPLY0_331 (ax2,joint->node[1].body->R,joint->axis2); + } + else { + ax2[0] = joint->axis2[0]; + ax2[1] = joint->axis2[1]; + ax2[2] = joint->axis2[2]; + } +} + + +static dReal getUniversalAngle1(dxJointUniversal *joint) +{ + if (joint->node[0].body) { + // length 1 joint axis in global coordinates, from each body + dVector3 ax1, ax2; + dMatrix3 R; + dQuaternion qcross, qq, qrel; + + getUniversalAxes (joint,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,joint->node[0].body->q,qcross); + dQMultiply2 (qrel,qq,joint->qrel1); + + return getHingeAngleFromRelativeQuat(qrel, joint->axis1); + } + return 0; +} + + +static dReal getUniversalAngle2(dxJointUniversal *joint) +{ + if (joint->node[0].body) { + // length 1 joint axis in global coordinates, from each body + dVector3 ax1, ax2; + dMatrix3 R; + dQuaternion qcross, qq, qrel; + + getUniversalAxes (joint,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 (joint->node[1].body) { + dQMultiply1 (qq, joint->node[1].body->q, qcross); + dQMultiply2 (qrel,qq,joint->qrel2); + } + else { + // pretend joint->node[1].body->q is the identity + dQMultiply2 (qrel,qcross, joint->qrel2); + } + + return - getHingeAngleFromRelativeQuat(qrel, joint->axis2); + } + return 0; +} + + +static void universalGetInfo1 (dxJointUniversal *j, dxJoint::Info1 *info) +{ + info->nub = 4; + info->m = 4; + + // see if we're powered or at a joint limit. + bool constraint1 = j->limot1.fmax > 0; + bool constraint2 = j->limot2.fmax > 0; + + bool limiting1 = (j->limot1.lostop >= -M_PI || j->limot1.histop <= M_PI) && + j->limot1.lostop <= j->limot1.histop; + bool limiting2 = (j->limot2.lostop >= -M_PI || j->limot2.histop <= M_PI) && + j->limot2.lostop <= j->limot2.histop; + + // We need to call testRotationLimit() even if we're motored, since it + // records the result. + if (limiting1 || limiting2) { + dReal angle1, angle2; + angle1 = getUniversalAngle1(j); + angle2 = getUniversalAngle2(j); + if (limiting1 && j->limot1.testRotationalLimit (angle1)) constraint1 = true; + if (limiting2 && j->limot2.testRotationalLimit (angle2)) constraint2 = true; + } + if (constraint1) + info->m++; + if (constraint2) + info->m++; +} + + +static void universalGetInfo2 (dxJointUniversal *joint, dxJoint::Info2 *info) +{ + // set the three ball-and-socket rows + setBall (joint,info,joint->anchor1,joint->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; + + getUniversalAxes(joint, 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 (joint->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 * - dDOT(ax1, ax2); + + // if the first angle is powered, or has joint limits, add in the stuff + int row = 4 + joint->limot1.addLimot (joint,info,4,ax1,1); + + // if the second angle is powered, or has joint limits, add in more stuff + joint->limot2.addLimot (joint,info,row,ax2,1); +} + + +static void universalComputeInitialRelativeRotations (dxJointUniversal *joint) +{ + if (joint->node[0].body) { + dVector3 ax1, ax2; + dMatrix3 R; + dQuaternion qcross; + + getUniversalAxes(joint, ax1, ax2); + + // Axis 1. + dRFrom2Axes(R, ax1[0], ax1[1], ax1[2], ax2[0], ax2[1], ax2[2]); + dRtoQ(R, qcross); + dQMultiply1 (joint->qrel1, joint->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 (joint->node[1].body) { + dQMultiply1 (joint->qrel2, joint->node[1].body->q, qcross); + } + else { + // set joint->qrel to qcross + for (int i=0; i<4; i++) joint->qrel2[i] = qcross[i]; + } + } +} + + +extern "C" void dJointSetUniversalAnchor (dxJointUniversal *joint, + dReal x, dReal y, dReal z) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); + setAnchors (joint,x,y,z,joint->anchor1,joint->anchor2); + universalComputeInitialRelativeRotations(joint); +} + + +extern "C" void dJointSetUniversalAxis1 (dxJointUniversal *joint, + dReal x, dReal y, dReal z) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); + if (joint->flags & dJOINT_REVERSE) + setAxes (joint,x,y,z,NULL,joint->axis2); + else + setAxes (joint,x,y,z,joint->axis1,NULL); + universalComputeInitialRelativeRotations(joint); +} + + +extern "C" void dJointSetUniversalAxis2 (dxJointUniversal *joint, + dReal x, dReal y, dReal z) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); + if (joint->flags & dJOINT_REVERSE) + setAxes (joint,x,y,z,joint->axis1,NULL); + else + setAxes (joint,x,y,z,NULL,joint->axis2); + universalComputeInitialRelativeRotations(joint); +} + + +extern "C" void dJointGetUniversalAnchor (dxJointUniversal *joint, + dVector3 result) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(result,"bad result argument"); + dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); + if (joint->flags & dJOINT_REVERSE) + getAnchor2 (joint,result,joint->anchor2); + else + getAnchor (joint,result,joint->anchor1); +} + + +extern "C" void dJointGetUniversalAnchor2 (dxJointUniversal *joint, + dVector3 result) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(result,"bad result argument"); + dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); + if (joint->flags & dJOINT_REVERSE) + getAnchor (joint,result,joint->anchor1); + else + getAnchor2 (joint,result,joint->anchor2); +} + + +extern "C" void dJointGetUniversalAxis1 (dxJointUniversal *joint, + dVector3 result) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(result,"bad result argument"); + dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); + if (joint->flags & dJOINT_REVERSE) + getAxis2 (joint,result,joint->axis2); + else + getAxis (joint,result,joint->axis1); +} + + +extern "C" void dJointGetUniversalAxis2 (dxJointUniversal *joint, + dVector3 result) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(result,"bad result argument"); + dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); + if (joint->flags & dJOINT_REVERSE) + getAxis (joint,result,joint->axis1); + else + getAxis2 (joint,result,joint->axis2); +} + + +extern "C" void dJointSetUniversalParam (dxJointUniversal *joint, + int parameter, dReal value) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); + if ((parameter & 0xff00) == 0x100) { + joint->limot2.set (parameter & 0xff,value); + } + else { + joint->limot1.set (parameter,value); + } +} + + +extern "C" dReal dJointGetUniversalParam (dxJointUniversal *joint, int parameter) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); + if ((parameter & 0xff00) == 0x100) { + return joint->limot2.get (parameter & 0xff); + } + else { + return joint->limot1.get (parameter); + } +} + + +extern "C" dReal dJointGetUniversalAngle1 (dxJointUniversal *joint) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); + if (joint->flags & dJOINT_REVERSE) + return getUniversalAngle2 (joint); + else + return getUniversalAngle1 (joint); +} + + +extern "C" dReal dJointGetUniversalAngle2 (dxJointUniversal *joint) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal"); + if (joint->flags & dJOINT_REVERSE) + return getUniversalAngle1 (joint); + else + return getUniversalAngle2 (joint); +} + + +extern "C" dReal dJointGetUniversalAngle1Rate (dxJointUniversal *joint) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a 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; +} + + +extern "C" dReal dJointGetUniversalAngle2Rate (dxJointUniversal *joint) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a 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; +} + + +extern "C" void dJointAddUniversalTorques (dxJointUniversal *joint, dReal torque1, dReal torque2) +{ + dVector3 axis1, axis2; + dAASSERT(joint); + dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a 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]); +} + + + + + +dxJoint::Vtable __duniversal_vtable = { + sizeof(dxJointUniversal), + (dxJoint::init_fn*) universalInit, + (dxJoint::getInfo1_fn*) universalGetInfo1, + (dxJoint::getInfo2_fn*) universalGetInfo2, + dJointTypeUniversal}; + +//**************************************************************************** +// angular motor + +static void amotorInit (dxJointAMotor *j) +{ + int i; + j->num = 0; + j->mode = dAMotorUser; + for (i=0; i<3; i++) { + j->rel[i] = 0; + dSetZero (j->axis[i],4); + j->limot[i].init (j->world); + j->angle[i] = 0; + } + dSetZero (j->reference1,4); + dSetZero (j->reference2,4); + + j->flags |= dJOINT_TWOBODIES; +} + + +// compute the 3 axes in global coordinates + +static void amotorComputeGlobalAxes (dxJointAMotor *joint, dVector3 ax[3]) +{ + if (joint->mode == dAMotorEuler) { + // special handling for euler mode + dMULTIPLY0_331 (ax[0],joint->node[0].body->R,joint->axis[0]); + dMULTIPLY0_331 (ax[2],joint->node[1].body->R,joint->axis[2]); + dCROSS (ax[1],=,ax[2],ax[0]); + dNormalize3 (ax[1]); + } + else { + for (int i=0; i < joint->num; i++) { + if (joint->rel[i] == 1) { + // relative to b1 + dMULTIPLY0_331 (ax[i],joint->node[0].body->R,joint->axis[i]); + } + if (joint->rel[i] == 2) { + // relative to b2 + dMULTIPLY0_331 (ax[i],joint->node[1].body->R,joint->axis[i]); + } + else { + // global - just copy it + ax[i][0] = joint->axis[i][0]; + ax[i][1] = joint->axis[i][1]; + ax[i][2] = joint->axis[i][2]; + } + } + } +} + + +static void amotorComputeEulerAngles (dxJointAMotor *joint, 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,joint->node[0].body->R,joint->reference1); + dMULTIPLY0_331 (ref2,joint->node[1].body->R,joint->reference2); + + // get q perpendicular to both ax[0] and ref1, get first euler angle + dVector3 q; + dCROSS (q,=,ax[0],ref1); + joint->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]); + joint->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]); + joint->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 + +static void amotorSetEulerReferenceVectors (dxJointAMotor *j) +{ + if (j->node[0].body && j->node[1].body) { + dVector3 r; // axis[2] and axis[0] in global coordinates + dMULTIPLY0_331 (r,j->node[1].body->R,j->axis[2]); + dMULTIPLY1_331 (j->reference1,j->node[0].body->R,r); + dMULTIPLY0_331 (r,j->node[0].body->R,j->axis[0]); + dMULTIPLY1_331 (j->reference2,j->node[1].body->R,r); + } +} + + +static void amotorGetInfo1 (dxJointAMotor *j, dxJoint::Info1 *info) +{ + info->m = 0; + info->nub = 0; + + // compute the axes and angles, if in euler mode + if (j->mode == dAMotorEuler) { + dVector3 ax[3]; + amotorComputeGlobalAxes (j,ax); + amotorComputeEulerAngles (j,ax); + } + + // see if we're powered or at a joint limit for each axis + for (int i=0; i < j->num; i++) { + if (j->limot[i].testRotationalLimit (j->angle[i]) || + j->limot[i].fmax > 0) { + info->m++; + } + } +} + + +static void amotorGetInfo2 (dxJointAMotor *joint, dxJoint::Info2 *info) +{ + int i; + + // compute the axes (if not global) + dVector3 ax[3]; + amotorComputeGlobalAxes (joint,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 (joint->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 < joint->num; i++) { + row += joint->limot[i].addLimot (joint,info,row,*(axptr[i]),1); + } +} + + +extern "C" void dJointSetAMotorNumAxes (dxJointAMotor *joint, int num) +{ + dAASSERT(joint && num >= 0 && num <= 3); + dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor"); + if (joint->mode == dAMotorEuler) { + joint->num = 3; + } + else { + if (num < 0) num = 0; + if (num > 3) num = 3; + joint->num = num; + } +} + + +extern "C" void dJointSetAMotorAxis (dxJointAMotor *joint, int anum, int rel, + dReal x, dReal y, dReal z) +{ + dAASSERT(joint && anum >= 0 && anum <= 2 && rel >= 0 && rel <= 2); + dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor"); + if (anum < 0) anum = 0; + if (anum > 2) anum = 2; + 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->R,r); + } + else { + dMULTIPLY1_331 (joint->axis[anum],joint->node[1].body->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]); + if (joint->mode == dAMotorEuler) amotorSetEulerReferenceVectors (joint); +} + + +extern "C" void dJointSetAMotorAngle (dxJointAMotor *joint, int anum, + dReal angle) +{ + dAASSERT(joint && anum >= 0 && anum < 3); + dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor"); + if (joint->mode == dAMotorUser) { + if (anum < 0) anum = 0; + if (anum > 3) anum = 3; + joint->angle[anum] = angle; + } +} + + +extern "C" void dJointSetAMotorParam (dxJointAMotor *joint, int parameter, + dReal value) +{ + dAASSERT(joint); + dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor"); + int anum = parameter >> 8; + if (anum < 0) anum = 0; + if (anum > 2) anum = 2; + parameter &= 0xff; + joint->limot[anum].set (parameter, value); +} + + +extern "C" void dJointSetAMotorMode (dxJointAMotor *joint, int mode) +{ + dAASSERT(joint); + dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor"); + joint->mode = mode; + if (joint->mode == dAMotorEuler) { + joint->num = 3; + amotorSetEulerReferenceVectors (joint); + } +} + + +extern "C" int dJointGetAMotorNumAxes (dxJointAMotor *joint) +{ + dAASSERT(joint); + dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor"); + return joint->num; +} + + +extern "C" void dJointGetAMotorAxis (dxJointAMotor *joint, int anum, + dVector3 result) +{ + dAASSERT(joint && anum >= 0 && anum < 3); + dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an 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->R,joint->axis[anum]); + } + else { + dMULTIPLY0_331 (result,joint->node[1].body->R,joint->axis[anum]); + } + } + else { + result[0] = joint->axis[anum][0]; + result[1] = joint->axis[anum][1]; + result[2] = joint->axis[anum][2]; + } +} + + +extern "C" int dJointGetAMotorAxisRel (dxJointAMotor *joint, int anum) +{ + dAASSERT(joint && anum >= 0 && anum < 3); + dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor"); + if (anum < 0) anum = 0; + if (anum > 2) anum = 2; + return joint->rel[anum]; +} + + +extern "C" dReal dJointGetAMotorAngle (dxJointAMotor *joint, int anum) +{ + dAASSERT(joint && anum >= 0 && anum < 3); + dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor"); + if (anum < 0) anum = 0; + if (anum > 3) anum = 3; + return joint->angle[anum]; +} + + +extern "C" dReal dJointGetAMotorAngleRate (dxJointAMotor *joint, int anum) +{ + // @@@ + dDebug (0,"not yet implemented"); + return 0; +} + + +extern "C" dReal dJointGetAMotorParam (dxJointAMotor *joint, int parameter) +{ + dAASSERT(joint); + dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor"); + int anum = parameter >> 8; + if (anum < 0) anum = 0; + if (anum > 2) anum = 2; + parameter &= 0xff; + return joint->limot[anum].get (parameter); +} + + +extern "C" int dJointGetAMotorMode (dxJointAMotor *joint) +{ + dAASSERT(joint); + dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor"); + return joint->mode; +} + + +extern "C" void dJointAddAMotorTorques (dxJointAMotor *joint, dReal torque1, dReal torque2, dReal torque3) +{ + dVector3 axes[3]; + dAASSERT(joint); + dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor"); + + if (joint->num == 0) + return; + dUASSERT((joint->flags & dJOINT_REVERSE) == 0, "dJointAddAMotorTorques not yet implemented for reverse AMotor joints"); + + amotorComputeGlobalAxes (joint,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][0] * torque2; + axes[0][2] += axes[1][0] * torque2; + if (joint->num >= 3) { + axes[0][0] += axes[2][0] * torque3; + axes[0][1] += axes[2][0] * torque3; + axes[0][2] += axes[2][0] * 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]); +} + + +dxJoint::Vtable __damotor_vtable = { + sizeof(dxJointAMotor), + (dxJoint::init_fn*) amotorInit, + (dxJoint::getInfo1_fn*) amotorGetInfo1, + (dxJoint::getInfo2_fn*) amotorGetInfo2, + dJointTypeAMotor}; + +//**************************************************************************** +// fixed joint + +static void fixedInit (dxJointFixed *j) +{ + dSetZero (j->offset,4); + dSetZero (j->qrel,4); +} + + +static void fixedGetInfo1 (dxJointFixed *j, dxJoint::Info1 *info) +{ + info->m = 6; + info->nub = 6; +} + + +static void fixedGetInfo2 (dxJointFixed *joint, dxJoint::Info2 *info) +{ + int s = info->rowskip; + + // Three rows for orientation + setFixedOrientation(joint, info, joint->qrel, 3); + + // Three rows for position. + // set jacobian + info->J1l[0] = 1; + info->J1l[s+1] = 1; + info->J1l[2*s+2] = 1; + + dVector3 ofs; + dMULTIPLY0_331 (ofs,joint->node[0].body->R,joint->offset); + if (joint->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 (joint->node[1].body) { + for (int j=0; j<3; j++) + info->c[j] = k * (joint->node[1].body->pos[j] - + joint->node[0].body->pos[j] + ofs[j]); + } + else { + for (int j=0; j<3; j++) + info->c[j] = k * (joint->offset[j] - joint->node[0].body->pos[j]); + } +} + + +extern "C" void dJointSetFixed (dxJointFixed *joint) +{ + dUASSERT(joint,"bad joint argument"); + dUASSERT(joint->vtable == &__dfixed_vtable,"joint is not fixed"); + int i; + + // This code is taken from sJointSetSliderAxis(), 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) { + dQMultiply1 (joint->qrel,joint->node[0].body->q,joint->node[1].body->q); + dReal ofs[4]; + for (i=0; i<4; i++) ofs[i] = joint->node[0].body->pos[i]; + for (i=0; i<4; i++) ofs[i] -= joint->node[1].body->pos[i]; + dMULTIPLY1_331 (joint->offset,joint->node[0].body->R,ofs); + } + else { + // set joint->qrel to the transpose of the first body's q + joint->qrel[0] = joint->node[0].body->q[0]; + for (i=1; i<4; i++) joint->qrel[i] = -joint->node[0].body->q[i]; + for (i=0; i<4; i++) joint->offset[i] = joint->node[0].body->pos[i]; + } + } +} + + +dxJoint::Vtable __dfixed_vtable = { + sizeof(dxJointFixed), + (dxJoint::init_fn*) fixedInit, + (dxJoint::getInfo1_fn*) fixedGetInfo1, + (dxJoint::getInfo2_fn*) fixedGetInfo2, + dJointTypeFixed}; + +//**************************************************************************** +// null joint + +static void nullGetInfo1 (dxJointNull *j, dxJoint::Info1 *info) +{ + info->m = 0; + info->nub = 0; +} + + +static void nullGetInfo2 (dxJointNull *joint, dxJoint::Info2 *info) +{ + dDebug (0,"this should never get called"); +} + + +dxJoint::Vtable __dnull_vtable = { + sizeof(dxJointNull), + (dxJoint::init_fn*) 0, + (dxJoint::getInfo1_fn*) nullGetInfo1, + (dxJoint::getInfo2_fn*) nullGetInfo2, + dJointTypeNull}; + +/******************** breakable joint contribution ***********************/ +extern "C" void dJointSetBreakable (dxJoint *joint, int b) { + dAASSERT(joint); + if (b) { + // we want this joint to be breakable but we must first check if it + // was already breakable + if (!joint->breakInfo) { + // allocate a dxJointBreakInfo struct + joint->breakInfo = new dxJointBreakInfo; + joint->breakInfo->flags = 0; + for (int i = 0; i < 3; i++) { + joint->breakInfo->b1MaxF[0] = 0; + joint->breakInfo->b1MaxT[0] = 0; + joint->breakInfo->b2MaxF[0] = 0; + joint->breakInfo->b2MaxT[0] = 0; + } + joint->breakInfo->callback = 0; + } + else { + // the joint was already breakable + return; + } + } + else { + // we want this joint to be unbreakable mut we must first check if + // it is alreay unbreakable + if (joint->breakInfo) { + // deallocate the dxJointBreakInfo struct + delete joint->breakInfo; + joint->breakInfo = 0; + } + else { + // the joint was already unbreakable + return; + } + } +} + +extern "C" void dJointSetBreakCallback (dxJoint *joint, dJointBreakCallback *callbackFunc) { + dAASSERT(joint); +# ifndef dNODEBUG + // only works for a breakable joint + if (!joint->breakInfo) { + dDebug (0, "dJointSetBreakCallback called on unbreakable joint"); + } +# endif + joint->breakInfo->callback = callbackFunc; +} + +extern "C" void dJointSetBreakMode (dxJoint *joint, int mode) { + dAASSERT(joint); +# ifndef dNODEBUG + // only works for a breakable joint + if (!joint->breakInfo) { + dDebug (0, "dJointSetBreakMode called on unbreakable joint"); + } +# endif + joint->breakInfo->flags = mode; +} + +extern "C" int dJointGetBreakMode (dxJoint *joint) { + dAASSERT(joint); +# ifndef dNODEBUG + // only works for a breakable joint + if (!joint->breakInfo) { + dDebug (0, "dJointGetBreakMode called on unbreakable joint"); + } +# endif + return joint->breakInfo->flags; +} + +extern "C" void dJointSetBreakForce (dxJoint *joint, int body, dReal x, dReal y, dReal z) { + dAASSERT(joint); +# ifndef dNODEBUG + // only works for a breakable joint + if (!joint->breakInfo) { + dDebug (0, "dJointSetBreakForce called on unbreakable joint"); + } +# endif + if (body) { + joint->breakInfo->b2MaxF[0] = x; + joint->breakInfo->b2MaxF[1] = y; + joint->breakInfo->b2MaxF[2] = z; + } + else { + joint->breakInfo->b1MaxF[0] = x; + joint->breakInfo->b1MaxF[1] = y; + joint->breakInfo->b1MaxF[2] = z; + } +} + +extern "C" void dJointSetBreakTorque (dxJoint *joint, int body, dReal x, dReal y, dReal z) { + dAASSERT(joint); +# ifndef dNODEBUG + // only works for a breakable joint + if (!joint->breakInfo) { + dDebug (0, "dJointSetBreakTorque called on unbreakable joint"); + } +# endif + if (body) { + joint->breakInfo->b2MaxT[0] = x; + joint->breakInfo->b2MaxT[1] = y; + joint->breakInfo->b2MaxT[2] = z; + } + else { + joint->breakInfo->b1MaxT[0] = x; + joint->breakInfo->b1MaxT[1] = y; + joint->breakInfo->b1MaxT[2] = z; + } +} + +extern "C" int dJointIsBreakable (dxJoint *joint) { + dAASSERT(joint); + return joint->breakInfo != 0; +} + +extern "C" void dJointGetBreakForce (dxJoint *joint, int body, dReal *force) { + dAASSERT(joint); +# ifndef dNODEBUG + // only works for a breakable joint + if (!joint->breakInfo) { + dDebug (0, "dJointGetBreakForce called on unbreakable joint"); + } +# endif + if (body) + for (int i=0; i<3; i++) force[i]=joint->breakInfo->b2MaxF[i]; + else + for (int i=0; i<3; i++) force[i]=joint->breakInfo->b1MaxF[i]; +} + +extern "C" void dJointGetBreakTorque (dxJoint *joint, int body, dReal *torque) { + dAASSERT(joint); +# ifndef dNODEBUG + // only works for a breakable joint + if (!joint->breakInfo) { + dDebug (0, "dJointGetBreakTorque called on unbreakable joint"); + } +# endif + if (body) + for (int i=0; i<3; i++) torque[i]=joint->breakInfo->b2MaxT[i]; + else + for (int i=0; i<3; i++) torque[i]=joint->breakInfo->b1MaxT[i]; +} +/*************************************************************************/ diff --git a/libraries/ode-0.9/contrib/BreakableJoints/joint.h b/libraries/ode-0.9/contrib/BreakableJoints/joint.h new file mode 100644 index 0000000000..0573119456 --- /dev/null +++ b/libraries/ode-0.9/contrib/BreakableJoints/joint.h @@ -0,0 +1,282 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without 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 +}; + + +// 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 +}; + +/******************** breakable joint contribution ***********************/ +struct dxJointBreakInfo : public dBase { + int flags; + dReal b1MaxF[3]; // maximum force on body 1 + dReal b1MaxT[3]; // maximum torque on body 1 + dReal b2MaxF[3]; // maximum force on body 2 + dReal b2MaxT[3]; // maximum torque on body 2 + dJointBreakCallback *callback; // function that is called when this joint breaks +}; +/*************************************************************************/ + +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; + }; + + // virtual function table: size of the joint structure, function pointers. + // we do it this way instead of using C++ virtual functions because + // sometimes we need to allocate joints ourself within a memory pool. + + typedef void init_fn (dxJoint *joint); + typedef void getInfo1_fn (dxJoint *joint, Info1 *info); + typedef void getInfo2_fn (dxJoint *joint, Info2 *info); + struct Vtable { + int size; + init_fn *init; + getInfo1_fn *getInfo1; + getInfo2_fn *getInfo2; + int typenum; // a dJointTypeXXX type number + }; + + Vtable *vtable; // virtual function table + int flags; // dJOINT_xxx flags + dxJointNode node[2]; // connections to bodies. node[1].body can be 0 + dJointFeedback *feedback; // optional feedback structure + + /******************** breakable joint contribution ***********************/ + // optional break info structure. if this is not NULL the the joint is + // breakable. + dxJointBreakInfo *breakInfo; + /*************************************************************************/ +}; + + +// 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, + dVector3 ax1, int rotational); +}; + + +// ball and socket + +struct dxJointBall : public dxJoint { + dVector3 anchor1; // anchor w.r.t first body + dVector3 anchor2; // anchor w.r.t second body +}; +extern struct dxJoint::Vtable __dball_vtable; + + +// 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 +}; +extern struct dxJoint::Vtable __dhinge_vtable; + + +// 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 +}; +extern struct dxJoint::Vtable __duniversal_vtable; + + +// 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 +}; +extern struct dxJoint::Vtable __dslider_vtable; + + +// contact + +struct dxJointContact : public dxJoint { + int the_m; // number of rows computed by getInfo1 + dContact contact; +}; +extern struct dxJoint::Vtable __dcontact_vtable; + + +// 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) +}; +extern struct dxJoint::Vtable __dhinge2_vtable; + + +// 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 +}; +extern struct dxJoint::Vtable __damotor_vtable; + + +// fixed + +struct dxJointFixed : public dxJoint { + dQuaternion qrel; // initial relative rotation body1 -> body2 + dVector3 offset; // relative offset between the bodies +}; +extern struct dxJoint::Vtable __dfixed_vtable; + + +// null joint, for testing only + +struct dxJointNull : public dxJoint { +}; +extern struct dxJoint::Vtable __dnull_vtable; + + + +#endif diff --git a/libraries/ode-0.9/contrib/BreakableJoints/objects.h b/libraries/ode-0.9/contrib/BreakableJoints/objects.h new file mode 100644 index 0000000000..de08391ede --- /dev/null +++ b/libraries/ode-0.9/contrib/BreakableJoints/objects.h @@ -0,0 +1,252 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without 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 + +/* world */ + +dWorldID dWorldCreate(); +void dWorldDestroy (dWorldID); + +void dWorldSetGravity (dWorldID, dReal x, dReal y, dReal z); +void dWorldGetGravity (dWorldID, dVector3 gravity); +void dWorldSetERP (dWorldID, dReal erp); +dReal dWorldGetERP (dWorldID); +void dWorldSetCFM (dWorldID, dReal cfm); +dReal dWorldGetCFM (dWorldID); +void dWorldStep (dWorldID, dReal stepsize); +void dWorldImpulseToForce (dWorldID, dReal stepsize, + dReal ix, dReal iy, dReal iz, dVector3 force); + +/* StepFast1 functions */ + +void dWorldStepFast1(dWorldID, dReal stepsize, int maxiterations); +void dWorldSetAutoEnableDepthSF1(dWorldID, int autoEnableDepth); + +int dWorldGetAutoEnableDepthSF1(dWorldID); + +void dBodySetAutoDisableThresholdSF1(dBodyID, dReal autoDisableThreshold); + +/* These functions are not yet implemented by ODE. */ +/* +dReal dBodyGetAutoDisableThresholdSF1(dBodyID); + +void dBodySetAutoDisableStepsSF1(dBodyID, int AutoDisableSteps); + +int dBodyGetAutoDisableStepsSF1(dBodyID); + +void dBodySetAutoDisableSF1(dBodyID, int doAutoDisable); + +int dBodyGetAutoDisableSF1(dBodyID); +*/ + +/* bodies */ + +dBodyID dBodyCreate (dWorldID); +void dBodyDestroy (dBodyID); + +void dBodySetData (dBodyID, void *data); +void *dBodyGetData (dBodyID); + +void dBodySetPosition (dBodyID, dReal x, dReal y, dReal z); +void dBodySetRotation (dBodyID, const dMatrix3 R); +void dBodySetQuaternion (dBodyID, const dQuaternion q); +void dBodySetLinearVel (dBodyID, dReal x, dReal y, dReal z); +void dBodySetAngularVel (dBodyID, dReal x, dReal y, dReal z); +const dReal * dBodyGetPosition (dBodyID); +const dReal * dBodyGetRotation (dBodyID); /* ptr to 4x3 rot matrix */ +const dReal * dBodyGetQuaternion (dBodyID); +const dReal * dBodyGetLinearVel (dBodyID); +const dReal * dBodyGetAngularVel (dBodyID); + +void dBodySetMass (dBodyID, const dMass *mass); +void dBodyGetMass (dBodyID, dMass *mass); + +void dBodyAddForce (dBodyID, dReal fx, dReal fy, dReal fz); +void dBodyAddTorque (dBodyID, dReal fx, dReal fy, dReal fz); +void dBodyAddRelForce (dBodyID, dReal fx, dReal fy, dReal fz); +void dBodyAddRelTorque (dBodyID, dReal fx, dReal fy, dReal fz); +void dBodyAddForceAtPos (dBodyID, dReal fx, dReal fy, dReal fz, + dReal px, dReal py, dReal pz); +void dBodyAddForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz, + dReal px, dReal py, dReal pz); +void dBodyAddRelForceAtPos (dBodyID, dReal fx, dReal fy, dReal fz, + dReal px, dReal py, dReal pz); +void dBodyAddRelForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz, + dReal px, dReal py, dReal pz); + +const dReal * dBodyGetForce (dBodyID); +const dReal * dBodyGetTorque (dBodyID); +void dBodySetForce (dBodyID b, dReal x, dReal y, dReal z); +void dBodySetTorque (dBodyID b, dReal x, dReal y, dReal z); + +void dBodyGetRelPointPos (dBodyID, dReal px, dReal py, dReal pz, + dVector3 result); +void dBodyGetRelPointVel (dBodyID, dReal px, dReal py, dReal pz, + dVector3 result); +void dBodyGetPointVel (dBodyID, dReal px, dReal py, dReal pz, + dVector3 result); +void dBodyGetPosRelPoint (dBodyID, dReal px, dReal py, dReal pz, + dVector3 result); +void dBodyVectorToWorld (dBodyID, dReal px, dReal py, dReal pz, + dVector3 result); +void dBodyVectorFromWorld (dBodyID, dReal px, dReal py, dReal pz, + dVector3 result); + +void dBodySetFiniteRotationMode (dBodyID, int mode); +void dBodySetFiniteRotationAxis (dBodyID, dReal x, dReal y, dReal z); + +int dBodyGetFiniteRotationMode (dBodyID); +void dBodyGetFiniteRotationAxis (dBodyID, dVector3 result); + +int dBodyGetNumJoints (dBodyID b); +dJointID dBodyGetJoint (dBodyID, int index); + +void dBodyEnable (dBodyID); +void dBodyDisable (dBodyID); +int dBodyIsEnabled (dBodyID); + +void dBodySetGravityMode (dBodyID b, int mode); +int dBodyGetGravityMode (dBodyID b); + + +/* joints */ + +dJointID dJointCreateBall (dWorldID, dJointGroupID); +dJointID dJointCreateHinge (dWorldID, dJointGroupID); +dJointID dJointCreateSlider (dWorldID, dJointGroupID); +dJointID dJointCreateContact (dWorldID, dJointGroupID, const dContact *); +dJointID dJointCreateHinge2 (dWorldID, dJointGroupID); +dJointID dJointCreateUniversal (dWorldID, dJointGroupID); +dJointID dJointCreateFixed (dWorldID, dJointGroupID); +dJointID dJointCreateNull (dWorldID, dJointGroupID); +dJointID dJointCreateAMotor (dWorldID, dJointGroupID); + +void dJointDestroy (dJointID); + +dJointGroupID dJointGroupCreate (int max_size); +void dJointGroupDestroy (dJointGroupID); +void dJointGroupEmpty (dJointGroupID); + +void dJointAttach (dJointID, dBodyID body1, dBodyID body2); +void dJointSetData (dJointID, void *data); +void *dJointGetData (dJointID); +int dJointGetType (dJointID); +dBodyID dJointGetBody (dJointID, int index); + +void dJointSetFeedback (dJointID, dJointFeedback *); +dJointFeedback *dJointGetFeedback (dJointID); + +/******************** breakable joint contribution ***********************/ +void dJointSetBreakable (dJointID, int b); +void dJointSetBreakCallback (dJointID, dJointBreakCallback *callbackFunc); +void dJointSetBreakMode (dJointID, int mode); +int dJointGetBreakMode (dJointID); +void dJointSetBreakForce (dJointID, int body, dReal x, dReal y, dReal z); +void dJointSetBreakTorque (dJointID, int body, dReal x, dReal y, dReal z); +int dJointIsBreakable (dJointID); +void dJointGetBreakForce (dJointID, int body, dReal *force); +void dJointGetBreakTorque (dJointID, int body, dReal *torque); +/*************************************************************************/ + +void dJointSetBallAnchor (dJointID, dReal x, dReal y, dReal z); +void dJointSetHingeAnchor (dJointID, dReal x, dReal y, dReal z); +void dJointSetHingeAxis (dJointID, dReal x, dReal y, dReal z); +void dJointSetHingeParam (dJointID, int parameter, dReal value); +void dJointAddHingeTorque(dJointID joint, dReal torque); +void dJointSetSliderAxis (dJointID, dReal x, dReal y, dReal z); +void dJointSetSliderParam (dJointID, int parameter, dReal value); +void dJointAddSliderForce(dJointID joint, dReal force); +void dJointSetHinge2Anchor (dJointID, dReal x, dReal y, dReal z); +void dJointSetHinge2Axis1 (dJointID, dReal x, dReal y, dReal z); +void dJointSetHinge2Axis2 (dJointID, dReal x, dReal y, dReal z); +void dJointSetHinge2Param (dJointID, int parameter, dReal value); +void dJointAddHinge2Torques(dJointID joint, dReal torque1, dReal torque2); +void dJointSetUniversalAnchor (dJointID, dReal x, dReal y, dReal z); +void dJointSetUniversalAxis1 (dJointID, dReal x, dReal y, dReal z); +void dJointSetUniversalAxis2 (dJointID, dReal x, dReal y, dReal z); +void dJointSetUniversalParam (dJointID, int parameter, dReal value); +void dJointAddUniversalTorques(dJointID joint, dReal torque1, dReal torque2); +void dJointSetFixed (dJointID); +void dJointSetAMotorNumAxes (dJointID, int num); +void dJointSetAMotorAxis (dJointID, int anum, int rel, + dReal x, dReal y, dReal z); +void dJointSetAMotorAngle (dJointID, int anum, dReal angle); +void dJointSetAMotorParam (dJointID, int parameter, dReal value); +void dJointSetAMotorMode (dJointID, int mode); +void dJointAddAMotorTorques (dJointID, dReal torque1, dReal torque2, dReal torque3); + +void dJointGetBallAnchor (dJointID, dVector3 result); +void dJointGetBallAnchor2 (dJointID, dVector3 result); +void dJointGetHingeAnchor (dJointID, dVector3 result); +void dJointGetHingeAnchor2 (dJointID, dVector3 result); +void dJointGetHingeAxis (dJointID, dVector3 result); +dReal dJointGetHingeParam (dJointID, int parameter); +dReal dJointGetHingeAngle (dJointID); +dReal dJointGetHingeAngleRate (dJointID); +dReal dJointGetSliderPosition (dJointID); +dReal dJointGetSliderPositionRate (dJointID); +void dJointGetSliderAxis (dJointID, dVector3 result); +dReal dJointGetSliderParam (dJointID, int parameter); +void dJointGetHinge2Anchor (dJointID, dVector3 result); +void dJointGetHinge2Anchor2 (dJointID, dVector3 result); +void dJointGetHinge2Axis1 (dJointID, dVector3 result); +void dJointGetHinge2Axis2 (dJointID, dVector3 result); +dReal dJointGetHinge2Param (dJointID, int parameter); +dReal dJointGetHinge2Angle1 (dJointID); +dReal dJointGetHinge2Angle1Rate (dJointID); +dReal dJointGetHinge2Angle2Rate (dJointID); +void dJointGetUniversalAnchor (dJointID, dVector3 result); +void dJointGetUniversalAnchor2 (dJointID, dVector3 result); +void dJointGetUniversalAxis1 (dJointID, dVector3 result); +void dJointGetUniversalAxis2 (dJointID, dVector3 result); +dReal dJointGetUniversalParam (dJointID, int parameter); +dReal dJointGetUniversalAngle1 (dJointID); +dReal dJointGetUniversalAngle2 (dJointID); +dReal dJointGetUniversalAngle1Rate (dJointID); +dReal dJointGetUniversalAngle2Rate (dJointID); +int dJointGetAMotorNumAxes (dJointID); +void dJointGetAMotorAxis (dJointID, int anum, dVector3 result); +int dJointGetAMotorAxisRel (dJointID, int anum); +dReal dJointGetAMotorAngle (dJointID, int anum); +dReal dJointGetAMotorAngleRate (dJointID, int anum); +dReal dJointGetAMotorParam (dJointID, int parameter); +int dJointGetAMotorMode (dJointID); + +int dAreConnected (dBodyID, dBodyID); +int dAreConnectedExcluding (dBodyID, dBodyID, int joint_type); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/ode-0.9/contrib/BreakableJoints/ode.cpp b/libraries/ode-0.9/contrib/BreakableJoints/ode.cpp new file mode 100644 index 0000000000..7137960dbc --- /dev/null +++ b/libraries/ode-0.9/contrib/BreakableJoints/ode.cpp @@ -0,0 +1,1404 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without 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 "joint.h" +#include +#include +#include "step.h" +#include +#include + +// misc defines +#define ALLOCA dALLOCA16 + +//**************************************************************************** +// utility + +static inline void initObject (dObject *obj, dxWorld *w) +{ + obj->world = w; + obj->next = 0; + obj->tome = 0; + obj->userdata = 0; + obj->tag = 0; +} + + +// add an object `obj' to the list who's head pointer is pointed to by `first'. + +static inline 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; +} + +//**************************************************************************** +// 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 processIslands (dxWorld *world, dReal stepsize) +{ + dxBody *b,*bb,**body; + dxJoint *j,**joint; + + // nothing to do if no bodies + if (world->nb <= 0) return; + + // 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->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 + dInternalStepIsland (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)) { + if (!j->tag) dDebug (0,"attached enabled joint not tagged"); + } + else { + if (j->tag) dDebug (0,"unattached or disabled joint tagged"); + } + } +# endif + /******************** breakable joint contribution ***********************/ + dxJoint* nextJ; + if (!world->firstjoint) + nextJ = 0; + else + nextJ = (dxJoint*)world->firstjoint->next; + for (j=world->firstjoint; j; j=nextJ) { + nextJ = (dxJoint*)j->next; + // check if joint is breakable and broken + if (j->breakInfo && j->breakInfo->flags & dJOINT_BROKEN) { + // detach (break) the joint + dJointAttach (j, 0, 0); + // call the callback function if it is set + if (j->breakInfo->callback) j->breakInfo->callback (j); + // finally destroy the joint if the dJOINT_DELETE_ON_BREAK is set + if (j->breakInfo->flags & dJOINT_DELETE_ON_BREAK) dJointDestroy (j); + } + } + /*************************************************************************/ +} + +//**************************************************************************** +// 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 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 + static int count = 0; + count++; + 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 *dBodyCreate (dxWorld *w) +{ + dAASSERT (w); + dxBody *b = new dxBody; + initObject (b,w); + b->firstjoint = 0; + b->flags = 0; + b->geom = 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->pos,4); + dSetZero (b->q,4); + b->q[0] = 1; + dRSetIdentity (b->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++; + 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 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->pos[0] = x; + b->pos[1] = y; + b->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); + dQuaternion q; + dRtoQ (R,q); + dNormalize4 (q); + b->q[0] = q[0]; + b->q[1] = q[1]; + b->q[2] = q[2]; + b->q[3] = q[3]; + dQtoR (b->q,b->R); + + // 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->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->pos; +} + + +const dReal * dBodyGetRotation (dBodyID b) +{ + dAASSERT (b); + return b->R; +} + + +const dReal * dBodyGetQuaternion (dBodyID b) +{ + dAASSERT (b); + return b->q; +} + + +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); + 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->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->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->pos[0]; + q[1] = py - b->pos[1]; + q[2] = pz - b->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->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->R,frel); + b->facc[0] += f[0]; + b->facc[1] += f[1]; + b->facc[2] += f[2]; + dVector3 q; + q[0] = px - b->pos[0]; + q[1] = py - b->pos[1]; + q[2] = pz - b->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->R,frel); + dMULTIPLY0_331 (p,b->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->R,prel); + result[0] = p[0] + b->pos[0]; + result[1] = p[1] + b->pos[1]; + result[2] = p[2] + b->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->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->pos[0]; + p[1] = py - b->pos[1]; + p[2] = pz - b->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->pos[0]; + prel[1] = py - b->pos[1]; + prel[2] = pz - b->pos[2]; + prel[3] = 0; + dMULTIPLY1_331 (result,b->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->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->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 dBodyEnable (dBodyID b) +{ + dAASSERT (b); + b->flags &= ~dxBodyDisabled; +} + + +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); +} + +//**************************************************************************** +// joints + +static void dJointInit (dxWorld *w, dxJoint *j) +{ + dIASSERT (w && j); + initObject (j,w); + j->vtable = 0; + j->flags = 0; + j->node[0].joint = j; + j->node[0].body = 0; + j->node[0].next = 0; + j->node[1].joint = j; + j->node[1].body = 0; + j->node[1].next = 0; + addObjectToList (j,(dObject **) &w->firstjoint); + w->nj++; +} + + +static dxJoint *createJoint (dWorldID w, dJointGroupID group, + dxJoint::Vtable *vtable) +{ + dIASSERT (w && vtable); + dxJoint *j; + if (group) { + j = (dxJoint*) group->stack.alloc (vtable->size); + group->num++; + } + else j = (dxJoint*) dAlloc (vtable->size); + dJointInit (w,j); + j->vtable = vtable; + if (group) j->flags |= dJOINT_INGROUP; + if (vtable->init) vtable->init (j); + j->feedback = 0; + /******************** breakable joint contribution ***********************/ + j->breakInfo = 0; + /*************************************************************************/ + return j; +} + + +dxJoint * dJointCreateBall (dWorldID w, dJointGroupID group) +{ + dAASSERT (w); + return createJoint (w,group,&__dball_vtable); +} + + +dxJoint * dJointCreateHinge (dWorldID w, dJointGroupID group) +{ + dAASSERT (w); + return createJoint (w,group,&__dhinge_vtable); +} + + +dxJoint * dJointCreateSlider (dWorldID w, dJointGroupID group) +{ + dAASSERT (w); + return createJoint (w,group,&__dslider_vtable); +} + + +dxJoint * dJointCreateContact (dWorldID w, dJointGroupID group, + const dContact *c) +{ + dAASSERT (w && c); + dxJointContact *j = (dxJointContact *) + createJoint (w,group,&__dcontact_vtable); + j->contact = *c; + return j; +} + + +dxJoint * dJointCreateHinge2 (dWorldID w, dJointGroupID group) +{ + dAASSERT (w); + return createJoint (w,group,&__dhinge2_vtable); +} + + +dxJoint * dJointCreateUniversal (dWorldID w, dJointGroupID group) +{ + dAASSERT (w); + return createJoint (w,group,&__duniversal_vtable); +} + + +dxJoint * dJointCreateFixed (dWorldID w, dJointGroupID group) +{ + dAASSERT (w); + return createJoint (w,group,&__dfixed_vtable); +} + + +dxJoint * dJointCreateNull (dWorldID w, dJointGroupID group) +{ + dAASSERT (w); + return createJoint (w,group,&__dnull_vtable); +} + + +dxJoint * dJointCreateAMotor (dWorldID w, dJointGroupID group) +{ + dAASSERT (w); + return createJoint (w,group,&__damotor_vtable); +} + + +void dJointDestroy (dxJoint *j) +{ + dAASSERT (j); + if (j->flags & dJOINT_INGROUP) return; + removeJointReferencesFromAttachedBodies (j); + removeObjectFromList (j); + /******************** breakable joint contribution ***********************/ + if (j->breakInfo) delete j->breakInfo; + /*************************************************************************/ + j->world->nj--; + dFree (j,j->vtable->size); +} + + +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->vtable->size)); + } + for (i=group->num-1; i >= 0; i--) { + if (jlist[i]->world) { + removeJointReferencesFromAttachedBodies (jlist[i]); + removeObjectFromList (jlist[i]); + jlist[i]->world->nj--; + } + } + group->num = 0; + group->stack.freeAll(); +} + + +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; + } +} + + +void dJointSetData (dxJoint *joint, void *data) +{ + dAASSERT (joint); + joint->userdata = data; +} + + +void *dJointGetData (dxJoint *joint) +{ + dAASSERT (joint); + return joint->userdata; +} + + +int dJointGetType (dxJoint *joint) +{ + dAASSERT (joint); + return joint->vtable->typenum; +} + + +dBodyID dJointGetBody (dxJoint *joint, int index) +{ + dAASSERT (joint); + if (index >= 0 && index < 2) 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; +} + + +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 + return w; +} + + +void dWorldDestroy (dxWorld *w) +{ + // delete all bodies and joints + dAASSERT (w); + dxBody *nextb, *b = w->firstbody; + while (b) { + nextb = (dxBody*) b->next; + delete b; + 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 { + dFree (j,j->vtable->size); + } + 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"); + processIslands (w,stepsize); +} + + +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; +} + +//**************************************************************************** +// 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); + */ +} diff --git a/libraries/ode-0.9/contrib/BreakableJoints/step.cpp b/libraries/ode-0.9/contrib/BreakableJoints/step.cpp new file mode 100644 index 0000000000..38aed6ccad --- /dev/null +++ b/libraries/ode-0.9/contrib/BreakableJoints/step.cpp @@ -0,0 +1,1170 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without 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 "joint.h" +#include +#include +#include +#include +#include +#include +#include "lcp.h" + +//**************************************************************************** +// misc defines + +#define FAST_FACTOR +//#define TIMING + +#define ALLOCA dALLOCA16 + +//**************************************************************************** +// 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 + +//**************************************************************************** +// 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; kpos[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->R); + + // notify all attached geoms that this body has moved + for (dxGeom *geom = b->geom; geom; geom = dGeomGetBodyNext (geom)) + dGeomMoved (geom); +} + +//**************************************************************************** +// the slow, but sure way +// note that this does not do any joint feedback! + +// given lists of bodies and joints that form an island, perform a first +// order timestep. +// +// `body' is the body array, `nb' is the size of the array. +// `_joint' is the body array, `nj' is the size of the array. + +void dInternalStepIsland_x1 (dxWorld *world, dxBody * const *body, int nb, + dxJoint * const *_joint, int nj, dReal stepsize) +{ + int i,j,k; + int n6 = 6*nb; + +# ifdef TIMING + dTimerStart("preprocessing"); +# endif + + // 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). + 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. + // @@@ check computation of rotational force. + dReal *I = (dReal*) ALLOCA (3*nb*4 * sizeof(dReal)); + dReal *invI = (dReal*) ALLOCA (3*nb*4 * sizeof(dReal)); + + //dSetZero (I,3*nb*4); + //dSetZero (invI,3*nb*4); + for (i=0; imass.I,body[i]->R); + dMULTIPLY0_333 (I+i*12,body[i]->R,tmp); + // compute inverse inertia tensor in global frame + dMULTIPLY2_333 (tmp,body[i]->invI,body[i]->R); + dMULTIPLY0_333 (invI+i*12,body[i]->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; + dxJoint::Info1 *info = (dxJoint::Info1*) ALLOCA (nj*sizeof(dxJoint::Info1)); + int *ofs = (int*) ALLOCA (nj*sizeof(int)); + for (i=0, j=0; jvtable->getInfo1 (joint[j],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 + dReal *fe = (dReal*) ALLOCA (n6 * sizeof(dReal)); + dReal *v = (dReal*) ALLOCA (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 + dReal *vnew = (dReal*) ALLOCA (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. + dReal *c = (dReal*) ALLOCA (m*sizeof(dReal)); + dReal *cfm = (dReal*) ALLOCA (m*sizeof(dReal)); + dReal *lo = (dReal*) ALLOCA (m*sizeof(dReal)); + dReal *hi = (dReal*) ALLOCA (m*sizeof(dReal)); + 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; + 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]->vtable->getInfo2 (joint[i],&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 + dReal *JinvM = (dReal*) ALLOCA (m*nskip*sizeof(dReal)); + //dSetZero (JinvM,m*nskip); + dMultiply0 (JinvM,J,invM,m,n6,n6); + int mskip = dPAD(m); + dReal *A = (dReal*) ALLOCA (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). + 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 vertically stacked 3x4 matrices, one per body. + // @@@ check computation of rotational force. + dReal *I = (dReal*) ALLOCA (3*nb*4 * sizeof(dReal)); + dReal *invI = (dReal*) ALLOCA (3*nb*4 * sizeof(dReal)); + + //dSetZero (I,3*nb*4); + //dSetZero (invI,3*nb*4); + for (i=0; imass.I,body[i]->R); + dMULTIPLY0_333 (I+i*12,body[i]->R,tmp); + // compute inverse inertia tensor in global frame + dMULTIPLY2_333 (tmp,body[i]->invI,body[i]->R); + dMULTIPLY0_333 (invI+i*12,body[i]->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. 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; jvtable->getInfo1 (joint[j],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. + dReal *c = (dReal*) ALLOCA (m*sizeof(dReal)); + dReal *cfm = (dReal*) ALLOCA (m*sizeof(dReal)); + dReal *lo = (dReal*) ALLOCA (m*sizeof(dReal)); + dReal *hi = (dReal*) ALLOCA (m*sizeof(dReal)); + 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; + for (i=0; ivtable->getInfo2 (joint[i],&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 + dReal *JinvM = (dReal*) ALLOCA (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); + dReal *A = (dReal*) ALLOCA (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 + dReal *rhs = (dReal*) ALLOCA (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; + +/******************** breakable joint contribution ***********************/ + // this saves us a few dereferences + dxJointBreakInfo *jBI = joint[i]->breakInfo; + // we need joint feedback if the joint is breakable or if the user + // requested feedback. + if (jBI||fb) { + // we need 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. + dJointFeedback temp_fb; // temporary storage for joint feedback + dReal data1[8],data2[8]; + Multiply1_8q1 (data1, JJ, lambda+ofs[i], info[i].m); + dReal *cf1 = cforce + 8*b1->tag; + cf1[0] += (temp_fb.f1[0] = data1[0]); + cf1[1] += (temp_fb.f1[1] = data1[1]); + cf1[2] += (temp_fb.f1[2] = data1[2]); + cf1[4] += (temp_fb.t1[0] = data1[4]); + cf1[5] += (temp_fb.t1[1] = data1[5]); + cf1[6] += (temp_fb.t1[2] = data1[6]); + if (b2) { + Multiply1_8q1 (data2, JJ + 8*info[i].m, lambda+ofs[i], info[i].m); + dReal *cf2 = cforce + 8*b2->tag; + cf2[0] += (temp_fb.f2[0] = data2[0]); + cf2[1] += (temp_fb.f2[1] = data2[1]); + cf2[2] += (temp_fb.f2[2] = data2[2]); + cf2[4] += (temp_fb.t2[0] = data2[4]); + cf2[5] += (temp_fb.t2[1] = data2[5]); + cf2[6] += (temp_fb.t2[2] = data2[6]); + } + // if the user requested so we must copy the feedback information to + // the feedback struct that the user suplied. + if (fb) { + // copy temp_fb to fb + fb->f1[0] = temp_fb.f1[0]; + fb->f1[1] = temp_fb.f1[1]; + fb->f1[2] = temp_fb.f1[2]; + fb->t1[0] = temp_fb.t1[0]; + fb->t1[1] = temp_fb.t1[1]; + fb->t1[2] = temp_fb.t1[2]; + if (b2) { + fb->f2[0] = temp_fb.f2[0]; + fb->f2[1] = temp_fb.f2[1]; + fb->f2[2] = temp_fb.f2[2]; + fb->t2[0] = temp_fb.t2[0]; + fb->t2[1] = temp_fb.t2[1]; + fb->t2[2] = temp_fb.t2[2]; + } + } + // if the joint is breakable we need to check the breaking conditions + if (jBI) { + dReal relCF1[3]; + dReal relCT1[3]; + // multiply the force and torque vectors by the rotation matrix of body 1 + dMULTIPLY1_331 (&relCF1[0],b1->R,&temp_fb.f1[0]); + dMULTIPLY1_331 (&relCT1[0],b1->R,&temp_fb.t1[0]); + if (jBI->flags & dJOINT_BREAK_AT_B1_FORCE) { + // check if the force is to high + for (int i = 0; i < 3; i++) { + if (relCF1[i] > jBI->b1MaxF[i]) { + jBI->flags |= dJOINT_BROKEN; + goto doneCheckingBreaks; + } + } + } + if (jBI->flags & dJOINT_BREAK_AT_B1_TORQUE) { + // check if the torque is to high + for (int i = 0; i < 3; i++) { + if (relCT1[i] > jBI->b1MaxT[i]) { + jBI->flags |= dJOINT_BROKEN; + goto doneCheckingBreaks; + } + } + } + if (b2) { + dReal relCF2[3]; + dReal relCT2[3]; + // multiply the force and torque vectors by the rotation matrix of body 2 + dMULTIPLY1_331 (&relCF2[0],b2->R,&temp_fb.f2[0]); + dMULTIPLY1_331 (&relCT2[0],b2->R,&temp_fb.t2[0]); + if (jBI->flags & dJOINT_BREAK_AT_B2_FORCE) { + // check if the force is to high + for (int i = 0; i < 3; i++) { + if (relCF2[i] > jBI->b2MaxF[i]) { + jBI->flags |= dJOINT_BROKEN; + goto doneCheckingBreaks; + } + } + } + if (jBI->flags & dJOINT_BREAK_AT_B2_TORQUE) { + // check if the torque is to high + for (int i = 0; i < 3; i++) { + if (relCT2[i] > jBI->b2MaxT[i]) { + jBI->flags |= dJOINT_BROKEN; + goto doneCheckingBreaks; + } + } + } + } + doneCheckingBreaks: + ; + } + } +/*************************************************************************/ + 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) +{ +# ifndef COMPARE_METHODS + dInternalStepIsland_x2 (world,body,nb,joint,nj,stepsize); +# endif + +# ifdef COMPARE_METHODS + int i; + + // save body state + dxBody *state = (dxBody*) ALLOCA (nb*sizeof(dxBody)); + for (i=0; i +#include +#include +#include +#include +#include +#include +#include "lcp.h" +#include "step.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; +} + + +// 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->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->R); + + // notify all attached geoms that this body has moved + for (dxGeom * geom = b->geom; geom; geom = dGeomGetBodyNext (geom)) + dGeomMoved (geom); +} + +//**************************************************************************** +//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); + + // 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); + + // 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); + +/******************** breakable joint contribution ***********************/ + // this saves us a few dereferences + dxJointBreakInfo *jBI = joint->breakInfo; + // we need joint feedback if the joint is breakable or if the user + // requested feedback. + if (jBI||fb) { + // we need 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. + dJointFeedback temp_fb; // temporary storage for joint feedback + dReal data1[8],data2[8]; + if (body[0]) + { + Multiply1_8q1 (data1, Jinfo.J1l, lambda, m); + dReal *cf1 = cforce; + cf1[0] = (temp_fb.f1[0] = data1[0]); + cf1[1] = (temp_fb.f1[1] = data1[1]); + cf1[2] = (temp_fb.f1[2] = data1[2]); + cf1[4] = (temp_fb.t1[0] = data1[4]); + cf1[5] = (temp_fb.t1[1] = data1[5]); + cf1[6] = (temp_fb.t1[2] = data1[6]); + } + if (body[1]) + { + Multiply1_8q1 (data2, Jinfo.J2l, lambda, m); + dReal *cf2 = cforce + 8; + cf2[0] = (temp_fb.f2[0] = data2[0]); + cf2[1] = (temp_fb.f2[1] = data2[1]); + cf2[2] = (temp_fb.f2[2] = data2[2]); + cf2[4] = (temp_fb.t2[0] = data2[4]); + cf2[5] = (temp_fb.t2[1] = data2[5]); + cf2[6] = (temp_fb.t2[2] = data2[6]); + } + // if the user requested so we must copy the feedback information to + // the feedback struct that the user suplied. + if (fb) { + // copy temp_fb to fb + fb->f1[0] = temp_fb.f1[0]; + fb->f1[1] = temp_fb.f1[1]; + fb->f1[2] = temp_fb.f1[2]; + fb->t1[0] = temp_fb.t1[0]; + fb->t1[1] = temp_fb.t1[1]; + fb->t1[2] = temp_fb.t1[2]; + if (body[1]) { + fb->f2[0] = temp_fb.f2[0]; + fb->f2[1] = temp_fb.f2[1]; + fb->f2[2] = temp_fb.f2[2]; + fb->t2[0] = temp_fb.t2[0]; + fb->t2[1] = temp_fb.t2[1]; + fb->t2[2] = temp_fb.t2[2]; + } + } + // if the joint is breakable we need to check the breaking conditions + if (jBI) { + dReal relCF1[3]; + dReal relCT1[3]; + // multiply the force and torque vectors by the rotation matrix of body 1 + dMULTIPLY1_331 (&relCF1[0],body[0]->R,&temp_fb.f1[0]); + dMULTIPLY1_331 (&relCT1[0],body[0]->R,&temp_fb.t1[0]); + if (jBI->flags & dJOINT_BREAK_AT_B1_FORCE) { + // check if the force is to high + for (int i = 0; i < 3; i++) { + if (relCF1[i] > jBI->b1MaxF[i]) { + jBI->flags |= dJOINT_BROKEN; + goto doneCheckingBreaks; + } + } + } + if (jBI->flags & dJOINT_BREAK_AT_B1_TORQUE) { + // check if the torque is to high + for (int i = 0; i < 3; i++) { + if (relCT1[i] > jBI->b1MaxT[i]) { + jBI->flags |= dJOINT_BROKEN; + goto doneCheckingBreaks; + } + } + } + if (body[1]) { + dReal relCF2[3]; + dReal relCT2[3]; + // multiply the force and torque vectors by the rotation matrix of body 2 + dMULTIPLY1_331 (&relCF2[0],body[1]->R,&temp_fb.f2[0]); + dMULTIPLY1_331 (&relCT2[0],body[1]->R,&temp_fb.t2[0]); + if (jBI->flags & dJOINT_BREAK_AT_B2_FORCE) { + // check if the force is to high + for (int i = 0; i < 3; i++) { + if (relCF2[i] > jBI->b2MaxF[i]) { + jBI->flags |= dJOINT_BROKEN; + goto doneCheckingBreaks; + } + } + } + if (jBI->flags & dJOINT_BREAK_AT_B2_TORQUE) { + // check if the torque is to high + for (int i = 0; i < 3; i++) { + if (relCT2[i] > jBI->b2MaxT[i]) { + jBI->flags |= dJOINT_BROKEN; + goto doneCheckingBreaks; + } + } + } + } + doneCheckingBreaks: + ; + } + } +/*************************************************************************/ + 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]->vtable->getInfo1 (joints[j], 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]->vtable->getInfo2 (joints[i], 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->R); + dMULTIPLY0_333 (globalI + b * 12, body->R, tmp); + // compute inverse inertia tensor in global frame + dMULTIPLY2_333 (tmp, body->invI, body->R); + dMULTIPLY0_333 (globalInvI + b * 12, body->R, tmp); + + for (i = 0; i < 4; i++) + body->tacc[i] = saveTacc[b * 4 + i]; + // 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; + } + + } + +#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]; + int r = rand () % (j + 1); + 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]->vtable->getInfo2 (joints[j], 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! + moveAndRotateBody (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; + +# 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; + + // 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 + /******************** breakable joint contribution ***********************/ + dxJoint* nextJ; + if (!world->firstjoint) + nextJ = 0; + else + nextJ = (dxJoint*)world->firstjoint->next; + for (j=world->firstjoint; j; j=nextJ) { + nextJ = (dxJoint*)j->next; + // check if joint is breakable and broken + if (j->breakInfo && j->breakInfo->flags & dJOINT_BROKEN) { + // detach (break) the joint + dJointAttach (j, 0, 0); + // call the callback function if it is set + if (j->breakInfo->callback) j->breakInfo->callback (j); + // finally destroy the joint if the dJOINT_DELETE_ON_BREAK is set + if (j->breakInfo->flags & dJOINT_DELETE_ON_BREAK) dJointDestroy (j); + } + } + /*************************************************************************/ + +# 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); +} diff --git a/libraries/ode-0.9/contrib/BreakableJoints/test_breakable.cpp b/libraries/ode-0.9/contrib/BreakableJoints/test_breakable.cpp new file mode 100644 index 0000000000..bfed3a32f7 --- /dev/null +++ b/libraries/ode-0.9/contrib/BreakableJoints/test_breakable.cpp @@ -0,0 +1,416 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without 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 + +#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 dsDrawCappedCylinder dsDrawCappedCylinderD +#endif + + +// some constants + +#define LENGTH 0.7 // chassis length +#define WIDTH 0.4 // chassis width +#define HEIGHT 0.2 // chassis height +#define RADIUS 0.22 // wheel radius +#define STARTZ 0.4 // starting height of chassis +#define CMASS 1 // chassis mass +#define WMASS 0.2 // wheel mass + +// dynamics and collision objects (chassis, 4 wheels, environment, obstacles, chain) +static dWorldID world; +static dSpaceID space; + +// chain stuff +static const float chain_radius = 0.1; +static const float chain_mass = 0.1; +static const int chain_num = 10; +static dBodyID chain_body[chain_num]; +static dGeomID chain_geom[chain_num]; +static dJointID chain_joint[chain_num-1]; + +// 1 chasses, 4 wheels +static dBodyID body[5]; +// joint[0] is left front wheel, joint[1] is right front wheel +static dJointID joint[4]; +static int joint_exists[4]; +static dJointGroupID contactgroup; +static dGeomID ground; +static dSpaceID car_space; +static dGeomID box[1]; +static dGeomID sphere[4]; +static dGeomID ground_box; +static const int obstacle_num = 25; +static dGeomID obstacle[obstacle_num]; + +// 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; + +// // do not collide objects that are connected +// dBodyID b1 = dGeomGetBody (o1), +// b2 = dGeomGetBody (o2); +// if (b1 && b2 && dAreConnected(b1, b2)) 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[i],dParamVel,v); + dJointSetHinge2Param (joint[i],dParamFMax,0.2); + dJointSetHinge2Param (joint[i],dParamLoStop,-0.75); + dJointSetHinge2Param (joint[i],dParamHiStop,0.75); + dJointSetHinge2Param (joint[i],dParamFudgeFactor,0.1); + } + } + + dSpaceCollide (space,0,&nearCallback); + //dWorldStep (world,0.05); + dWorldStepFast1 (world,0.05,5); + + // 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<=4; i++) + dsDrawCylinder (dBodyGetPosition(body[i]), + dBodyGetRotation(body[i]), + 0.2, + RADIUS); + + dVector3 ss; + dGeomBoxGetLengths (ground_box,ss); + dsDrawBox (dGeomGetPosition(ground_box),dGeomGetRotation(ground_box),ss); + + dsSetColor (1,0,0); + for (i=0; i +#include + +#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 dsDrawCappedCylinder dsDrawCappedCylinderD +#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/textures"; + if(argc==2) + { + fn.path_to_textures = argv[1]; + } + + // create world + + 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); + + // breakable joints contribution + // the wheels can break + dJointSetBreakable (joint[i], 1); + // the wheels wil break at a specific force + dJointSetBreakMode (joint[i], dJOINT_BREAK_AT_B1_FORCE|dJOINT_BREAK_AT_B2_FORCE); + // specify the force for the first body connected to the joint ... + dJointSetBreakForce (joint[i], 0, 1.5, 1.5, 1.5); + // and for the second body + dJointSetBreakForce (joint[i], 1, 1.5, 1.5, 1.5); + } + + // 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); + + dJointGroupDestroy (contactgroup); + dSpaceDestroy (space); + dWorldDestroy (world); + dGeomDestroy (box[0]); + dGeomDestroy (sphere[0]); + dGeomDestroy (sphere[1]); + dGeomDestroy (sphere[2]); + + return 0; +} diff --git a/libraries/ode-0.9/contrib/DotNetManaged/AssemblyInfo.cpp b/libraries/ode-0.9/contrib/DotNetManaged/AssemblyInfo.cpp new file mode 100644 index 0000000000..e550a32282 --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/AssemblyInfo.cpp @@ -0,0 +1,58 @@ +#include "stdafx.h" + +using namespace System::Reflection; +using namespace System::Runtime::CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly:AssemblyTitleAttribute("")]; +[assembly:AssemblyDescriptionAttribute("")]; +[assembly:AssemblyConfigurationAttribute("")]; +[assembly:AssemblyCompanyAttribute("")]; +[assembly:AssemblyProductAttribute("")]; +[assembly:AssemblyCopyrightAttribute("")]; +[assembly:AssemblyTrademarkAttribute("")]; +[assembly:AssemblyCultureAttribute("")]; + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the value or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly:AssemblyVersionAttribute("1.0.*")]; + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project directory. +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly:AssemblyDelaySignAttribute(false)]; +[assembly:AssemblyKeyFileAttribute("")]; +[assembly:AssemblyKeyNameAttribute("")]; + diff --git a/libraries/ode-0.9/contrib/DotNetManaged/Body.cpp b/libraries/ode-0.9/contrib/DotNetManaged/Body.cpp new file mode 100644 index 0000000000..c95ae57909 --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/Body.cpp @@ -0,0 +1,322 @@ +#include "StdAfx.h" + +#include +#include "Body.h" + +namespace ODEManaged +{ + + //Constructors + + Body::Body(void) + { + _id = 0; + } + + Body::Body(World &world) + { + _id = dBodyCreate(world.Id()); + } + + + //Destructor + + Body::~Body(void) + { + dBodyDestroy(this->_id); + } + + + //Methods + + //Id + dBodyID Body::Id() + { + return _id; + } + + + //SetData + void Body::SetData(void *data) + { + dBodySetData(this->_id, data); + } + + //GetData + void *Body::GetData(void) + { + return dBodyGetData(this->_id); + } + + + //SetPosition + void Body::SetPosition (double x, double y, double z) + { + dBodySetPosition(this->_id, x, y, z); + } + + + //Overloaded GetPosition + Vector3 Body::GetPosition(void) + { + Vector3 retVal; + const dReal *temp; + temp = dBodyGetPosition(this->_id); + retVal.x = temp[0]; + retVal.y = temp[1]; + retVal.z = temp[2]; + return retVal; + }; + + void Body::GetPosition(double position __gc[]) + { + const dReal *temp; + temp = dBodyGetPosition(this->_id); + position[0] = temp[0]; + position[1] = temp[1]; + position[2] = temp[2]; + } + + + //SetRotationIdentity + void Body::SetRotationIdentity(void) + { + dMatrix3 temp; + dRSetIdentity(temp); + dBodySetRotation(this->_id, temp); + } + + + //SetRotation (left handed system=>transpose) + void Body::SetRotation(Matrix3 rotation) + { + dMatrix3 temp; + temp[0] = rotation.m11; + temp[4] = rotation.m12; + temp[8] = rotation.m13; + temp[1] = rotation.m21; + temp[5] = rotation.m22; + temp[9] = rotation.m23; + temp[2] = rotation.m31; + temp[6] = rotation.m32; + temp[10] = rotation.m33; + dBodySetRotation(this->_id, temp); + } + + //GetRotation (left handed system=>transpose) + Matrix3 Body::GetRotation(void) + { + Matrix3 retVal; + //const dMatrix3 *m; + const dReal *temp; + temp = dBodyGetRotation(this->_id); + retVal.m11 = temp[0]; + retVal.m12 = temp[4]; + retVal.m13 = temp[8]; + retVal.m21 = temp[1]; + retVal.m22 = temp[5]; + retVal.m23 = temp[9]; + retVal.m31 = temp[2]; + retVal.m32 = temp[6]; + retVal.m33 = temp[10]; + return retVal; + } + + + //Overloaded SetMass + void Body::SetMass(double mass, Vector3 centerOfGravity, Matrix3 inertia) + { + dMass *temp = new dMass(); + dMassSetParameters(temp, mass, + centerOfGravity.x, + centerOfGravity.y, + centerOfGravity.z, + inertia.m11, inertia.m22, + inertia.m33, inertia.m12, + inertia.m13, inertia.m23); + + dBodySetMass(this->_id, temp); + } + + + //SetMassSphere + void Body::SetMassSphere(double density, double radius) + { + dMass *temp = new dMass(); + dMassSetSphere(temp, density, radius); + dBodySetMass(this->_id, temp); + } + + + //SetMassBox + void Body::SetMassBox(double density, double sideX, double sideY, double sideZ) + { + dMass *temp = new dMass(); + dMassSetBox(temp, density, sideX, sideY, sideZ); + dBodySetMass(this->_id, temp); + } + + + //SetMassCappedCylinder + void Body::SetMassCappedCylinder(double density, int axis, double cylinderRadius, double cylinderLength) + { + dMass *temp = new dMass(); + dMassSetCappedCylinder(temp, density, axis, + cylinderRadius, + cylinderLength); + + dBodySetMass(this->_id, temp); + } + + + //AddForce + void Body::AddForce(double fX, double fY, double fZ) + { + dBodyAddForce(this->_id, fX, fY, fZ); + } + + + //AddRelForce + void Body::AddRelForce(double fX, double fY, double fZ) + { + dBodyAddRelForce(this->_id, fX,fY,fZ); + } + + + //AddForceAtPos + void Body::AddForceAtPos(double fX, double fY, double fZ, double pX, double pY, double pZ) + { + dBodyAddForceAtPos(this->_id, fX, fY, fZ, pX, pY, pZ); + } + + + //AddRelForceAtPos + void Body::AddRelForceAtPos(double fX, double fY, double fZ, double pX, double pY, double pZ) + { + dBodyAddRelForceAtPos(this->_id, fX, fY, fZ, pX, pY, pZ); + } + + + //AddRelForceAtRelPos + void Body::AddRelForceAtRelPos(double fX, double fY, double fZ, double pX, double pY, double pZ) + { + dBodyAddRelForceAtRelPos(this->_id, fX, fY, fZ, pX, pY, pZ); + } + + + //ApplyLinearVelocityDrag + void Body::ApplyLinearVelocityDrag(double dragCoef) + { + const dReal *temp; + double fX; + double fY; + double fZ; + temp = dBodyGetLinearVel(this->_id); + fX = temp[0]*dragCoef*-1; + fY = temp[1]*dragCoef*-1; + fZ = temp[2]*dragCoef*-1; + dBodyAddForce(this->_id, fX, fY, fZ); + } + + + //ApplyAngularVelocityDrag + void Body::ApplyAngularVelocityDrag(double dragCoef) + { + const dReal *temp; + double fX; + double fY; + double fZ; + temp = dBodyGetAngularVel(this->_id); + fX = temp[0]*dragCoef*-1; + fY = temp[1]*dragCoef*-1; + fZ = temp[2]*dragCoef*-1; + dBodyAddTorque(this->_id, fX, fY, fZ); + } + + + //AddTorque + void Body::AddTorque(double fX, double fY, double fZ) + { + dBodyAddTorque(this->_id, fX, fY, fZ); + } + + + //AddRelTorque + void Body::AddRelTorque(double fX, double fY, double fZ) + { + dBodyAddRelTorque(this->_id, fX,fY,fZ); + } + + + //SetLinearVelocity + void Body::SetLinearVelocity(double x, double y, double z) + { + dBodySetLinearVel(this->_id, x, y, z); + } + + + //GetLinearVelocity + Vector3 Body::GetLinearVelocity(void) + { + Vector3 retVal; + const dReal *temp; + temp = dBodyGetLinearVel(this->_id); + retVal.x = temp[0]; + retVal.y = temp[1]; + retVal.z = temp[2]; + return retVal; + } + + + //SetAngularVelocity + void Body::SetAngularVelocity(double x, double y, double z) + { + dBodySetAngularVel(this->_id, x, y, z); + } + + //GetAngularVelocity + Vector3 Body::GetAngularVelocity(void) + { + Vector3 retVal; + const dReal *temp; + temp = dBodyGetAngularVel(this->_id); + retVal.x = temp[0]; + retVal.y = temp[1]; + retVal.z = temp[2]; + return retVal; + } + + + //GetRelPointPos + Vector3 Body::GetRelPointPos(double pX, double pY, double pZ) + { + Vector3 retVal; + dVector3 temp; + dBodyGetRelPointPos(this->_id, pX, pY, pZ, temp); + retVal.x = temp[0]; + retVal.y = temp[1]; + retVal.z = temp[2]; + return retVal; + } + + + //GetRelPointVel + Vector3 Body::GetRelPointVel(double pX, double pY, double pZ) + { + Vector3 retVal; + dVector3 temp; + dBodyGetRelPointVel(this->_id, pX, pY, pZ, temp); + retVal.x = temp[0]; + retVal.y = temp[1]; + retVal.z = temp[2]; + return retVal; + } + + + //ConnectedTo + int Body::ConnectedTo(const Body &b) + { + return dAreConnected(this->_id, b._id); + } + +} diff --git a/libraries/ode-0.9/contrib/DotNetManaged/Body.h b/libraries/ode-0.9/contrib/DotNetManaged/Body.h new file mode 100644 index 0000000000..9347c179ef --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/Body.h @@ -0,0 +1,76 @@ +#pragma once + +#include "World.h" +#include "CommonMgd.h" + +namespace ODEManaged +{ + __gc public class Body + { + public: + + //Constructors and Destructors + + Body(void); + Body(World &world); + + ~Body(void); + + + //Public Methods + + dBodyID Id(); + void SetData (void *data); + void *GetData (void); + + //POSITION + void SetPosition(double x, double y, double z); + Vector3 GetPosition(void); + void GetPosition(double position __gc[]); + + //ROTATION + void SetRotationIdentity(void); + void SetRotation(Matrix3 rotation); + Matrix3 GetRotation(void); + + //MASS + void SetMass(double mass, Vector3 centerOfGravity, Matrix3 inertia); + void SetMassSphere(double density, double radius); + void SetMassBox(double density, double sideX, double sideY, double sideZ); + void SetMassCappedCylinder(double density, int axis, double cylinderRadius, double cylinderLength); + + //FORCE AND TORQUE + void AddForce(double fX, double fY, double fZ); + void AddRelForce(double fX, double fY, double fZ); + void AddForceAtPos(double fX, double fY, double fZ,double pX, double pY, double pZ); + void AddRelForceAtPos(double fX, double fY, double fZ,double pX, double pY, double pZ); + void AddRelForceAtRelPos(double fX, double fY, double fZ,double pX, double pY, double pZ); + void ApplyLinearVelocityDrag(double dragCoef); + void ApplyAngularVelocityDrag(double dragCoef); + + + void AddTorque(double fX, double fY, double fZ); + void AddRelTorque(double fX, double fY, double fZ); + + //LINEAR VELOCITY + void SetLinearVelocity (double x, double y, double z); + Vector3 GetLinearVelocity(void); + + //ANGULAR VELOCITY + void SetAngularVelocity (double x, double y, double z); + Vector3 GetAngularVelocity(void); + + //POINT + Vector3 GetRelPointPos(double pX, double pY, double pZ); + Vector3 GetRelPointVel(double pX, double pY, double pZ); + + //CONNECTED TO + int ConnectedTo (const Body &b); + + private: + + dBodyID _id; + + }; +} + diff --git a/libraries/ode-0.9/contrib/DotNetManaged/CommonMgd.h b/libraries/ode-0.9/contrib/DotNetManaged/CommonMgd.h new file mode 100644 index 0000000000..143397d179 --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/CommonMgd.h @@ -0,0 +1,43 @@ +#pragma once + +namespace ODEManaged +{ + + __value public struct Vector3 + { + double x; + double y; + double z; + }; + + + __value public struct Vector4 + { + double W; + double x; + double y; + double z; + }; + + + __value public struct Matrix3 + { + double m11; + double m12; + double m13; + double m21; + double m22; + double m23; + double m31; + double m32; + double m33; + }; + + //__value public struct NearCallback + //{ + // void *data; + // dGeomID o1; + // dGeomID o2; + //}; + +} \ No newline at end of file diff --git a/libraries/ode-0.9/contrib/DotNetManaged/DotNetManaged.sln b/libraries/ode-0.9/contrib/DotNetManaged/DotNetManaged.sln new file mode 100644 index 0000000000..2694a266d5 --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/DotNetManaged.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 7.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DotNetManaged", "DotNetManaged.vcproj", "{4B75AC19-971A-4CC6-A4F5-0695C9F8562F}" +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + ConfigName.0 = Debug + ConfigName.1 = Release + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {4B75AC19-971A-4CC6-A4F5-0695C9F8562F}.Debug.ActiveCfg = Debug|Win32 + {4B75AC19-971A-4CC6-A4F5-0695C9F8562F}.Debug.Build.0 = Debug|Win32 + {4B75AC19-971A-4CC6-A4F5-0695C9F8562F}.Release.ActiveCfg = Release|Win32 + {4B75AC19-971A-4CC6-A4F5-0695C9F8562F}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/libraries/ode-0.9/contrib/DotNetManaged/DotNetManaged.vcproj b/libraries/ode-0.9/contrib/DotNetManaged/DotNetManaged.vcproj new file mode 100644 index 0000000000..2f5bb6cbd9 --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/DotNetManaged.vcproj @@ -0,0 +1,379 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libraries/ode-0.9/contrib/DotNetManaged/Geom.cpp b/libraries/ode-0.9/contrib/DotNetManaged/Geom.cpp new file mode 100644 index 0000000000..3655466ad5 --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/Geom.cpp @@ -0,0 +1,219 @@ + +#include "StdAfx.h" + +#include +#include "Geom.h" + + +namespace ODEManaged +{ + + //Constructors + + Geom::Geom(void) + { + _id = 0; + } + + + //Destructor + + Geom::~Geom(void) + { + dGeomDestroy(this->_id); + } + + + //Methods + + //Id + dGeomID Geom::Id(void) + { + return _id; + } + + + //GetBody + dBodyID Geom::GetBody(void) + { + return dGeomGetBody(this->_id); + } + + + //Overloaded SetBody + void Geom::SetBody(Body &body) + { + dGeomSetBody(this->_id, body.Id()); + } + + //void Geom::SetBody(dBodyID b) + //{ + // dGeomSetBody(this->_id, b); + //} + + + //SetPosition + void Geom::SetPosition(double x, double y, double z) + { + dGeomSetPosition(this->_id, x, y, z); + } + + + //SetRotation + void Geom::SetRotation(Matrix3 rotation) + { + dMatrix3 temp; + temp[0] = rotation.m11; + temp[4] = rotation.m12; + temp[8] = rotation.m13; + temp[1] = rotation.m21; + temp[5] = rotation.m22; + temp[9] = rotation.m23; + temp[2] = rotation.m31; + temp[6] = rotation.m32; + temp[10] = rotation.m33; + dGeomSetRotation(_id, temp); + } + + + //Destroy + void Geom::Destroy() + { + if(this->_id) dGeomDestroy(this->_id); + _id = 0; + } + + + //SetData + void Geom::SetData(void *data) + { + dGeomSetData(this->_id, data); + } + + + //GetData + void *Geom::GetData(void) + { + return dGeomGetData(this->_id); + } + + + //GetPosition + Vector3 Geom::GetPosition(void) + { + Vector3 retVal; + const dReal *temp; + temp = dGeomGetPosition(this->_id); + retVal.x = temp[0]; + retVal.y = temp[1]; + retVal.z = temp[2]; + return retVal; + } + + + //GetRotation (left handed system=>transpose) + Matrix3 Geom::GetRotation(void) + { + Matrix3 retVal; + const dReal *temp; + temp = dGeomGetRotation(this->_id); + retVal.m11 = temp[0]; + retVal.m12 = temp[4]; + retVal.m13 = temp[8]; + retVal.m21 = temp[1]; + retVal.m22 = temp[5]; + retVal.m23 = temp[9]; + retVal.m31 = temp[2]; + retVal.m32 = temp[6]; + retVal.m33 = temp[10]; + return retVal; + } + + + //CreateSphere + void Geom::CreateSphere(Space &space, double radius) + { + if(this->_id) dGeomDestroy(this->_id); + _id = dCreateSphere(space.Id(), radius); + } + + + //CreateBox + void Geom::CreateBox(Space &space, double lx, double ly, double lz) + { + if(this->_id) dGeomDestroy(this->_id); + _id = dCreateBox(space.Id(), lx, ly, lz); + } + + + //CreatePlane + void Geom::CreatePlane(Space &space, double a, double b, double c, double d) + { + if(this->_id) dGeomDestroy(this->_id); + _id = dCreatePlane(space.Id(), a, b, c, d); + } + + + //CreateCCylinder + void Geom::CreateCCylinder(Space &space, double radius, double length) + { + if(this->_id) dGeomDestroy(this->_id); + _id = dCreateCCylinder(space.Id(), radius, length); + } + + + //SphereGetRadius + double Geom::SphereGetRadius(void) + { + return dGeomSphereGetRadius(this->_id); + } + + + //BoxGetLengths + Vector3 Geom::BoxGetLengths(void) + { + Vector3 retVal; + dVector3 temp; + dGeomBoxGetLengths(this->_id, temp); + retVal.x = temp[0]; + retVal.y = temp[1]; + retVal.z = temp[2]; + return retVal; + } + + + //PlaneGetParams + Vector4 Geom::PlaneGetParams(void) + { + Vector4 retVal; + dVector4 temp; + dGeomPlaneGetParams(this->_id, temp); + retVal.W = temp[0]; + retVal.x = temp[1]; + retVal.y = temp[2]; + retVal.z = temp[3]; + return retVal; + } + + + //CCylinderGetParams + void Geom::CCylinderGetParams(double *radius, double *length) + { + dGeomCCylinderGetParams(this->_id, radius, length); + } + + + //GetClass + int Geom::GetClass(void) + { + return dGeomGetClass(this->_id); + } + +} + + + + + + + diff --git a/libraries/ode-0.9/contrib/DotNetManaged/Geom.h b/libraries/ode-0.9/contrib/DotNetManaged/Geom.h new file mode 100644 index 0000000000..83a6faf705 --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/Geom.h @@ -0,0 +1,75 @@ +#pragma once + +#include "Body.h" +#include "Space.h" +#include "CommonMgd.h" + +namespace ODEManaged +{ + __gc public class Geom + { + public: + + + //Constructor + + Geom (void); + + + //Destructor + + ~Geom (void); + + + //Methods + + //Basic Stuff + + dGeomID Id (void); + dBodyID GetBody (void); + + //Overloaded SetBody + void SetBody (Body &body); + /*void SetBody (dBodyID b);*/ + + Vector3 GetPosition (void); + void SetPosition (double x, double y, double z); + + Matrix3 GetRotation (void); + void SetRotation (Matrix3 rotation); + + void SetData (void *data); + void *GetData (void); + + + //Create Objects + + void CreateSphere (Space &space, double radius); + void CreateBox (Space &space, double lx, double ly, double lz); + void CreatePlane (Space &space, double a, double b, double c, double d); + void CreateCCylinder (Space &space, double radius, double length); + + + //Destroy Objects + + void Destroy (void); + + + //Get Object's Parameters + + double SphereGetRadius (void); + Vector3 BoxGetLengths (void); + Vector4 PlaneGetParams (void); + void CCylinderGetParams (double *radius, double *length); + int GetClass (void); + + + //Properties + + private: + + dGeomID _id; + + }; + +} diff --git a/libraries/ode-0.9/contrib/DotNetManaged/Joint.cpp b/libraries/ode-0.9/contrib/DotNetManaged/Joint.cpp new file mode 100644 index 0000000000..e2d8de697d --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/Joint.cpp @@ -0,0 +1,35 @@ +#include "StdAfx.h" + +#include +#include "joint.h" +#include "CommonMgd.h" +#include "world.h" + +namespace ODEManaged +{ + + //Constructor + + Joint::Joint(void) + { + _id=0; + } + + + //Destructor + + Joint::~Joint(void) + { + dJointDestroy(this->_id); + } + + + //Methods + + //Id + dJointID Joint::Id(void) + { + return _id; + } + +} diff --git a/libraries/ode-0.9/contrib/DotNetManaged/Joint.h b/libraries/ode-0.9/contrib/DotNetManaged/Joint.h new file mode 100644 index 0000000000..d9ab254d37 --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/Joint.h @@ -0,0 +1,21 @@ +#pragma once + +#include "JointGroup.h" +#include "World.h" +#include "Body.h" + +namespace ODEManaged +{ + __gc public class Joint + { + protected: + //Constructor and Destructor Defenition + Joint(void); + ~Joint(void); + + //Public Methods + dJointID Id(void); + + dJointID _id; + }; +} diff --git a/libraries/ode-0.9/contrib/DotNetManaged/JointAMotor.cpp b/libraries/ode-0.9/contrib/DotNetManaged/JointAMotor.cpp new file mode 100644 index 0000000000..c5a4543ca5 --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/JointAMotor.cpp @@ -0,0 +1,162 @@ +#include "StdAfx.h" + +#include +#include "JointAMotor.h" + +namespace ODEManaged +{ + + //Constructors + + JointAMotor::JointAMotor(void) : Joint(){} + + + JointAMotor::JointAMotor(World &world) + { + if(this->_id) dJointDestroy(this->_id); + _id = dJointCreateAMotor(world.Id(), 0); + } + + + JointAMotor::JointAMotor(World &world, JointGroup &jointGroup) + { + if(this->_id) dJointDestroy(this->_id); + _id = dJointCreateAMotor(world.Id(), jointGroup.Id()); + } + + + //Destructor + + JointAMotor::~JointAMotor(void){} + + + //Methods + + //Overloaded Create + void JointAMotor::Create(World &world, JointGroup &jointGroup) + { + if(this->_id) dJointDestroy(this->_id); + _id = dJointCreateAMotor(world.Id(), jointGroup.Id()); + } + + void JointAMotor::Create(World &world) + { + if(this->_id) dJointDestroy(this->_id); + _id = dJointCreateAMotor(world.Id(), 0); + } + + + //Overloaded Attach + void JointAMotor::Attach(Body &body1, Body &body2) + { + dJointAttach(this->_id, body1.Id(), body2.Id()); + } + + void JointAMotor::Attach(Body &body1) + { + dJointAttach(this->_id, body1.Id(), 0); + } + + + //SetNumAxes + + void JointAMotor::SetNumAxes(int num) + { + dJointSetAMotorNumAxes(this->_id, num); + } + + + //GetNumAxes + + int JointAMotor::GetNumAxes(void) + { + return dJointGetAMotorNumAxes(this->_id); + } + + + //SetAxis + + void JointAMotor::SetAxis(int anum, int rel, double x, double y ,double z) + { + dJointSetAMotorAxis(this->_id, anum, rel, x, y, z); + } + + + //GetAxis + + Vector3 JointAMotor::GetAxis(int anum) + { + Vector3 retVal; + dVector3 temp; + dJointGetAMotorAxis(this->_id, anum, temp); + retVal.x = temp[0]; + retVal.y = temp[1]; + retVal.z = temp[2]; + return retVal; + } + + + //SetAngle + + void JointAMotor::SetAngle(int anum, double angle) + { + dJointSetAMotorAngle(this->_id, anum, angle); + } + + + //GetAngle + + double JointAMotor::GetAngle(int anum) + { + return dJointGetAMotorAngle(this->_id, anum); + } + + + //SetParam + + void JointAMotor::SetParam(int parameter, double value) + { + dJointSetAMotorParam(this->_id, parameter, value); + } + + + //GetParam + + double JointAMotor::GetParam(int parameter) + { + return dJointGetAMotorParam(this->_id, parameter); + } + + + //SetMode + + void JointAMotor::SetMode(int mode) + { + dJointSetAMotorMode(this->_id, mode); + } + + + //GetMode + + int JointAMotor::GetMode(void) + { + return dJointGetAMotorMode(this->_id); + } + + + //GetAxisRel + + int JointAMotor::GetAxisRel(int anum) + { + return dJointGetAMotorAxisRel(this->_id, anum); + } + + + //GetAngleRate + + double JointAMotor::GetAngleRate(int anum) + { + return dJointGetAMotorAngleRate(this->_id, anum); + } + +} diff --git a/libraries/ode-0.9/contrib/DotNetManaged/JointAMotor.h b/libraries/ode-0.9/contrib/DotNetManaged/JointAMotor.h new file mode 100644 index 0000000000..aa3ca4b9c1 --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/JointAMotor.h @@ -0,0 +1,62 @@ +#pragma once + +#include "Joint.h" + +namespace ODEManaged +{ + __gc public class JointAMotor : public Joint + { + public: + + + //Constructors + + JointAMotor (void); + JointAMotor (World &world); + JointAMotor (World &world, JointGroup &jointGroup); + + + //Destructor + + virtual ~JointAMotor (void); + + + //Methods + + //Basic Stuff + + //Overloaded Create + void Create (World &world, JointGroup &jointGroup); + void Create (World &world); + + void SetNumAxes (int num); + int GetNumAxes (void); + + void SetAxis (int anum, int rel, double x, double y, double z); + Vector3 GetAxis (int anum); + + void SetAngle (int anum, double angle); + double GetAngle (int anum); + + void SetMode (int mode); + int GetMode (void); + + int GetAxisRel (int anum); + double GetAngleRate (int anum); + + //Overloaded Attach + void Attach (Body &body1, Body &body2); + void Attach (Body &body1); + + + //Movement Parameters + + void SetParam (int parameter, double value); + double GetParam (int parameter); + + + + + + }; +} diff --git a/libraries/ode-0.9/contrib/DotNetManaged/JointBall.cpp b/libraries/ode-0.9/contrib/DotNetManaged/JointBall.cpp new file mode 100644 index 0000000000..d9336c9da6 --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/JointBall.cpp @@ -0,0 +1,79 @@ +#include "StdAfx.h" + +#include +#include "jointball.h" + +namespace ODEManaged +{ + + //Constructors + + JointBall::JointBall(void) : Joint(){} + + + JointBall::JointBall(World &world) + { + if(this->_id) dJointDestroy(this->_id); + _id = dJointCreateBall(world.Id(), 0); + } + + + JointBall::JointBall(World &world, JointGroup &jointGroup) + { + if(this->_id) dJointDestroy(this->_id); + _id = dJointCreateBall(world.Id(), jointGroup.Id()); + } + + + //Destructor + + JointBall::~JointBall(void){} + + + //Methods + + //Overloaded Create + void JointBall::Create(World &world, JointGroup &jointGroup) + { + if(this->_id) dJointDestroy(this->_id); + _id = dJointCreateBall(world.Id(), jointGroup.Id()); + } + + void JointBall::Create(World &world) + { + if(this->_id) dJointDestroy(this->_id); + _id = dJointCreateBall(world.Id(), 0); + } + + + //Overloaded Attach + void JointBall::Attach(Body &body1, Body &body2) + { + dJointAttach(this->_id, body1.Id(), body2.Id()); + } + + void JointBall::Attach(Body &body1) + { + dJointAttach(this->_id, body1.Id(), 0); + } + + + //SetAnchor + void JointBall::SetAnchor(double x, double y ,double z) + { + dJointSetBallAnchor(this->_id, x, y, z); + } + + //GetAnchor + Vector3 JointBall::GetAnchor(void) + { + Vector3 retVal; + dVector3 temp; + dJointGetBallAnchor(this->_id,temp); + retVal.x = temp[0]; + retVal.y = temp[1]; + retVal.z = temp[2]; + return retVal; + } + +} diff --git a/libraries/ode-0.9/contrib/DotNetManaged/JointBall.h b/libraries/ode-0.9/contrib/DotNetManaged/JointBall.h new file mode 100644 index 0000000000..2355bddaf5 --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/JointBall.h @@ -0,0 +1,38 @@ +#pragma once + +#include "Joint.h" + +namespace ODEManaged +{ + __gc public class JointBall : public Joint + { + public: + + //Constructors + + JointBall(void); + JointBall(World &world); + JointBall(World &world, JointGroup &jointGroup); + + + //Destructors + + virtual ~JointBall(void); + + + //Methods + + //Overloaded Create + void Create(World &world, JointGroup &jointGroup); + void Create(World &world); + + //Overloaded Attach + void Attach(Body &body1, Body &body2); + void Attach(Body &body1); + + void SetAnchor(double x, double y, double z); + Vector3 GetAnchor(void); + + }; + +} diff --git a/libraries/ode-0.9/contrib/DotNetManaged/JointFixed.cpp b/libraries/ode-0.9/contrib/DotNetManaged/JointFixed.cpp new file mode 100644 index 0000000000..afe922257e --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/JointFixed.cpp @@ -0,0 +1,67 @@ +#include "StdAfx.h" + +#include +#include "jointfixed.h" + +namespace ODEManaged +{ + + //Constructors + + JointFixed::JointFixed(void) : Joint(){} + + + JointFixed::JointFixed(World &world) + { + if(this->_id) dJointDestroy(this->_id); + _id = dJointCreateFixed(world.Id(),0); + } + + + JointFixed::JointFixed(World &world, JointGroup &jointGroup) + { + if(this->_id) dJointDestroy(this->_id); + _id = dJointCreateFixed(world.Id(), jointGroup.Id()); + } + + + //Destructor + + JointFixed::~JointFixed(void){} + + + //Methods + + //Overloaded Create + void JointFixed::Create(World &world, JointGroup &jointGroup) + { + if(this->_id) dJointDestroy(this->_id); + _id = dJointCreateFixed(world.Id(), jointGroup.Id()); + } + + void JointFixed::Create(World &world) + { + if(this->_id) dJointDestroy(this->_id); + _id = dJointCreateFixed(world.Id(), 0); + } + + + //Overloaded Attach + void JointFixed::Attach(Body &body1, Body &body2) + { + dJointAttach(this->_id, body1.Id(), body2.Id()); + } + + void JointFixed::Attach(Body &body1) + { + dJointAttach(this->_id, body1.Id(), 0); + } + + + //Fixed + void JointFixed::SetFixed(void) + { + dJointSetFixed(this->_id); + } + +} diff --git a/libraries/ode-0.9/contrib/DotNetManaged/JointFixed.h b/libraries/ode-0.9/contrib/DotNetManaged/JointFixed.h new file mode 100644 index 0000000000..5ca50dc772 --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/JointFixed.h @@ -0,0 +1,37 @@ +#pragma once + +#include "Joint.h" + +namespace ODEManaged +{ + __gc public class JointFixed : public Joint + { + public: + + //Constructors + + JointFixed(void); + JointFixed(World &world); + JointFixed(World &world, JointGroup &jointGroup); + + + //Destructor + + virtual ~JointFixed(void); + + + //Methods + + //Overloaded Create + void Create(World &world, JointGroup &jointGroup); + void Create(World &world); + + //Overloaded Attach + void Attach(Body &body1, Body &body2); + void Attach(Body &body1); + + void SetFixed(void); + + }; + +} diff --git a/libraries/ode-0.9/contrib/DotNetManaged/JointGroup.cpp b/libraries/ode-0.9/contrib/DotNetManaged/JointGroup.cpp new file mode 100644 index 0000000000..925751ffd6 --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/JointGroup.cpp @@ -0,0 +1,53 @@ +#include "StdAfx.h" + +#include +#include "jointgroup.h" + +namespace ODEManaged +{ + + //Constructors + + JointGroup::JointGroup(void) + { + _id=0; + } + + JointGroup::JointGroup (int maxSize) + { + _id = dJointGroupCreate(maxSize); + } + + + //Destructor + + JointGroup::~JointGroup(void) + { + dJointGroupDestroy(this->_id); + } + + + //Methods + + //ID + dJointGroupID JointGroup::Id() + { + return _id; + } + + + //Create + void JointGroup::Create (int maxSize) + { + if(_id) dJointGroupDestroy(_id); + _id = dJointGroupCreate(maxSize); + } + + + //Empty + void JointGroup::Empty (void) + { + dJointGroupEmpty(this->_id); + } + +} diff --git a/libraries/ode-0.9/contrib/DotNetManaged/JointGroup.h b/libraries/ode-0.9/contrib/DotNetManaged/JointGroup.h new file mode 100644 index 0000000000..b62ced0f64 --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/JointGroup.h @@ -0,0 +1,33 @@ +#pragma once + +namespace ODEManaged +{ + __gc public class JointGroup + { + public: + + //Constructors + + JointGroup(void); + JointGroup(int maxSize); + + + //Destructor + + ~JointGroup(void); + + + //Methods + + dJointGroupID Id(void); + void Create(int maxSize); + void Empty(void); + + + private: + + dJointGroupID _id; + + }; + +} diff --git a/libraries/ode-0.9/contrib/DotNetManaged/JointHinge.cpp b/libraries/ode-0.9/contrib/DotNetManaged/JointHinge.cpp new file mode 100644 index 0000000000..85d420bdff --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/JointHinge.cpp @@ -0,0 +1,121 @@ +#include "stdafx.h" + +#include +#include "jointhinge.h" + +namespace ODEManaged +{ + + //Constructors + + JointHinge::JointHinge(void) : Joint(){} + + + JointHinge::JointHinge(World &world) + { + if(this->_id) dJointDestroy(this->_id); + _id = dJointCreateHinge(world.Id(), 0); + } + + + JointHinge::JointHinge(World &world, JointGroup &jointGroup) + { + if(this->_id) dJointDestroy(this->_id); + _id = dJointCreateHinge(world.Id(), jointGroup.Id()); + } + + + //Destructor + + JointHinge::~JointHinge(void){} + + + //Methods + + //Overloaded Create + void JointHinge::Create(World &world, JointGroup &jointGroup) + { + if(this->_id) dJointDestroy(this->_id); + _id = dJointCreateHinge(world.Id(), jointGroup.Id()); + } + + void JointHinge::Create(World &world) + { + if(this->_id) dJointDestroy(this->_id); + _id = dJointCreateHinge(world.Id(), 0); + } + + + //Overloaded Attach + void JointHinge::Attach(Body &body1, Body &body2) + { + dJointAttach(this->_id, body1.Id(), body2.Id()); + } + + void JointHinge::Attach(Body &body1) + { + dJointAttach(this->_id, body1.Id(), 0); + } + + + //SetAxis + void JointHinge::SetAxis(double x, double y, double z) + { + dJointSetHingeAxis(this->_id, x, y, z); + } + + //GetAxis + Vector3 JointHinge::GetAxis(void) + { + Vector3 retVal; + dVector3 temp; + dJointGetHingeAxis(this->_id, temp); + retVal.x = temp[0]; + retVal.y = temp[1]; + retVal.z = temp[2]; + return retVal; + } + + + //SetAnchor + void JointHinge::SetAnchor(double x, double y, double z) + { + dJointSetHingeAnchor(this->_id, x, y, z); + } + + //GetAnchor + Vector3 JointHinge::GetAnchor(void) + { + Vector3 retVal; + dVector3 temp; + dJointGetHingeAnchor(this->_id, temp); + retVal.x = temp[0]; + retVal.y = temp[1]; + retVal.z = temp[2]; + return retVal; + } + + + //Movement Parameters + + //SetAllMovParams + void JointHinge::SetAllMovParams(double LoStop, double HiStop, + double Velocity, double MaxForce, + double FudgeFactor, double Bounce, + double StopERP, double StopCFM) + { + if (LoStop > -3.141592653 && LoStop <= 0) + dJointSetHingeParam(this->_id, dParamLoStop, LoStop); + + if (HiStop < 3.141592653 && HiStop >= 0) + dJointSetHingeParam(this->_id, dParamHiStop, HiStop); + + dJointSetHingeParam(this->_id, dParamVel, Velocity); + dJointSetHingeParam(this->_id, dParamFMax, MaxForce); + dJointSetHingeParam(this->_id, dParamFudgeFactor, FudgeFactor); + dJointSetHingeParam(this->_id, dParamBounce, Bounce); + dJointSetHingeParam(this->_id, dParamStopERP, StopERP); + dJointSetHingeParam(this->_id, dParamStopCFM, StopCFM); + } + +} diff --git a/libraries/ode-0.9/contrib/DotNetManaged/JointHinge.h b/libraries/ode-0.9/contrib/DotNetManaged/JointHinge.h new file mode 100644 index 0000000000..3115845fb8 --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/JointHinge.h @@ -0,0 +1,195 @@ +#pragma once + +#include "Joint.h" +#include "CommonMgd.h" + +namespace ODEManaged +{ + __gc public class JointHinge : public Joint + { + public: + + //Constructors + + JointHinge(void); + JointHinge(World &world); + JointHinge(World &world, JointGroup &jointGroup); + + + //Destructor + + virtual~JointHinge(void); + + + //Methods + + //Overloaded Create + void Create(World &world, JointGroup &jointGroup); + void Create(World &world); + + //Overloaded Attach + void Attach(Body &body1, Body &body2); + void Attach(Body &body1); + + void SetAnchor(double x, double y, double z); + Vector3 GetAnchor(void); + + void SetAxis(double x, double y, double z); + Vector3 GetAxis(void); + + void SetAllMovParams(double LoStop, double HiStop, + double Velocity, double MaxForce, + double FudgeFactor, double Bounce, + double StopERP, double StopCFM); + + + //Properties + + //LoStop + __property double get_LoStop(void) + { + return dJointGetHingeParam(this->_id, dParamLoStop); + } + + __property void set_LoStop(double value) + { + if (value > -3.141592653 && value <= 0) + dJointSetHingeParam(this->_id, dParamLoStop, value); + } + + + //HiStop + __property double get_HiStop(void) + { + return dJointGetHingeParam(this->_id, dParamHiStop); + } + + __property void set_HiStop(double value) + { + if (value < 3.141592653 && value >= 0) + dJointSetHingeParam(this->_id, dParamHiStop, value); + } + + + //Velocity + __property double get_Velocity(void) + { + return dJointGetHingeParam(this->_id, dParamVel); + } + + __property void set_Velocity(double value) + { + dJointSetHingeParam(this->_id, dParamVel, value); + } + + + //MaxForce + __property double get_MaxForce(void) + { + return dJointGetHingeParam(this->_id, dParamFMax); + } + + __property void set_MaxForce(double value) + { + dJointSetHingeParam(this->_id, dParamFMax, value); + } + + + //FudgeFactor + __property double get_FudgeFactor(void) + { + return dJointGetHingeParam(this->_id, dParamFudgeFactor); + } + + __property void set_FudgeFactor(double value) + { + dJointSetHingeParam(this->_id, dParamFudgeFactor, value); + } + + + //Bounce + __property double get_Bounce(void) + { + return dJointGetHingeParam(this->_id, dParamBounce); + } + + __property void set_Bounce(double value) + { + dJointSetHingeParam(this->_id, dParamBounce, value); + } + + + //StopERP + __property double get_StopERP(void) + { + return dJointGetHingeParam(this->_id, dParamStopERP); + } + + __property void set_StopERP(double value) + { + dJointSetHingeParam(this->_id, dParamStopERP, value); + } + + + //StopCFM + __property double get_StopCFM(void) + { + return dJointGetHingeParam(this->_id, dParamStopCFM); + } + + __property void set_StopCFM(double value) + { + dJointSetHingeParam(this->_id, dParamStopCFM, value); + } + + + //GetAngle + __property double get_Angle(void) + { + return dJointGetHingeAngle(this->_id); + } + + + //GetAngleRate + __property double get_AngleRate(void) + { + return dJointGetHingeAngleRate(this->_id); + } + + }; + +} + +// void SetSuspensionERP(double value); +// double GetSuspensionERP(void); + +// void SetSuspensionCFM(double value); +// double GetSuspensionCFM(void); + +/* + //SetSuspensionERP + void JointHinge::SetSuspensionERP(double value) + { + dJointSetHingeParam(this->_id, dParamSuspensionERP, value); + } + + //GetSuspensionERP + double JointHinge::GetSuspensionERP(void) + { + return dJointGetHingeParam(this->_id, dParamSuspensionERP); + } + + + //SetSuspensionCFM + void JointHinge::SetSuspensionCFM(double value) + { + dJointSetHingeParam(this->_id, dParamSuspensionCFM, value); + } + + //GetSuspensionCFM + double JointHinge::GetSuspensionCFM(void) + { + return dJointGetHingeParam(this->_id, dParamSuspensionCFM); + } + +*/ diff --git a/libraries/ode-0.9/contrib/DotNetManaged/JointHinge2.cpp b/libraries/ode-0.9/contrib/DotNetManaged/JointHinge2.cpp new file mode 100644 index 0000000000..94fd7a7b47 --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/JointHinge2.cpp @@ -0,0 +1,133 @@ +#include "StdAfx.h" + +#include +#include "jointhinge2.h" + +namespace ODEManaged +{ + //Constructors + JointHinge2::JointHinge2(void) : Joint(){} + + JointHinge2::JointHinge2(World &world) + { + if(this->_id) dJointDestroy(this->_id); + _id = dJointCreateHinge2(world.Id(),0); + } + + JointHinge2::JointHinge2(World &world, JointGroup &jointGroup) + { + if(this->_id) dJointDestroy(this->_id); + _id = dJointCreateHinge2(world.Id(), jointGroup.Id()); + } + + //Destructor + JointHinge2::~JointHinge2(void){} + + //CreateHinge2 (overload 1) + void JointHinge2::Create(World &world, JointGroup &jointGroup) + { + if(this->_id) dJointDestroy(this->_id); + _id = dJointCreateHinge2(world.Id(), jointGroup.Id()); + } + + //CreateHinge2 (overload 2) + void JointHinge2::Create(World &world) + { + if(this->_id) dJointDestroy(this->_id); + _id = dJointCreateHinge2(world.Id(),0); + } + + //SetAnchor1 + void JointHinge2::SetAnchor (double x, double y ,double z) + { + dJointSetHinge2Anchor(_id, x,y,z); + } + + //GetAnchor1 + Vector3 JointHinge2::GetAnchor() + { + Vector3 retVal; + dVector3 temp; + dJointGetHinge2Anchor(_id,temp); + retVal.x = temp[0]; + retVal.y = temp[1]; + retVal.z = temp[2]; + return retVal; + } + + //SetAxis1 + void JointHinge2::SetAxis1 (double x, double y ,double z) + { + dJointSetHinge2Axis1(_id, x,y,z); + } + + //GetAxis1 + Vector3 JointHinge2::GetAxis1() + { + Vector3 retVal; + dVector3 temp; + dJointGetHinge2Axis1(_id,temp); + retVal.x = temp[0]; + retVal.y = temp[1]; + retVal.z = temp[2]; + return retVal; + } + + //SetAxis2 + void JointHinge2::SetAxis2 (double x, double y ,double z) + { + dJointSetHinge2Axis2(_id, x,y,z); + } + + //GetAxis2 + Vector3 JointHinge2::GetAxis2() + { + Vector3 retVal; + dVector3 temp; + dJointGetHinge2Axis2(_id,temp); + retVal.x = temp[0]; + retVal.y = temp[1]; + retVal.z = temp[2]; + return retVal; + } + + //GetAngle1 + double JointHinge2::GetAngle1 () + { + return dJointGetHinge2Angle1(this->_id); + } + + //GetAngle1Rate + double JointHinge2::GetAngle1Rate () + { + return dJointGetHinge2Angle1Rate(this->_id); + } + + ////GetAngle hmm, this doesn't exist + //double JointHinge2::GetAngle2 () + //{ + // return dJointGetHinge2Angle2(this->_id); + //} + + //GetAngle2Rate + double JointHinge2::GetAngle2Rate () + { + return dJointGetHinge2Angle2Rate(this->_id); + } + + + //Attach (overload 1) + void JointHinge2::Attach (Body &body1, Body &body2) + { + dJointAttach(_id, body1.Id(),body2.Id()); + } + + //Attach (overload 2) + //TODO: possibly add an overload that takes anchor as a param also. + void JointHinge2::Attach (Body &body1) + { + dJointAttach(_id, body1.Id(),0); + } + + +} diff --git a/libraries/ode-0.9/contrib/DotNetManaged/JointHinge2.h b/libraries/ode-0.9/contrib/DotNetManaged/JointHinge2.h new file mode 100644 index 0000000000..e883ea820c --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/JointHinge2.h @@ -0,0 +1,48 @@ +#pragma once + +#include "Joint.h" +#include "CommonMgd.h" + +namespace ODEManaged +{ + __gc public class JointHinge2 : public Joint + { + public: + + + //Constructors + + JointHinge2 (void); + JointHinge2 (World &world); + JointHinge2 (World &world, JointGroup &jointGroup); + + //Destructors + + virtual ~JointHinge2 (void); + + + //Methods + + //Overloaded Hinge.Create + void Create (World &world, JointGroup &jointGroup); + void Create (World &world); + + void SetAnchor (double x, double y, double z); + Vector3 GetAnchor (void); + + void SetAxis1 (double x, double y, double z); + Vector3 GetAxis1 (void); + + void SetAxis2 (double x, double y, double z); + Vector3 GetAxis2 (void); + + double GetAngle1 (void); + double GetAngle1Rate (void); + + //double GetAngle2 (void); + double GetAngle2Rate (void); + + void Attach (Body &body1, Body &body2); + void Attach( Body &body1); + }; +} diff --git a/libraries/ode-0.9/contrib/DotNetManaged/JointSlider.cpp b/libraries/ode-0.9/contrib/DotNetManaged/JointSlider.cpp new file mode 100644 index 0000000000..ab7ebd6965 --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/JointSlider.cpp @@ -0,0 +1,102 @@ +#include "StdAfx.h" + +#include +#include "jointslider.h" + +namespace ODEManaged +{ + + //Constructors + + JointSlider::JointSlider(void) : Joint(){} + + + JointSlider::JointSlider(World &world) + { + if(this->_id) dJointDestroy(this->_id); + _id = dJointCreateSlider(world.Id(), 0); + } + + + JointSlider::JointSlider(World &world, JointGroup &jointGroup) + { + if(this->_id) dJointDestroy(this->_id); + _id = dJointCreateSlider(world.Id(), jointGroup.Id()); + } + + + //Destructor + + JointSlider::~JointSlider(void){} + + + //Methods + + //Overloaded Create + void JointSlider::Create(World &world, JointGroup &jointGroup) + { + if(this->_id) dJointDestroy(this->_id); + _id = dJointCreateSlider(world.Id(), jointGroup.Id()); + } + + void JointSlider::Create(World &world) + { + if(this->_id) dJointDestroy(this->_id); + _id = dJointCreateSlider(world.Id(), 0); + } + + + //Overloaded Attach + void JointSlider::Attach(Body &body1, Body &body2) + { + dJointAttach(this->_id, body1.Id(), body2.Id()); + } + + void JointSlider::Attach(Body &body1) + { + dJointAttach(this->_id, body1.Id(), 0); + } + + + //SetAxis + void JointSlider::SetAxis(double x, double y, double z) + { + dJointSetSliderAxis(this->_id, x, y, z); + } + + //GetAxis + Vector3 JointSlider::GetAxis(void) + { + Vector3 retVal; + dVector3 temp; + dJointGetSliderAxis(this->_id, temp); + retVal.x = temp[0]; + retVal.y = temp[1]; + retVal.z = temp[2]; + return retVal; + } + + + //Movement Parameters + + //SetAllMovParams + void JointSlider::SetAllMovParams(double LoStop, double HiStop, + double Velocity, double MaxForce, + double FudgeFactor, double Bounce, + double StopERP, double StopCFM) + { + if (LoStop <= 0) + dJointSetHingeParam(this->_id, dParamLoStop, LoStop); + + if (HiStop >= 0) + dJointSetHingeParam(this->_id, dParamHiStop, HiStop); + + dJointSetSliderParam(this->_id, dParamVel, Velocity); + dJointSetSliderParam(this->_id, dParamFMax, MaxForce); + dJointSetSliderParam(this->_id, dParamFudgeFactor, FudgeFactor); + dJointSetSliderParam(this->_id, dParamBounce, Bounce); + dJointSetSliderParam(this->_id, dParamStopERP, StopERP); + dJointSetSliderParam(this->_id, dParamStopCFM, StopCFM); + } + +} diff --git a/libraries/ode-0.9/contrib/DotNetManaged/JointSlider.h b/libraries/ode-0.9/contrib/DotNetManaged/JointSlider.h new file mode 100644 index 0000000000..7e96e5974b --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/JointSlider.h @@ -0,0 +1,158 @@ +#pragma once + +#include "Joint.h" +#include "CommonMgd.h" + +namespace ODEManaged +{ + __gc public class JointSlider : public Joint + { + public: + + + //Constructors + + JointSlider(void); + JointSlider(World &world); + JointSlider(World &world, JointGroup &jointGroup); + + + //Destructors + + virtual ~JointSlider(void); + + + //Methods + + //Overloaded Create + void Create(World &world, JointGroup &jointGroup); + void Create(World &world); + + //Overloaded Attach + void Attach(Body &body1, Body &body2); + void Attach(Body &body1); + + void SetAxis(double x, double y, double z); + Vector3 GetAxis(void); + + void SetAllMovParams(double LoStop, double HiStop, + double Velocity, double MaxForce, + double FudgeFactor, double Bounce, + double StopERP, double StopCFM); + + + //Properties + + //LoStop + __property double get_LoStop(void) + { + return dJointGetSliderParam(this->_id, dParamLoStop); + } + + __property void set_LoStop(double value) + { + if (value <=0) + dJointSetSliderParam(this->_id, dParamLoStop, value); + } + + + //HiStop + __property double get_HiStop(void) + { + return dJointGetSliderParam(this->_id, dParamHiStop); + } + + __property void set_HiStop(double value) + { + if (value >= 0) + dJointSetSliderParam(this->_id, dParamHiStop, value); + } + + + //Velocity + __property double get_Velocity(void) + { + return dJointGetSliderParam(this->_id, dParamVel); + } + + __property void set_Velocity(double value) + { + dJointSetSliderParam(this->_id, dParamVel, value); + } + + + //MaxForce + __property double get_MaxForce(void) + { + return dJointGetSliderParam(this->_id, dParamFMax); + } + + __property void set_MaxForce(double value) + { + dJointSetSliderParam(this->_id, dParamFMax, value); + } + + + //FudgeFactor + __property double get_FudgeFactor(void) + { + return dJointGetSliderParam(this->_id, dParamFudgeFactor); + } + + __property void set_FudgeFactor(double value) + { + dJointSetSliderParam(this->_id, dParamFudgeFactor, value); + } + + + //Bounce + __property double get_Bounce(void) + { + return dJointGetSliderParam(this->_id, dParamBounce); + } + + __property void set_Bounce(double value) + { + dJointSetSliderParam(this->_id, dParamBounce, value); + } + + + //StopERP + __property double get_StopERP(void) + { + return dJointGetSliderParam(this->_id, dParamStopERP); + } + + __property void set_StopERP(double value) + { + dJointSetSliderParam(this->_id, dParamStopERP, value); + } + + + //StopCFM + __property double get_StopCFM(void) + { + return dJointGetSliderParam(this->_id, dParamStopCFM); + } + + __property void set_StopCFM(double value) + { + dJointSetSliderParam(this->_id, dParamStopCFM, value); + } + + + //GetAngle + __property double get_Position(void) + { + return dJointGetSliderPosition(this->_id); + } + + + //GetAngleRate + __property double get_PositionRate(void) + { + return dJointGetSliderPositionRate(this->_id); + } + + }; +} diff --git a/libraries/ode-0.9/contrib/DotNetManaged/Release/ode.dll b/libraries/ode-0.9/contrib/DotNetManaged/Release/ode.dll new file mode 100755 index 0000000000..ccf2a41263 Binary files /dev/null and b/libraries/ode-0.9/contrib/DotNetManaged/Release/ode.dll differ diff --git a/libraries/ode-0.9/contrib/DotNetManaged/Space.cpp b/libraries/ode-0.9/contrib/DotNetManaged/Space.cpp new file mode 100644 index 0000000000..c9a7e190f6 --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/Space.cpp @@ -0,0 +1,53 @@ +#include "StdAfx.h" + +#include +#include "Space.h" +#include "TEST.h" + +namespace ODEManaged +{ + + //Constructor + + Space::Space(void) + { + _id = dSimpleSpaceCreate(); + } + + Space::Space(int minlevel, int maxlevel) + { + _id = dHashSpaceCreate(); + dHashSpaceSetLevels(this->_id, minlevel, maxlevel); + } + + + //Destructor + + Space::~Space(void) + { + dSpaceDestroy(this->_id); + } + + + //Methods + + //Id + dSpaceID Space::Id() + { + return _id; + } + + + //Collide + void Space::Collide(void *data, dNearCallback *callback) + { + dSpaceCollide(this->_id, data, callback); + } + + + + + + + +} diff --git a/libraries/ode-0.9/contrib/DotNetManaged/Space.h b/libraries/ode-0.9/contrib/DotNetManaged/Space.h new file mode 100644 index 0000000000..78e81ad64e --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/Space.h @@ -0,0 +1,33 @@ +#pragma once + +#include "CommonMgd.h" + +namespace ODEManaged +{ + __gc public class Space + { + public: + + //Constructor + + Space(void); + Space(int minlevel, int maxlevel); + + //Destructor + + ~Space(void); + + + //Methods + + dSpaceID Id(void); + void Collide(void *data, dNearCallback *callback); + + + private: + + dSpaceID _id; + + }; + +} diff --git a/libraries/ode-0.9/contrib/DotNetManaged/Stdafx.cpp b/libraries/ode-0.9/contrib/DotNetManaged/Stdafx.cpp new file mode 100644 index 0000000000..b6c9d98811 --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/Stdafx.cpp @@ -0,0 +1,5 @@ +// stdafx.cpp : source file that includes just the standard includes +// ODEManaged.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" diff --git a/libraries/ode-0.9/contrib/DotNetManaged/Stdafx.h b/libraries/ode-0.9/contrib/DotNetManaged/Stdafx.h new file mode 100644 index 0000000000..22227596cd --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/Stdafx.h @@ -0,0 +1,12 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, +// but are changed infrequently + +#pragma once + +#using + + + + + diff --git a/libraries/ode-0.9/contrib/DotNetManaged/TEST.h b/libraries/ode-0.9/contrib/DotNetManaged/TEST.h new file mode 100644 index 0000000000..e2cdbc36c2 --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/TEST.h @@ -0,0 +1,17 @@ + +#pragma once + +#include "CommonMgd.h" + +namespace ODEManaged +{ + +void RnearCallback(void *data, dGeomID o1, dGeomID o2) + { + } + +} + + + + diff --git a/libraries/ode-0.9/contrib/DotNetManaged/World.cpp b/libraries/ode-0.9/contrib/DotNetManaged/World.cpp new file mode 100644 index 0000000000..beab21a4c5 --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/World.cpp @@ -0,0 +1,74 @@ +#include "StdAfx.h" + +#include +#include "World.h" + +namespace ODEManaged +{ + + //Constructor + + World::World(void) + { + /*dWorldID _temp = dWorldCreate(); + _id = _temp;*/ + _id = dWorldCreate(); + } + + + //Destructor + + World::~World(void) + { + dWorldDestroy(this->_id); + } + + + //Methods + + //Id + dWorldID World::Id() + { + return _id; + } + + + //SetGravity + void World::SetGravity(double x, double y, double z) + { + dWorldSetGravity(this->_id, x, y, z); + } + + + //Overloaded GetGravity + Vector3 World::GetGravity(void) + { + Vector3 retVal; + dVector3 temp; + dWorldGetGravity(this->_id, temp); + retVal.x = temp[0]; + retVal.y = temp[1]; + retVal.z = temp[2]; + return retVal; + } + + void World::GetGravity(double gravity __gc[]) + { + dVector3 temp; + dWorldGetGravity(this->_id, temp); + gravity[0] = temp[0]; + gravity[1] = temp[1]; + gravity[2] = temp[2]; + } + + + //Step + void World::Step(double stepSize) + { + dWorldStep(this->_id, stepSize); + } + +} + + + diff --git a/libraries/ode-0.9/contrib/DotNetManaged/World.h b/libraries/ode-0.9/contrib/DotNetManaged/World.h new file mode 100644 index 0000000000..c4c60e5438 --- /dev/null +++ b/libraries/ode-0.9/contrib/DotNetManaged/World.h @@ -0,0 +1,67 @@ +#pragma once + +#include "CommonMgd.h" + +namespace ODEManaged +{ + __gc public class World + { + public: + + //Constructor + + World(void); + + + //Destructor + + ~World(void); + + + // Methods + + dWorldID Id(void); + + void SetGravity(double x, double y, double z); + + //Overloaded GetGravity + Vector3 GetGravity(void); + void GetGravity(double gravity __gc[]); + + void Step(double stepSize); + + + //Properties + + //Constraint Force Mixing + __property void set_CFM(double cfm) + { + dWorldSetCFM(this->_id,cfm); + } + + __property double get_CFM(void) + { + return dWorldGetCFM(this->_id); + } + + + //Error Reduction Parameter + __property void set_ERP(double erp) + { + dWorldSetERP(this->_id,erp); + } + + __property double get_ERP(void) + { + return dWorldGetERP(this->_id); + } + + + private: + + dWorldID _id; + + }; + +} + diff --git a/libraries/ode-0.9/contrib/GeomTransformGroup/GeomTransformGroup.cpp b/libraries/ode-0.9/contrib/GeomTransformGroup/GeomTransformGroup.cpp new file mode 100644 index 0000000000..26b77b0401 --- /dev/null +++ b/libraries/ode-0.9/contrib/GeomTransformGroup/GeomTransformGroup.cpp @@ -0,0 +1,218 @@ + +/* ************************************************************************ */ +/* + grouped and transformed geometry functions + author: Tim Schmidt tisch@uni-paderborn.de +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "objects.h" +#include "array.h" +#include "geom_internal.h" + +// given a pointer `p' to a dContactGeom, return the dContactGeom at +// p + skip bytes. + +#define CONTACT(p,skip) ((dContactGeom*) (((char*)p) + (skip))) + + +// ############################################################################ + +int dGeomTransformGroupClass = -1; +// ############################################################################ + +struct dxGeomTransformGroup { + dArray parts; // all the geoms that make up the group + dVector3 relativePosition; + dMatrix3 relativeRotation; +}; +// ############################################################################ + +void dGeomTransformGroupSetRelativePosition (dxGeom *g, dReal x, dReal y, dReal z) +{ + dAASSERT (g); + dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g); + transformGroup->relativePosition[0] = x; + transformGroup->relativePosition[1] = y; + transformGroup->relativePosition[2] = z; +} +// ############################################################################ + +void dGeomTransformGroupSetRelativeRotation (dxGeom *g, const dMatrix3 R) +{ + dAASSERT (g); + dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g); + memcpy (transformGroup->relativeRotation,R,sizeof(dMatrix3)); +} +// ############################################################################ + +const dReal * dGeomTransformGroupGetRelativePosition (dxGeom *g) +{ + dAASSERT (g); + dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g); + return transformGroup->relativePosition; +} +// ############################################################################ + +const dReal * dGeomTransformGroupGetRelativeRotation (dxGeom *g) +{ + dAASSERT (g); + dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g); + return transformGroup->relativeRotation; +} +// ############################################################################ + +static void computeFinalTransformation (const dxGeom *tg, const dxGeom *part) +{ + dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(tg); + dMULTIPLY0_331 (part->pos,tg->R,transformGroup->relativePosition); + part->pos[0] += tg->pos[0]; + part->pos[1] += tg->pos[1]; + part->pos[2] += tg->pos[2]; + dMULTIPLY0_333 (part->R,tg->R,transformGroup->relativeRotation); +} +// ############################################################################ + +int dCollideTransformGroup (const dxGeom *o1, const dxGeom *o2, int flags, + dContactGeom *contact, int skip) +{ + dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(o1); + if (transformGroup->parts.size() == 0) + { + return 0; + } + int numleft = flags & NUMC_MASK; + if (numleft == 0) numleft = 1; + flags &= ~NUMC_MASK; + int num=0, i=0; + while (i < transformGroup->parts.size() && numleft > 0) + { + dUASSERT (transformGroup->parts[i]->spaceid==0, + "GeomTransformGroup encapsulated object must not be in a space"); + dUASSERT (transformGroup->parts[i]->body==0, + "GeomTransformGroup encapsulated object must not be attached to a body"); + if (!o1->space_aabb) + { + computeFinalTransformation (o1, transformGroup->parts[i]); + } + dxBody *bodyBackup = transformGroup->parts[i]->body; + transformGroup->parts[i]->body = o1->body; + int n = dCollide (transformGroup->parts[i],const_cast(o2), + flags | numleft,contact,skip); + transformGroup->parts[i]->body = bodyBackup; + contact = CONTACT (contact,skip*n); + numleft -= n; + num += n; + i++; + } + return num; +} +// ############################################################################ + +static dColliderFn * dGeomTransformGroupColliderFn (int num) +{ + return (dColliderFn *) &dCollideTransformGroup; +} +// ############################################################################ + +static void dGeomTransformGroupAABB (dxGeom *geom, dReal aabb[6]) +{ + dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(geom); + aabb[0] = dInfinity; + aabb[1] = -dInfinity; + aabb[2] = dInfinity; + aabb[3] = -dInfinity; + aabb[4] = dInfinity; + aabb[5] = -dInfinity; + int i,j; + for (i=0; i < transformGroup->parts.size(); i++) + { + computeFinalTransformation (geom, transformGroup->parts[i]); + dReal aabb2[6]; + transformGroup->parts[i]->_class->aabb (transformGroup->parts[i],aabb2); + for (j=0; j<6; j += 2) if (aabb2[j] < aabb[j]) aabb[j] = aabb2[j]; + for (j=1; j<6; j += 2) if (aabb2[j] > aabb[j]) aabb[j] = aabb2[j]; + } +} +// ############################################################################ + +static void dGeomTransformGroupDtor (dxGeom *geom) +{ + dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(geom); + transformGroup->parts.~dArray(); +} +// ############################################################################ + +dxGeom *dCreateGeomTransformGroup (dSpaceID space) +{ + if (dGeomTransformGroupClass == -1) { + dGeomClass c; + c.bytes = sizeof (dxGeomTransformGroup); + c.collider = &dGeomTransformGroupColliderFn; + c.aabb = &dGeomTransformGroupAABB; + c.aabb_test = 0; + c.dtor = dGeomTransformGroupDtor; + dGeomTransformGroupClass = dCreateGeomClass (&c); + } + dxGeom *g = dCreateGeom (dGeomTransformGroupClass); + if (space) + { + dSpaceAdd (space,g); + } + dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g); + transformGroup->parts.constructor(); + dSetZero (transformGroup->relativePosition,4); + dRSetIdentity (transformGroup->relativeRotation); + return g; +} +// ############################################################################ + +void dGeomTransformGroupAddGeom (dxGeom *g, dxGeom *obj) +{ + dUASSERT (g && g->_class->num == dGeomTransformGroupClass, + "argument not a geom TransformGroup"); + dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g); + transformGroup->parts.push (obj); +} +// ############################################################################ + +void dGeomTransformGroupRemoveGeom (dxGeom *g, dxGeom *obj) +{ + dUASSERT (g && g->_class->num == dGeomTransformGroupClass, + "argument not a geom TransformGroup"); + dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g); + for (int i=0; i < transformGroup->parts.size(); i++) { + if (transformGroup->parts[i] == obj) { + transformGroup->parts.remove (i); + return; + } + } +} +// ############################################################################ + +dxGeom * dGeomTransformGroupGetGeom (dxGeom *g, int i) +{ + dUASSERT (g && g->_class->num == dGeomTransformGroupClass, + "argument not a geom TransformGroup"); + dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g); + dAASSERT (i >= 0 && i < transformGroup->parts.size()); + return transformGroup->parts[i]; +} +// ############################################################################ + +int dGeomTransformGroupGetNumGeoms (dxGeom *g) +{ + dUASSERT (g && g->_class->num == dGeomTransformGroupClass, + "argument not a geom TransformGroup"); + dxGeomTransformGroup *transformGroup = (dxGeomTransformGroup*) CLASSDATA(g); + return transformGroup->parts.size(); +} diff --git a/libraries/ode-0.9/contrib/GeomTransformGroup/GeomTransformGroup.h b/libraries/ode-0.9/contrib/GeomTransformGroup/GeomTransformGroup.h new file mode 100644 index 0000000000..705fdb9218 --- /dev/null +++ b/libraries/ode-0.9/contrib/GeomTransformGroup/GeomTransformGroup.h @@ -0,0 +1,29 @@ + +/* ************************************************************************ */ +/* + grouped and transformed geometry functions + author: Tim Schmidt tisch@uni-paderborn.de +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + +extern int dGeomTransformGroupClass; + +void dGeomTransformGroupSetRelativePosition (dGeomID g, dReal x, dReal y, dReal z); +void dGeomTransformGroupSetRelativeRotation (dGeomID g, const dMatrix3 R); +const dReal * dGeomTransformGroupGetRelativePosition (dxGeom *g); +const dReal * dGeomTransformGroupGetRelativeRotation (dxGeom *g); +dGeomID dCreateGeomTransformGroup (dSpaceID space); +void dGeomTransformGroupAddGeom (dGeomID tg, dGeomID obj); +void dGeomTransformGroupRemoveGeom (dGeomID tg, dGeomID obj); +dGeomID dGeomTransformGroupGetGeom (dGeomID tg, int i); +int dGeomTransformGroupGetNumGeoms (dGeomID tg); + + +#ifdef __cplusplus +} +#endif diff --git a/libraries/ode-0.9/contrib/GeomTransformGroup/README.txt b/libraries/ode-0.9/contrib/GeomTransformGroup/README.txt new file mode 100644 index 0000000000..bca0e6652b --- /dev/null +++ b/libraries/ode-0.9/contrib/GeomTransformGroup/README.txt @@ -0,0 +1,148 @@ +README for GeomTransformGroup by Tim Schmidt. +--------------------------------------------- + +This is a patch to add the dGeomTransformGroup object to the list of geometry +objects. + +It should work with the cvs version of the ode library from 07/24/2002. + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +comment by russ smith: this code is easy to use with the rest of ODE. +simply copy GeomTransformGroup.cpp to ode/src and copy GeomTransformGroup.h +to include/ode. then add GeomTransformGroup.cpp to the ODE_SRC variable +in the makefile. rebuild, and you're done! of course i could have done all +this for you, but i prefer to keep GeomTransformGroup separated from the +rest of ODE for now while other issues with the collision system are +resolved. + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + +Description: + +The dGeomTransformGroup is an adaption of the TransformGroup known from +Java3D (and maybe other libraries with a similar scene graph representation). +It can be used to build an arbitrarily structured tree of objects that are +each positioned relative to the particular parent node. + +If you have a plane for example, there is one root node associated with the +plane's body and another three transformgroups placed 'under' this node. One +with the fuselage (cappedcylinder) under it and two with the underlying wings +(flat boxes). And if you want to add engines, simply put them 'next to' the +wings under another two transformgroups. + +bodyTG ---> associated with dBody + | + +--fuselageTG + | | + | +--fuselageCylinder + | + +--leftwingTG + | | + | +--wingBox + | | + | +--leftengineTG + | | + | +--leftengineCylinder + | + +--rightwingTG + | + +--wingBox + | + +--rightengineTG + | + +--rightengineCylinder + +This is a method to easily compose objects without the necessity of always +calculating global coordinates. But apart from this there is something else +that makes dGeomTransformGroups very valuable. + +Maybe you remember that some users reported the problem of acquiring the +correct bodies to be attached by a contactjoint in the nearCallback when +using dGeomGroups and dGeomTransforms at the same time. This results from the +fact that dGeomGroups are not associated with bodies while all other +geometries are. + +So, as you can see in the nearCallback of the the test_buggy demo you have to +attach the contactjoint with the bodies that you get from the geometries that +are stored in the contact struct (-> dGeomGetBody(contacts[i].geom.g1)). +Normally you would do this by asking o1 and o2 directly with dGeomGetBody(o1) +and dGeomGetBody(o2) respectively. + +As a first approach you can overcome that problem by testing o1 and o2 if +they are groups or not to find out how to get the corresponding bodies. + +However this will fail if you want grouped transforms that are constructed +out of dGeomTransforms encapsulated in a dGeomGroup. According to the test +you use contacts[i].geom.g1 to get the right body. Unfortunately g1 is +encapsulated in a transform and therefore not attached to any body. In this +case the dGeomTransform 'in the middle' would have been the right object to +be asked for the body. + +You may now conclude that it is a good idea to unwrap the group encapsulated +geoms at the beginning of the nearcallback and use dGeomGetBody(o1) +consistently. But keep in mind that this also means not to invoke +dCollide(..) on groups at all and therefore not to expoit the capability of +dGeomGroups to speed up collision detection by the creation of bounding boxes +around the encapsulated geometry. + +Everything becomes even worse if you create a dGeomTransform that contains a +dGeomGroup of geoms. The function that cares about the collision of +transforms with other objects uses the position and rotation of the +respective encapsulated object to compute its final position and orientation. +Unfortunately dGeomGroups do not have a position and rotation, so the result +will not be what you have expected. + +Here the dGeomTransformGroups comes into operation, because it combines the +advantages and capabilities of the dGeomGroup and the dGeomTransform. +And as an effect of synergy it is now even possible to set the position of a +group of geoms with one single command. +Even nested encapsulations of dGeomTransformGroups in dGeomTransformGroups +should be possible (to be honest, I have not tried that so far ;-) ). + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +API: + +dGeomID dCreateGeomTransformGroup (dSpaceID space); + - create a GeomTransformGroup + +void dGeomTransformGroupAddGeom (dGeomID tg, dGeomID obj); + - Comparable to dGeomTransformSetGeom or dGeomGroupAdd + - add objects to this group + +void dGeomTransformGroupRemoveGeom (dGeomID tg, dGeomID obj); + - remove objects from this group + +void dGeomTransformGroupSetRelativePosition + (dGeomID g, dReal x, dReal y, dReal z); +void dGeomTransformGroupSetRelativeRotation + (dGeomID g, const dMatrix3 R); + - Comparable to setting the position and rotation of all the + dGeomTransform encapsulated geometry. The difference + is that it is global with respect to this group and therefore + affects all geoms in this group. + - The relative position and rotation are attributes of the + transformgroup, so the position and rotation of the individual + geoms are not changed + +const dReal * dGeomTransformGroupGetRelativePosition (dGeomID g); +const dReal * dGeomTransformGroupGetRelativeRotation (dGeomID g); + - get the relative position and rotation + +dGeomID dGeomTransformGroupGetGeom (dGeomID tg, int i); + - Comparable to dGeomGroupGetGeom + - get a specific geom of the group + +int dGeomTransformGroupGetNumGeoms (dGeomID tg); + - Comparable to dGeomGroupGetNumGeoms + - get the number of geoms in the group + + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Tim Schmidt +student of computer science +University of Paderborn, Germany +tisch@uni-paderborn.de diff --git a/libraries/ode-0.9/contrib/Mac_CFMCarbon/CW7_projects.sit.bin b/libraries/ode-0.9/contrib/Mac_CFMCarbon/CW7_projects.sit.bin new file mode 100644 index 0000000000..c06768c899 Binary files /dev/null and b/libraries/ode-0.9/contrib/Mac_CFMCarbon/CW7_projects.sit.bin differ diff --git a/libraries/ode-0.9/contrib/Mac_CFMCarbon/README.txt b/libraries/ode-0.9/contrib/Mac_CFMCarbon/README.txt new file mode 100644 index 0000000000..7c1f8a4489 --- /dev/null +++ b/libraries/ode-0.9/contrib/Mac_CFMCarbon/README.txt @@ -0,0 +1,95 @@ +----------------------------- +ODE - Mac CFM Carbon Port +(contact Frank Condello with questions regarding this port) + +Although ODE contains a MacOSX makefile, and some individuals have implemented ODE in +Cocoa, I opted to use (and prefer) CodeWarrior. This also opens up ODE to MacOS8 & 9 +users, without scarfing functionality in MacOSX (same binaries run on both platforms). + +The 'ode_CW7.mcp' project contains release and debug targets to create static ODE and +DrawStuff libraries. + +'examples_CW7.mcp' contains targets for the entire ODE test suite, plus a couple other +test programs which were posted to the ODE mailing list. + + +----------------------------- +Compiling Notes: + +You'll need to extract the CodeWarrior projects from the 'CW7_projects.sit.bin' archive +(They're nearly a meg uncompressed so this was done to be bandwith friendly on the CVS). + +Projects require CodeWarrior 7 or above (recreating them with earlier versions shouldn't +be too difficult). The projects use relative paths and are meant to be compiled from +'contrib/Mac_CFMCarbon/'. Don't move them! + +All the libraries build into the 'lib/' directory, all test applications build into +'contrib/Mac_CFMCarbon/mac_testbin/' (and must be run from that directory since the +texture path is hard-coded). + +You'll need to compile the release ODE library, and the DrawStuff library before +compiling the examples. + +The ODE 'configurator' has not been ported, but a Mac-friendly 'config.h' header has been +manually hacked together (all PPC Macs should be fine with this header). Single or double +precision can be defined in the 'CommonPrefix.h' header found in +'contrib/Mac_CFMCarbon/mac_source/'. + +'contrib/Mac_CFMCarbon/mac_source/' also contains any mac specific additions to the main source. +The directory structure here matches the main source tree, and I would recommend that this +format is maintained when making additions, since the access paths are touchy (more below...) + +Some issues were encountered with duplicate header names. CodeWarrior tends to be +unforgiving about this sort of thing but fudging with the access paths eventually +cleared up the problem. If ODE fails to compile, make sure the and +"objects.h" or and are actually pointing to the correct header. + +You'll need Apple's OpenGL SDK (with GLUT) in your compiler path to build DrawStuff. I've +added redirection headers in 'contrib/Mac_CFMCarbon/mac_source/include/GL/' to properly +link with the Apple headers (since the projects are set to follow DOS paths). + +The examples link against a crapload of static libraries, but my initial builds using +ODE, MSL, GLUT, and DrawStuff shared/merged DLL's proved unstable (mostly problems with +SIOUX spawning multiple sessions, and crashes in Classic). Static libs just worked better +in the end, but the test apps are a little bloated as a result, and need to be re-linked +whenever a change to a library is made. + +IMPORTANT: You must use the same 'CommonPrefix.h' settings for libraries, and test apps +(i.e. double or single precision). + + +----------------------------- +Running the test apps: + +The test apps will show the SIOUX CLI prompt when run. Just hit OK to ignore it, or add any +DrawStuff arguments. You'll want to log output to a file for 'test_ode'. + +There are two extra test programs in the 'mac_source' directory. Both were posted to the ODE +mailing list by OSX users. 'test_stability1' visualizes some internal issues with ODE, and +'test_stacktest' is a standalone GLUT program (doesn't use DrawStuff) that can be useful +to stress test the library, and give you an idea of just how much stack memory you're +going to need for large systems. + +ISSUES: + +The carbon DrawStuff lib uses GLUT to make life easy, but GLUT isn't exactly bug-free +or stable on the Mac... Try moving the mouse around if a simulation is running slowly +on OS9 (it's not ODE's fault, but rather a poor carbon GLUT implementation - seems GLUT stalls +when it's not getting system events - I haven't seen this problem on OSX). + +The 3D view may not update if typing in the SIOUX console window. + +You cannot pass startup args to GLUT due to the way the DrawStuff library initializes. + +'Write Frames' doesn't actually do anything at the moment. + +The 'test_joints' app seems broken (though I don't know what the intended effect should be) + + +----------------------------- +TODO: + +- Re-add shared library targets (if stability issues are resolved). +- Implement 'Write Frames' in DrawStuff. +- Write a Carbon compatible configurator +- Create CodeWarrior 8 projects (once I scrounge up enough dough for the update). \ No newline at end of file diff --git a/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/CommonPrefix.h b/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/CommonPrefix.h new file mode 100644 index 0000000000..5948b3e324 --- /dev/null +++ b/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/CommonPrefix.h @@ -0,0 +1,6 @@ +#define TARGET_API_MAC_CARBON 1 +#define finite isfinite +#define dNODEBUG 1 + +// Comment out for single precision +#define PRECISION_DOUBLE 1 \ No newline at end of file diff --git a/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/DSPrefix.h b/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/DSPrefix.h new file mode 100644 index 0000000000..612252839f --- /dev/null +++ b/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/DSPrefix.h @@ -0,0 +1,6 @@ +#ifndef prefix_h +#define prefix_h + +#include "CommonPrefix.h" + +#endif // prefix_h \ No newline at end of file diff --git a/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/DebugPrefix.h b/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/DebugPrefix.h new file mode 100644 index 0000000000..0e328a9f79 --- /dev/null +++ b/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/DebugPrefix.h @@ -0,0 +1,10 @@ +#ifndef prefix_h +#define prefix_h + +#include "CommonPrefix.h" + +#ifdef dNODEBUG +#undef dNODEBUG +#endif + +#endif // prefix_h \ No newline at end of file diff --git a/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/ExamplesPrefix.h b/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/ExamplesPrefix.h new file mode 100644 index 0000000000..1dedfc93ac --- /dev/null +++ b/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/ExamplesPrefix.h @@ -0,0 +1,13 @@ +#ifndef prefix_h +#define prefix_h + +#include "CommonPrefix.h" + +// Hack to automatically call SIOUX's CLI interface for the test apps +#include +#include +int fmain (int argc, char **argv); +int main (int argc, char **argv) { argc = ccommand(&argv); return fmain(argc, argv); } +#define main(argc, argv) fmain(argc, argv) + +#endif // prefix_h \ No newline at end of file diff --git a/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/ODETestPrefix.h b/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/ODETestPrefix.h new file mode 100644 index 0000000000..f8f5022223 --- /dev/null +++ b/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/ODETestPrefix.h @@ -0,0 +1,13 @@ +#ifndef prefix_h +#define prefix_h + +#include "CommonPrefix.h" + +// Hack to automatically call SIOUX's CLI interface for the test apps +#include +#include +int fmain (); +int main (int argc, char **argv) { argc = ccommand(&argv); return fmain(); } +#define main() fmain() + +#endif // prefix_h \ No newline at end of file diff --git a/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/ReleasePrefix.h b/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/ReleasePrefix.h new file mode 100644 index 0000000000..612252839f --- /dev/null +++ b/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/ReleasePrefix.h @@ -0,0 +1,6 @@ +#ifndef prefix_h +#define prefix_h + +#include "CommonPrefix.h" + +#endif // prefix_h \ No newline at end of file diff --git a/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/drawstuff/src/mac_glut_carbon.cpp b/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/drawstuff/src/mac_glut_carbon.cpp new file mode 100644 index 0000000000..eb0b144f89 --- /dev/null +++ b/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/drawstuff/src/mac_glut_carbon.cpp @@ -0,0 +1,281 @@ +/************************************************************************* + * * + * DrawStuff Library, Copyright (C) 2001 Russell L. Smith. * + * Email: russ@q12.org Web: www.q12.org * + * * + * 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 (see the file LICENSE.TXT); if not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307 USA. * + * * + *************************************************************************/ + +// main window and event handling for Mac CFM Carbon + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include "internal.h" + + +//*************************************************************************** +// error handling for unix (works just fine with SIOUX) + +static void printMessage (char *msg1, 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 (char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + printMessage ("Error",msg,ap); + exit (1); +} + + +extern "C" void dsDebug (char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + printMessage ("INTERNAL ERROR",msg,ap); + // *((char *)0) = 0; ... commit SEGVicide ? + abort(); +} + +extern "C" void dsPrint (char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + vprintf (msg,ap); +} + +//*************************************************************************** +// openGL window + +// window and openGL +static int width=0,height=0; // window size +static int last_key_pressed=0; // last key pressed in the window +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 dsFunctions *gfn; +static int frame = 1; + +float getTime (void) +{ + UnsignedWide ms; + + Microseconds(&ms); + return ms.lo / 1000000.0; +} + + +static void captureFrame (int num) +{ +// TODO +} + +static void reshape(int w, int h) +{ + width = w; + height = h; +} + +static void draw(void) +{ + dsDrawFrame (width,height,gfn,pause && !singlestep); + singlestep = 0; + glutSwapBuffers(); + + if (pause==0 && writeframes) { + captureFrame (frame); + frame++; + } +} + +static void idle(void) +{ + static float lasttime=0; + float t; + + // Try to maintain a reasonable rate (good enough for testing anyway) + t = getTime(); + if (lasttime < t) { + lasttime = t+0.005; + draw(); + } +} + +static void key(unsigned char key, int x, int y) +{ + if (!glutGetModifiers()) { + + if (key >= ' ' && key <= 126 && gfn->command) gfn->command (key); + + // GLUT_ACTIVE_CTRL doesn't seem to be working, so we use Alt + } else if (glutGetModifiers()&GLUT_ACTIVE_ALT) { + + switch (key) { + case 't': case 'T': + dsSetTextures (dsGetTextures() ^ 1); + break; + case 's': case 'S': + dsSetShadows (dsGetShadows() ^ 1); + 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; + } + // No case 'X' - Quit works through the Mac system menu, or cmd-q + case 'w': case 'W': + writeframes ^= 1; + if (writeframes) printf ("Write frames not done yet!\n");// TODO + break; + } + } + + last_key_pressed = key; +} + +static int mx=0,my=0; // mouse position +static int mode = 0; // mouse button bits + +static void MouseDown(int button, int state, int x, int y) +{ + if(button == GLUT_LEFT_BUTTON) + { + if(state == GLUT_DOWN) + mode |= 1; + else if(state == GLUT_UP) + mode &= (~1); + } + else if (button == GLUT_MIDDLE_BUTTON) + { + if(state == GLUT_DOWN) + mode |= 3; + else if(state == GLUT_UP) + mode &= (~3); + } + else if (button == GLUT_RIGHT_BUTTON) + { + if(state == GLUT_DOWN) + mode |= 2; + else if(state == GLUT_UP) + mode &= (~2); + } + + mx = x; + my = y; +} + +static void MouseMove(int x, int y) +{ + dsMotion (mode, x - mx, y - my); + mx = x; + my = y; +} + +static void createMainWindow (int _width, int _height) +{ + // So GLUT doesn't complain + int argc = 0; + char **argv = NULL; + + // initialize variables + width = _width; + height = _height; + last_key_pressed = 0; + + if (width < 1 || height < 1) dsDebug (0,"bad window width or height"); + + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); + glutInitWindowSize(_width, _height); + glutInitWindowPosition(100, 100); + glutCreateWindow("ODE Simulation"); + + glutKeyboardFunc(key); + glutMotionFunc(MouseMove); + glutMouseFunc(MouseDown); + glutReshapeFunc(reshape); + glutDisplayFunc(idle); + glutIdleFunc(idle); +} + +void dsPlatformSimLoop (int window_width, int window_height, dsFunctions *fn, + int initial_pause) +{ + SIOUXSettings.initializeTB = false; + SIOUXSettings.standalone = false; + SIOUXSettings.setupmenus = false; + SIOUXSettings.autocloseonquit = true; + SIOUXSettings.asktosaveonclose = false; + + gfn = fn; + pause = initial_pause; + + printf ( + "\n" + "Simulation test environment v%d.%02d\n" + " Option-P : pause / unpause (or say `-pause' on command line).\n" + " Option-O : single step when paused.\n" + " Option-T : toggle textures (or say `-notex' on command line).\n" + " Option-S : toggle shadows (or say `-noshadow' on command line).\n" + " Option-V : print current viewpoint coordinates (x,y,z,h,p,r).\n" + " Option-W : write frames to ppm files: frame/frameNNN.ppm\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); + + createMainWindow (window_width, window_height); + dsStartGraphics (window_width,window_height,fn); + + if (fn->start) fn->start(); + + glutMainLoop(); + + if (fn->stop) fn->stop(); + dsStopGraphics(); +} + +extern "C" void dsStop(){ }// GLUT/MSL hooks into the system to exit diff --git a/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/include/GL/gl.h b/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/include/GL/gl.h new file mode 100644 index 0000000000..4acaeed7d8 --- /dev/null +++ b/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/include/GL/gl.h @@ -0,0 +1,2 @@ +// A little hackaround (Apple use / in the FILENAME, which doesn't work when following DOS paths) +#include \ No newline at end of file diff --git a/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/include/GL/glu.h b/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/include/GL/glu.h new file mode 100644 index 0000000000..5b4a791d41 --- /dev/null +++ b/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/include/GL/glu.h @@ -0,0 +1,2 @@ +// A little hackaround (Apple use / in the FILENAME, which doesn't work when following DOS paths) +#include \ No newline at end of file diff --git a/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/include/ode/config.h b/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/include/ode/config.h new file mode 100644 index 0000000000..bb889f9d4c --- /dev/null +++ b/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/include/ode/config.h @@ -0,0 +1,52 @@ +/* This file has been manually hacked together for the Mac CFM Carbon build - Frank. */ + +#ifndef _ODE_CONFIG_H_ +#define _ODE_CONFIG_H_ + +/* standard system headers */ +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* #define PENTIUM 1 -- not a pentium */ + +/* integer types (we assume int >= 32 bits) */ +typedef char int8; +typedef unsigned char uint8; +typedef int int32; +typedef unsigned int uint32; + +/* an integer type that we can safely cast a pointer to and from without loss of bits. */ +typedef unsigned int intP; + +#ifdef PRECISION_DOUBLE + + /*select the base floating point type*/ + #define dDOUBLE 1 + + /* the floating point infinity */ + #define dInfinity DBL_MAX + +#else + + /* select the base floating point type */ + #define dSINGLE 1 + + /* the floating point infinity */ + #define dInfinity FLT_MAX + +#endif + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/ode/test/test_stability1.cpp b/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/ode/test/test_stability1.cpp new file mode 100644 index 0000000000..79c066a5dc --- /dev/null +++ b/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/ode/test/test_stability1.cpp @@ -0,0 +1,289 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without 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 + +#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 dsDrawCappedCylinder dsDrawCappedCylinderD +#endif + + +// some constants + +#define DENSITY (5.0) // density of all objects + +// dynamics and collision objects + +struct MyObject { + dBodyID body; // the body + dGeomID geom; // geometry representing this body +}; + +static dWorldID world; +static dSpaceID space; +static MyObject fallingObject; +static dGeomID box1, box2; +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) +{ + 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 && dAreConnected (b1,b2)) return; + + dContact contact[4]; // up to 3 contacts per box + for (i=0; i<4; i++) { + contact[i].surface.mode = dContactBounce; //dContactMu2; + contact[i].surface.mu = dInfinity; + contact[i].surface.mu2 = 0; + contact[i].surface.bounce = 0.5; + contact[i].surface.bounce_vel = 0.1; + } + if (int numc = dCollide (o1,o2,4,&contact[0].geom,sizeof(dContact))) { + // dMatrix3 RI; + // dRSetIdentity (RI); + // const dReal ss[3] = {0.02,0.02,0.02}; + 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,k; + dReal sides[3]; + dMass m; + + cmd = locase (cmd); + if (cmd == 'b' || cmd == 's' || cmd == 'c') { + // Destroy the currently falling object and replace it by an instance of the requested type + if (fallingObject.body) { + dBodyDestroy (fallingObject.body); + dGeomDestroy (fallingObject.geom); + memset (&fallingObject, 0, sizeof(fallingObject)); + } + + fallingObject.body = dBodyCreate (world); + for (k=0; k<3; k++) sides[k] = dRandReal()*0.5+0.1; + + // Start out centered above the V-gap + dBodySetPosition (fallingObject.body, 0,0,5); + +#if 0 + dMatrix3 R; + dRFromAxisAndAngle (R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, + dRandReal()*2.0-1.0,dRandReal()*10.0-5.0); + dBodySetRotation (fallingObject.body,R); + dBodySetData (fallingObject.body,(void*) i); +#endif + + if (cmd == 'b') { + dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]); + fallingObject.geom = dCreateBox (space,sides[0],sides[1],sides[2]); + } + else if (cmd == 'c') { + sides[0] *= 0.5; + dMassSetCappedCylinder (&m,DENSITY,3,sides[0],sides[1]); + fallingObject.geom = dCreateCCylinder (space,sides[0],sides[1]); + } + else if (cmd == 's') { + sides[0] *= 0.5; + dMassSetSphere (&m,DENSITY,sides[0]); + fallingObject.geom = dCreateSphere (space,sides[0]); + } + + dGeomSetBody (fallingObject.geom,fallingObject.body); + + dBodySetMass (fallingObject.body,&m); + } +} + + +// draw a geom + +void drawGeom (dGeomID g, const dReal *pos, const dReal *R) +{ + 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 == dCCylinderClass) { + dReal radius,length; + dGeomCCylinderGetParams (g,&radius,&length); + dsDrawCappedCylinder (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); + } + */ +} + + +// simulation loop + +static void simLoop (int pause) +{ + dsSetColor (0,0,2); + dSpaceCollide (space,0,&nearCallback); + if (!pause) dWorldStep (world,0.0005); + + // remove all contact joints + dJointGroupEmpty (contactgroup); + + dsSetColor (1,1,0); + dsSetTexture (DS_WOOD); + + // draw the falling object + dsSetColor (1,0,0); + drawGeom (fallingObject.geom,0,0); + + // draw the constraining boxes + dsSetColor(0.8, 1, 0.8); + drawGeom (box1,0,0); + drawGeom (box2,0,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/textures"; + if(argc==2) + { + fn.path_to_textures = argv[1]; + } + + // create world + + world = dWorldCreate(); + space = dHashSpaceCreate(); + contactgroup = dJointGroupCreate (0); + dWorldSetGravity (world,0,0,-0.5); + dWorldSetCFM (world,1e-5); + dCreatePlane (space,0,0,1,0); + memset (&fallingObject,0,sizeof(fallingObject)); + + // Create two flat boxes, just slightly off vertical and a bit apart for stuff to fall in between. + // Don't create bodies for these boxes -- they'll be immovable instead. + { + dReal sides[3]; + dMatrix3 R; + + sides[0] = 4; + sides[1] = 0.2; + sides[2] = 3; + + box1 = dCreateBox (space,sides[0],sides[1],sides[2]); + dGeomSetPosition (box1, 0, sides[1], sides[2]/2); + dRFromAxisAndAngle (R, 1, 0, 0, -0.1); + dGeomSetRotation (box1, R); + + box2 = dCreateBox (space,sides[0],sides[1],sides[2]); + dGeomSetPosition (box2, 0, -sides[1], sides[2]/2); + dRFromAxisAndAngle (R, 1, 0, 0, 0.1); + dGeomSetRotation (box2, R); + } + + // Pretend to drop a box to start + command('b'); + + // run simulation + dsSimulationLoop (argc,argv,640,480,&fn); + + dJointGroupDestroy (contactgroup); + dSpaceDestroy (space); + dWorldDestroy (world); + + return 0; +} diff --git a/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/ode/test/test_stacktest.c b/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/ode/test/test_stacktest.c new file mode 100644 index 0000000000..e49fd73c39 --- /dev/null +++ b/libraries/ode-0.9/contrib/Mac_CFMCarbon/mac_source/ode/test/test_stacktest.c @@ -0,0 +1,197 @@ +#include +#include +#include "ode.h" + +#define NUMBODIES 80 + +#define USE_SPHERE 0 +#define USE_HELIX 1 +#define USE_TORQUE 1 +#define USE_WEIRD_MATRIX_OPS 0 + +#define CONTACTS 1 + +dWorldID aWorld; +dSpaceID aSpace; +float cycle = 0, fade; +dJointGroupID aContactGroup; +dBodyID bodies[NUMBODIES]; +dGeomID geoms[NUMBODIES]; +GLfloat colors[NUMBODIES][4]; +unsigned int contactsThisFrame; + +void kglTransformByODEGeom(dGeomID geom) { + const dReal *p = dGeomGetPosition(geom); + const dReal *R = dGeomGetRotation(geom); + GLdouble glm[16]; + + glm[0] = R[0]; glm[1] = R[4]; glm[2] = R[8]; glm[3] = 0; + glm[4] = R[1]; glm[5] = R[5]; glm[6] = R[9]; glm[7] = 0; + glm[8] = R[2]; glm[9] = R[6]; glm[10] = R[10];glm[11] = 0; + glm[12] = p[0]; glm[13] = p[1]; glm[14] = p[2]; glm[15] = 1; + + glMultMatrixd(glm); +} + +static void odeNearCallback(void *data, dGeomID g1, dGeomID g2) { + dBodyID b1 = dGeomGetBody(g1), + b2 = dGeomGetBody(g2); + dContact contact[CONTACTS]; + int contactsUsed, i; + + if (b1 && b2 && dAreConnected(b1, b2)) return; + + contactsUsed = dCollide(g1, g2, CONTACTS, &contact[0].geom, + sizeof(dContact)); + if (contactsUsed > CONTACTS) contactsUsed = CONTACTS; + + for (i = 0; i < contactsUsed; i++) { + contact[i].surface.mode = 0; + contact[i].surface.mu = 20.0; + + dJointAttach(dJointCreateContact(aWorld, aContactGroup, + &(contact[i])), b1, b2); + contactsThisFrame++; + } +} + +void myGlutResize(int w, int h) { + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(45.0, (GLfloat)w / h, 1.0, 120.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0, -6, -20); +} + +void myGlutIdle(void) { + const float step = 1.0/120; + int i; + + cycle = fmod(cycle + step / 4, 1); + fade = fabs(cycle * 2 - 1); + + contactsThisFrame = 0; + dSpaceCollide(aSpace, NULL, &odeNearCallback); + //printf("%u\n", contactsThisFrame); + dWorldStep(aWorld, step); + dJointGroupEmpty(aContactGroup); + + for (i = 0; i < NUMBODIES; i++) { + const dReal *cvel = dBodyGetLinearVel(bodies[i]); + dBodyAddForce(bodies[i], + -cvel[0] * 0.5, + -cvel[1] * 0.5, + -cvel[2] * 0.5 + ); + } + + glutPostRedisplay(); +} + +void myGlutDisplay(void) { + int i; + + glClearColor(fade * 0.15, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (USE_WEIRD_MATRIX_OPS) glPushMatrix(); + for (i = 0; i < NUMBODIES; i++) { + if (!USE_WEIRD_MATRIX_OPS) glPushMatrix(); + kglTransformByODEGeom(geoms[i]); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, colors[i]); + glColor3f(fade * 1.5, 0, 0); +#if USE_SPHERE + glRotatef(90, 1, 0, 0); + glutSolidSphere(0.5, 9, 6); + glDisable(GL_LIGHTING); + glutWireSphere(0.5, 9, 6); +#else + glutSolidCube(1); + glDisable(GL_LIGHTING); + glutWireCube(1); +#endif + glEnable(GL_LIGHTING); + if (!USE_WEIRD_MATRIX_OPS) glPopMatrix(); + } + if (USE_WEIRD_MATRIX_OPS) glPopMatrix(); + + glutSwapBuffers(); +} + +int main(int argc, char **argv) { + printf("Initializing GLUT\n"); + + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); + glutInitWindowSize(400, 300); + glutInitWindowPosition(100, 100); + glutCreateWindow("ODE Crash Test"); + + glutDisplayFunc(myGlutDisplay); + glutReshapeFunc(myGlutResize); + glutIdleFunc(myGlutIdle); + + glPolygonOffset(1, 1); + glDepthFunc(GL_LEQUAL); + glEnable(GL_POLYGON_OFFSET_FILL); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + myGlutResize(400, 300); + + printf("Creating ODE world\n"); + aWorld = dWorldCreate(); + aSpace = dHashSpaceCreate(); + aContactGroup = dJointGroupCreate(0); + dCreatePlane(aSpace, 0, 1, 0, 0); + dWorldSetGravity(aWorld, 0, -9.81, 0); + dWorldSetERP(aWorld, 0.4); + dWorldSetCFM(aWorld, 1e-10); + + printf("Creating objects\n"); + { + int i; + dMass mass; + + dMassSetBox(&mass, 1.0, 1, 1, 1); + + for (i = 0; i < NUMBODIES; i++) { + float fraction = (float)i / NUMBODIES; + + bodies[i] = dBodyCreate(aWorld); + dBodySetMass(bodies[i], &mass); +#if USE_SPHERE + geoms[i] = dCreateSphere(aSpace, 0.5); +#else + geoms[i] = dCreateBox(aSpace, 1, 1, 1); +#endif + dGeomSetBody(geoms[i], bodies[i]); + + if (USE_HELIX) { + float r = (i % 3 - 1) * (1.5+4*(1 - fraction)), + theta = (float)i / 4; + dBodySetPosition(bodies[i], + sin(theta) * r, + (float)i + 1, + cos(theta) * r + ); + } else { + dBodySetPosition(bodies[i], 0, (float)i * 2 + 1, 0); + } + if (USE_TORQUE) dBodyAddTorque(bodies[i], fraction*10, fraction*20, fraction*30); + + colors[i][0] = fraction; + colors[i][1] = 1 - fraction; + colors[i][2] = 1 - fabs(fraction * 2 - 1); + colors[i][3] = 1; + } + } + + printf("Starting simulation\n"); + glutMainLoop(); + + return 0; +} \ No newline at end of file diff --git a/libraries/ode-0.9/contrib/Ode.NET/Drawstuff/AssemblyInfo.cs b/libraries/ode-0.9/contrib/Ode.NET/Drawstuff/AssemblyInfo.cs new file mode 100644 index 0000000000..8d2b86a0a2 --- /dev/null +++ b/libraries/ode-0.9/contrib/Ode.NET/Drawstuff/AssemblyInfo.cs @@ -0,0 +1,18 @@ +using System; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("Drawstuff.NET")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Ode.NET")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: ComVisible(false)] +[assembly: Guid("b2a39dd4-dd67-4e8a-af70-d3b412da8850")] +[assembly: AssemblyVersion("0.7.0.0")] +[assembly: AssemblyFileVersion("0.7.0.0")] +[assembly: CLSCompliantAttribute(true)] diff --git a/libraries/ode-0.9/contrib/Ode.NET/Drawstuff/Drawstuff.cs b/libraries/ode-0.9/contrib/Ode.NET/Drawstuff/Drawstuff.cs new file mode 100644 index 0000000000..aa84966cca --- /dev/null +++ b/libraries/ode-0.9/contrib/Ode.NET/Drawstuff/Drawstuff.cs @@ -0,0 +1,58 @@ +using System; +using System.Runtime.InteropServices; +using Ode.NET; + +namespace Drawstuff.NET +{ +#if dDOUBLE + using dReal = System.Double; +#else + using dReal = System.Single; +#endif + + public static class ds + { + public const int VERSION = 2; + + public enum Texture + { + None, + Wood + } + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void CallbackFunction(int arg); + + [StructLayout(LayoutKind.Sequential)] + public struct Functions + { + public int version; + public CallbackFunction start; + public CallbackFunction step; + public CallbackFunction command; + public CallbackFunction stop; + public string path_to_textures; + } + + [DllImport("drawstuff", EntryPoint="dsDrawBox")] + public static extern void DrawBox(ref d.Vector3 pos, ref d.Matrix3 R, ref d.Vector3 sides); + + [DllImport("drawstuff", EntryPoint = "dsDrawCapsule")] + public static extern void DrawCapsule(ref d.Vector3 pos, ref d.Matrix3 R, dReal length, dReal radius); + + [DllImport("drawstuff", EntryPoint = "dsDrawConvex")] + public static extern void DrawConvex(ref d.Vector3 pos, ref d.Matrix3 R, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons); + + [DllImport("drawstuff", EntryPoint="dsSetColor")] + public static extern void SetColor(float red, float green, float blue); + + [DllImport("drawstuff", EntryPoint="dsSetTexture")] + public static extern void SetTexture(Texture texture); + + [DllImport("drawstuff", EntryPoint="dsSetViewpoint")] + public static extern void SetViewpoint(ref d.Vector3 xyz, ref d.Vector3 hpr); + + [DllImport("drawstuff", EntryPoint="dsSimulationLoop")] + public static extern void SimulationLoop(int argc, string[] argv, int window_width, int window_height, ref Functions fn); + } +} diff --git a/libraries/ode-0.9/contrib/Ode.NET/Drawstuff/premake.lua b/libraries/ode-0.9/contrib/Ode.NET/Drawstuff/premake.lua new file mode 100644 index 0000000000..d777ffba35 --- /dev/null +++ b/libraries/ode-0.9/contrib/Ode.NET/Drawstuff/premake.lua @@ -0,0 +1,19 @@ +package.name = "Drawstuff.NET" +package.kind = "dll" +package.language = "c#" + +if (options["with-doubles"]) then + package.defines = { "dDOUBLE" } +else + package.defines = { "dSINGLE " } +end + +package.links = { + "System", + "Ode.NET" +} + +package.files = { + "AssemblyInfo.cs", + "Drawstuff.cs" +} diff --git a/libraries/ode-0.9/contrib/Ode.NET/Ode/AssemblyInfo.cs b/libraries/ode-0.9/contrib/Ode.NET/Ode/AssemblyInfo.cs new file mode 100644 index 0000000000..6a8c2b67aa --- /dev/null +++ b/libraries/ode-0.9/contrib/Ode.NET/Ode/AssemblyInfo.cs @@ -0,0 +1,18 @@ +using System; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("Ode.NET")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Ode.NET")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: ComVisible(false)] +[assembly: Guid("1347a35e-c32b-4ff6-8064-7d10b2cc113b")] +[assembly: AssemblyVersion("0.7.0.0")] +[assembly: AssemblyFileVersion("0.7.0.0")] +[assembly: CLSCompliantAttribute(true)] diff --git a/libraries/ode-0.9/contrib/Ode.NET/Ode/Ode.cs b/libraries/ode-0.9/contrib/Ode.NET/Ode/Ode.cs new file mode 100644 index 0000000000..06038102aa --- /dev/null +++ b/libraries/ode-0.9/contrib/Ode.NET/Ode/Ode.cs @@ -0,0 +1,1732 @@ +using System; +using System.Runtime.InteropServices; +using System.Security; + +namespace Ode.NET +{ +#if dDOUBLE + using dReal = System.Double; +#else + using dReal = System.Single; +#endif + + public static class d + { + public static dReal Infinity = dReal.MaxValue; + + #region Flags and Enumerations + + [Flags] + public enum ContactFlags : int + { + Mu2 = 0x001, + FDir1 = 0x002, + Bounce = 0x004, + SoftERP = 0x008, + SoftCFM = 0x010, + Motion1 = 0x020, + Motion2 = 0x040, + Slip1 = 0x080, + Slip2 = 0x100, + Approx0 = 0x0000, + Approx1_1 = 0x1000, + Approx1_2 = 0x2000, + Approx1 = 0x3000 + } + + public enum GeomClassID : int + { + SphereClass, + BoxClass, + CapsuleClass, + CylinderClass, + PlaneClass, + RayClass, + ConvexClass, + GeomTransformClass, + TriMeshClass, + HeightfieldClass, + FirstSpaceClass, + SimpleSpaceClass = FirstSpaceClass, + HashSpaceClass, + QuadTreeSpaceClass, + LastSpaceClass = QuadTreeSpaceClass, + FirstUserClass, + LastUserClass = FirstUserClass + MaxUserClasses - 1, + NumClasses, + MaxUserClasses = 4 + } + + public enum JointType : int + { + None, + Ball, + Hinge, + Slider, + Contact, + Universal, + Hinge2, + Fixed, + Null, + AMotor, + LMotor, + Plane2D + } + + public enum JointParam : int + { + LoStop, + HiStop, + Vel, + FMax, + FudgeFactor, + Bounce, + CFM, + StopERP, + StopCFM, + SuspensionERP, + SuspensionCFM, + LoStop2 = 256, + HiStop2, + Vel2, + FMax2, + FudgeFactor2, + Bounce2, + CFM2, + StopERP2, + StopCFM2, + SuspensionERP2, + SuspensionCFM2, + LoStop3 = 512, + HiStop3, + Vel3, + FMax3, + FudgeFactor3, + Bounce3, + CFM3, + StopERP3, + StopCFM3, + SuspensionERP3, + SuspensionCFM3 + } + + #endregion + + #region Callbacks + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate int AABBTestFn(IntPtr o1, IntPtr o2, ref AABB aabb); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate int ColliderFn(IntPtr o1, IntPtr o2, int flags, out ContactGeom contact, int skip); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void GetAABBFn(IntPtr geom, out AABB aabb); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate ColliderFn GetColliderFnFn(int num); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void GeomDtorFn(IntPtr o); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate dReal HeightfieldGetHeight(IntPtr p_user_data, int x, int z); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void NearCallback(IntPtr data, IntPtr geom1, IntPtr geom2); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate int TriArrayCallback(IntPtr trimesh, IntPtr refObject, int[] triangleIndex, int triCount); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate int TriRayCallback(IntPtr trimesh, IntPtr ray, int triangleIndex, dReal u, dReal v); + + #endregion + + #region Structs + + [StructLayout(LayoutKind.Sequential)] + public struct AABB + { + public dReal MinX, MaxX; + public dReal MinY, MaxY; + public dReal MinZ, MaxZ; + } + + + [StructLayout(LayoutKind.Sequential)] + public struct Contact + { + public SurfaceParameters surface; + public ContactGeom geom; + public Vector3 fdir1; + } + + + [StructLayout(LayoutKind.Sequential)] + public struct ContactGeom + { + public static readonly int SizeOf = Marshal.SizeOf(typeof(ContactGeom)); + + public Vector3 pos; + public Vector3 normal; + public dReal depth; + public IntPtr g1; + public IntPtr g2; + public int side1; + public int side2; + } + + [StructLayout(LayoutKind.Sequential)] + public struct GeomClass + { + public int bytes; + public GetColliderFnFn collider; + public GetAABBFn aabb; + public AABBTestFn aabb_test; + public GeomDtorFn dtor; + } + + + [StructLayout(LayoutKind.Sequential)] + public struct JointFeedback + { + public Vector3 f1; + public Vector3 t1; + public Vector3 f2; + public Vector3 t2; + } + + + [StructLayout(LayoutKind.Sequential)] + public struct Mass + { + public dReal mass; + public Vector4 c; + public Matrix3 I; + } + + + [StructLayout(LayoutKind.Sequential)] + public struct Matrix3 + { + public Matrix3(dReal m00, dReal m10, dReal m20, dReal m01, dReal m11, dReal m21, dReal m02, dReal m12, dReal m22) + { + M00 = m00; M10 = m10; M20 = m20; _m30 = 0.0f; + M01 = m01; M11 = m11; M21 = m21; _m31 = 0.0f; + M02 = m02; M12 = m12; M22 = m22; _m32 = 0.0f; + } + public dReal M00, M10, M20; + private dReal _m30; + public dReal M01, M11, M21; + private dReal _m31; + public dReal M02, M12, M22; + private dReal _m32; + } + + [StructLayout(LayoutKind.Sequential)] + public struct Matrix4 + { + public Matrix4(dReal m00, dReal m10, dReal m20, dReal m30, + dReal m01, dReal m11, dReal m21, dReal m31, + dReal m02, dReal m12, dReal m22, dReal m32, + dReal m03, dReal m13, dReal m23, dReal m33) + { + M00 = m00; M10 = m10; M20 = m20; M30 = m30; + M01 = m01; M11 = m11; M21 = m21; M31 = m31; + M02 = m02; M12 = m12; M22 = m22; M32 = m32; + M03 = m03; M13 = m13; M23 = m23; M33 = m33; + } + public dReal M00, M10, M20, M30; + public dReal M01, M11, M21, M31; + public dReal M02, M12, M22, M32; + public dReal M03, M13, M23, M33; + } + + [StructLayout(LayoutKind.Sequential)] + public struct Quaternion + { + public dReal W, X, Y, Z; + } + + + [StructLayout(LayoutKind.Sequential)] + public struct SurfaceParameters + { + public ContactFlags mode; + public dReal mu; + public dReal mu2; + public dReal bounce; + public dReal bounce_vel; + public dReal soft_erp; + public dReal soft_cfm; + public dReal motion1; + public dReal motion2; + public dReal slip1; + public dReal slip2; + } + + + [StructLayout(LayoutKind.Sequential)] + public struct Vector3 + { + public Vector3(dReal x, dReal y, dReal z) + { + X = x; Y = y; Z = z; _w = 0.0f; + } + public dReal X, Y, Z; + private dReal _w; + } + + + [StructLayout(LayoutKind.Sequential)] + public struct Vector4 + { + public Vector4(dReal x, dReal y, dReal z, dReal w) + { + X = x; Y = y; Z = z; W = w; + } + public dReal X, Y, Z, W; + } + + #endregion + + [DllImport("ode", EntryPoint = "dAreConnected"), SuppressUnmanagedCodeSecurity] + public static extern bool AreConnected(IntPtr b1, IntPtr b2); + + [DllImport("ode", EntryPoint = "dAreConnectedExcluding"), SuppressUnmanagedCodeSecurity] + public static extern bool AreConnectedExcluding(IntPtr b1, IntPtr b2, JointType joint_type); + + [DllImport("ode", EntryPoint = "dBodyAddForce"), SuppressUnmanagedCodeSecurity] + public static extern void BodyAddForce(IntPtr body, dReal fx, dReal fy, dReal fz); + + [DllImport("ode", EntryPoint = "dBodyAddForceAtPos"), SuppressUnmanagedCodeSecurity] + public static extern void BodyAddForceAtPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); + + [DllImport("ode", EntryPoint = "dBodyAddForceAtRelPos"), SuppressUnmanagedCodeSecurity] + public static extern void BodyAddForceAtRelPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); + + [DllImport("ode", EntryPoint = "dBodyAddRelForce"), SuppressUnmanagedCodeSecurity] + public static extern void BodyAddRelForce(IntPtr body, dReal fx, dReal fy, dReal fz); + + [DllImport("ode", EntryPoint = "dBodyAddRelForceAtPos"), SuppressUnmanagedCodeSecurity] + public static extern void BodyAddRelForceAtPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); + + [DllImport("ode", EntryPoint = "dBodyAddRelForceAtRelPos"), SuppressUnmanagedCodeSecurity] + public static extern void BodyAddRelForceAtRelPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); + + [DllImport("ode", EntryPoint = "dBodyAddRelTorque"), SuppressUnmanagedCodeSecurity] + public static extern void BodyAddRelTorque(IntPtr body, dReal fx, dReal fy, dReal fz); + + [DllImport("ode", EntryPoint = "dBodyAddTorque"), SuppressUnmanagedCodeSecurity] + public static extern void BodyAddTorque(IntPtr body, dReal fx, dReal fy, dReal fz); + + [DllImport("ode", EntryPoint = "dBodyCopyPosition"), SuppressUnmanagedCodeSecurity] + public static extern void BodyCopyPosition(IntPtr body, out Vector3 pos); + + [DllImport("ode", EntryPoint = "dBodyCopyPosition"), SuppressUnmanagedCodeSecurity] + public static extern void BodyCopyPosition(IntPtr body, out dReal X); + + [DllImport("ode", EntryPoint = "dBodyCopyQuaternion"), SuppressUnmanagedCodeSecurity] + public static extern void BodyCopyQuaternion(IntPtr body, out Quaternion quat); + + [DllImport("ode", EntryPoint = "dBodyCopyQuaternion"), SuppressUnmanagedCodeSecurity] + public static extern void BodyCopyQuaternion(IntPtr body, out dReal X); + + [DllImport("ode", EntryPoint = "dBodyCopyRotation"), SuppressUnmanagedCodeSecurity] + public static extern void BodyCopyRotation(IntPtr body, out Matrix3 R); + + [DllImport("ode", EntryPoint = "dBodyCopyRotation"), SuppressUnmanagedCodeSecurity] + public static extern void BodyCopyRotation(IntPtr body, out dReal M00); + + [DllImport("ode", EntryPoint = "dBodyCreate"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr BodyCreate(IntPtr world); + + [DllImport("ode", EntryPoint = "dBodyDestroy"), SuppressUnmanagedCodeSecurity] + public static extern void BodyDestroy(IntPtr body); + + [DllImport("ode", EntryPoint = "dBodyDisable"), SuppressUnmanagedCodeSecurity] + public static extern void BodyDisable(IntPtr body); + + [DllImport("ode", EntryPoint = "dBodyEnable"), SuppressUnmanagedCodeSecurity] + public static extern void BodyEnable(IntPtr body); + + [DllImport("ode", EntryPoint = "dBodyGetAutoDisableAngularThreshold"), SuppressUnmanagedCodeSecurity] + public static extern dReal BodyGetAutoDisableAngularThreshold(IntPtr body); + + [DllImport("ode", EntryPoint = "dBodyGetAutoDisableFlag"), SuppressUnmanagedCodeSecurity] + public static extern bool BodyGetAutoDisableFlag(IntPtr body); + + [DllImport("ode", EntryPoint = "dBodyGetAutoDisableLinearThreshold"), SuppressUnmanagedCodeSecurity] + public static extern dReal BodyGetAutoDisableLinearThreshold(IntPtr body); + + [DllImport("ode", EntryPoint = "dBodyGetAutoDisableSteps"), SuppressUnmanagedCodeSecurity] + public static extern int BodyGetAutoDisableSteps(IntPtr body); + + [DllImport("ode", EntryPoint = "dBodyGetAutoDisableTime"), SuppressUnmanagedCodeSecurity] + public static extern dReal BodyGetAutoDisableTime(IntPtr body); + +#if !dNO_UNSAFE_CODE + [CLSCompliant(false)] + [DllImport("ode", EntryPoint = "dBodyGetAngularVel"), SuppressUnmanagedCodeSecurity] + public extern unsafe static Vector3* BodyGetAngularVelUnsafe(IntPtr body); + public static Vector3 BodyGetAngularVel(IntPtr body) + { + unsafe { return *(BodyGetAngularVelUnsafe(body)); } + } +#endif + + [DllImport("ode", EntryPoint = "dBodyGetData"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr BodyGetData(IntPtr body); + + [DllImport("ode", EntryPoint = "dBodyGetFiniteRotationMode"), SuppressUnmanagedCodeSecurity] + public static extern int BodyGetFiniteRotationMode(IntPtr body); + + [DllImport("ode", EntryPoint = "dBodyGetFiniteRotationAxis"), SuppressUnmanagedCodeSecurity] + public static extern void BodyGetFiniteRotationAxis(IntPtr body, out Vector3 result); + +#if !dNO_UNSAFE_CODE + [CLSCompliant(false)] + [DllImport("ode", EntryPoint = "dBodyGetForce"), SuppressUnmanagedCodeSecurity] + public extern unsafe static Vector3* BodyGetForceUnsafe(IntPtr body); + public static Vector3 BodyGetForce(IntPtr body) + { + unsafe { return *(BodyGetForceUnsafe(body)); } + } +#endif + + [DllImport("ode", EntryPoint = "dBodyGetGravityMode"), SuppressUnmanagedCodeSecurity] + public static extern bool BodyGetGravityMode(IntPtr body); + + [DllImport("ode", EntryPoint = "dBodyGetJoint"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr BodyGetJoint(IntPtr body, int index); + +#if !dNO_UNSAFE_CODE + [CLSCompliant(false)] + [DllImport("ode", EntryPoint = "dBodyGetLinearVel"), SuppressUnmanagedCodeSecurity] + public extern unsafe static Vector3* BodyGetLinearVelUnsafe(IntPtr body); + public static Vector3 BodyGetLinearVel(IntPtr body) + { + unsafe { return *(BodyGetLinearVelUnsafe(body)); } + } +#endif + + [DllImport("ode", EntryPoint = "dBodyGetMass"), SuppressUnmanagedCodeSecurity] + public static extern void BodyGetMass(IntPtr body, out Mass mass); + + [DllImport("ode", EntryPoint = "dBodyGetNumJoints"), SuppressUnmanagedCodeSecurity] + public static extern int BodyGetNumJoints(IntPtr body); + + [DllImport("ode", EntryPoint = "dBodyGetPointVel"), SuppressUnmanagedCodeSecurity] + public static extern void BodyGetPointVel(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); + +#if !dNO_UNSAFE_CODE + [CLSCompliant(false)] + [DllImport("ode", EntryPoint = "dBodyGetPosition"), SuppressUnmanagedCodeSecurity] + public extern unsafe static Vector3* BodyGetPositionUnsafe(IntPtr body); + public static Vector3 BodyGetPosition(IntPtr body) + { + unsafe { return *(BodyGetPositionUnsafe(body)); } + } +#endif + + [DllImport("ode", EntryPoint = "dBodyGetPosRelPoint"), SuppressUnmanagedCodeSecurity] + public static extern void BodyGetPosRelPoint(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); + +#if !dNO_UNSAFE_CODE + [CLSCompliant(false)] + [DllImport("ode", EntryPoint = "dBodyGetQuaternion"), SuppressUnmanagedCodeSecurity] + public extern unsafe static Quaternion* BodyGetQuaternionUnsafe(IntPtr body); + public static Quaternion BodyGetQuaternion(IntPtr body) + { + unsafe { return *(BodyGetQuaternionUnsafe(body)); } + } +#endif + + [DllImport("ode", EntryPoint = "dBodyGetRelPointPos"), SuppressUnmanagedCodeSecurity] + public static extern void BodyGetRelPointPos(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); + + [DllImport("ode", EntryPoint = "dBodyGetRelPointVel"), SuppressUnmanagedCodeSecurity] + public static extern void BodyGetRelPointVel(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); + +#if !dNO_UNSAFE_CODE + [CLSCompliant(false)] + [DllImport("ode", EntryPoint = "dBodyGetRotation"), SuppressUnmanagedCodeSecurity] + public extern unsafe static Matrix3* BodyGetRotationUnsafe(IntPtr body); + public static Matrix3 BodyGetRotation(IntPtr body) + { + unsafe { return *(BodyGetRotationUnsafe(body)); } + } +#endif + +#if !dNO_UNSAFE_CODE + [CLSCompliant(false)] + [DllImport("ode", EntryPoint = "dBodyGetTorque"), SuppressUnmanagedCodeSecurity] + public extern unsafe static Vector3* BodyGetTorqueUnsafe(IntPtr body); + public static Vector3 BodyGetTorque(IntPtr body) + { + unsafe { return *(BodyGetTorqueUnsafe(body)); } + } +#endif + + [DllImport("ode", EntryPoint = "dBodyIsEnabled"), SuppressUnmanagedCodeSecurity] + public static extern bool BodyIsEnabled(IntPtr body); + + [DllImport("ode", EntryPoint = "dBodySetAngularVel"), SuppressUnmanagedCodeSecurity] + public static extern void BodySetAngularVel(IntPtr body, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dBodySetAutoDisableAngularThreshold"), SuppressUnmanagedCodeSecurity] + public static extern void BodySetAutoDisableAngularThreshold(IntPtr body, dReal angular_threshold); + + [DllImport("ode", EntryPoint = "dBodySetAutoDisableDefaults"), SuppressUnmanagedCodeSecurity] + public static extern void BodySetAutoDisableDefaults(IntPtr body); + + [DllImport("ode", EntryPoint = "dBodySetAutoDisableFlag"), SuppressUnmanagedCodeSecurity] + public static extern void BodySetAutoDisableFlag(IntPtr body, bool do_auto_disable); + + [DllImport("ode", EntryPoint = "dBodySetAutoDisableLinearThreshold"), SuppressUnmanagedCodeSecurity] + public static extern void BodySetAutoDisableLinearThreshold(IntPtr body, dReal linear_threshold); + + [DllImport("ode", EntryPoint = "dBodySetAutoDisableSteps"), SuppressUnmanagedCodeSecurity] + public static extern void BodySetAutoDisableSteps(IntPtr body, int steps); + + [DllImport("ode", EntryPoint = "dBodySetAutoDisableTime"), SuppressUnmanagedCodeSecurity] + public static extern void BodySetAutoDisableTime(IntPtr body, dReal time); + + [DllImport("ode", EntryPoint = "dBodySetData"), SuppressUnmanagedCodeSecurity] + public static extern void BodySetData(IntPtr body, IntPtr data); + + [DllImport("ode", EntryPoint = "dBodySetFiniteRotationMode"), SuppressUnmanagedCodeSecurity] + public static extern void BodySetFiniteRotationMode(IntPtr body, int mode); + + [DllImport("ode", EntryPoint = "dBodySetFiniteRotationModeAxis"), SuppressUnmanagedCodeSecurity] + public static extern void BodySetFiniteRotationModeAxis(IntPtr body, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dBodySetForce"), SuppressUnmanagedCodeSecurity] + public static extern void BodySetForce(IntPtr body, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dBodySetGravityMode"), SuppressUnmanagedCodeSecurity] + public static extern void BodySetGravityMode(IntPtr body, bool mode); + + [DllImport("ode", EntryPoint = "dBodySetLinearVel"), SuppressUnmanagedCodeSecurity] + public static extern void BodySetLinearVel(IntPtr body, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dBodySetMass"), SuppressUnmanagedCodeSecurity] + public static extern void BodySetMass(IntPtr body, ref Mass mass); + + [DllImport("ode", EntryPoint = "dBodySetPosition"), SuppressUnmanagedCodeSecurity] + public static extern void BodySetPosition(IntPtr body, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dBodySetQuaternion"), SuppressUnmanagedCodeSecurity] + public static extern void BodySetQuaternion(IntPtr body, ref Quaternion q); + + [DllImport("ode", EntryPoint = "dBodySetQuaternion"), SuppressUnmanagedCodeSecurity] + public static extern void BodySetQuaternion(IntPtr body, ref dReal w); + + [DllImport("ode", EntryPoint = "dBodySetRotation"), SuppressUnmanagedCodeSecurity] + public static extern void BodySetRotation(IntPtr body, ref Matrix3 R); + + [DllImport("ode", EntryPoint = "dBodySetRotation"), SuppressUnmanagedCodeSecurity] + public static extern void BodySetRotation(IntPtr body, ref dReal M00); + + [DllImport("ode", EntryPoint = "dBodySetTorque"), SuppressUnmanagedCodeSecurity] + public static extern void BodySetTorque(IntPtr body, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dBodyVectorFromWorld"), SuppressUnmanagedCodeSecurity] + public static extern void BodyVectorFromWorld(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); + + [DllImport("ode", EntryPoint = "dBodyVectorToWorld"), SuppressUnmanagedCodeSecurity] + public static extern void BodyVectorToWorld(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); + + [DllImport("ode", EntryPoint = "dBoxBox"), SuppressUnmanagedCodeSecurity] + public static extern void BoxBox(ref Vector3 p1, ref Matrix3 R1, + ref Vector3 side1, ref Vector3 p2, + ref Matrix3 R2, ref Vector3 side2, + ref Vector3 normal, out dReal depth, out int return_code, + int maxc, out ContactGeom contact, int skip); + + [DllImport("ode", EntryPoint = "dBoxTouchesBox"), SuppressUnmanagedCodeSecurity] + public static extern void BoxTouchesBox(ref Vector3 _p1, ref Matrix3 R1, + ref Vector3 side1, ref Vector3 _p2, + ref Matrix3 R2, ref Vector3 side2); + + [DllImport("ode", EntryPoint = "dClosestLineSegmentPoints"), SuppressUnmanagedCodeSecurity] + public static extern void ClosestLineSegmentPoints(ref Vector3 a1, ref Vector3 a2, + ref Vector3 b1, ref Vector3 b2, + ref Vector3 cp1, ref Vector3 cp2); + + [DllImport("ode", EntryPoint = "dCloseODE"), SuppressUnmanagedCodeSecurity] + public static extern void CloseODE(); + + [DllImport("ode", EntryPoint = "dCollide"), SuppressUnmanagedCodeSecurity] + public static extern int Collide(IntPtr o1, IntPtr o2, int flags, [In, Out] ContactGeom[] contact, int skip); + + [DllImport("ode", EntryPoint = "dConnectingJoint"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr ConnectingJoint(IntPtr j1, IntPtr j2); + + [DllImport("ode", EntryPoint = "dCreateBox"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr CreateBox(IntPtr space, dReal lx, dReal ly, dReal lz); + + [DllImport("ode", EntryPoint = "dCreateCapsule"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr CreateCapsule(IntPtr space, dReal radius, dReal length); + + [DllImport("ode", EntryPoint = "dCreateConvex"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr CreateConvex(IntPtr space, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons); + + [DllImport("ode", EntryPoint = "dCreateCylinder"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr CreateCylinder(IntPtr space, dReal radius, dReal length); + + [DllImport("ode", EntryPoint = "dCreateHeightfield"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr CreateHeightfield(IntPtr space, IntPtr data, int bPlaceable); + + [DllImport("ode", EntryPoint = "dCreateGeom"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr CreateGeom(int classnum); + + [DllImport("ode", EntryPoint = "dCreateGeomClass"), SuppressUnmanagedCodeSecurity] + public static extern int CreateGeomClass(ref GeomClass classptr); + + [DllImport("ode", EntryPoint = "dCreateGeomTransform"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr CreateGeomTransform(IntPtr space); + + [DllImport("ode", EntryPoint = "dCreatePlane"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr CreatePlane(IntPtr space, dReal a, dReal b, dReal c, dReal d); + + [DllImport("ode", EntryPoint = "dCreateRay"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr CreateRay(IntPtr space, dReal length); + + [DllImport("ode", EntryPoint = "dCreateSphere"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr CreateSphere(IntPtr space, dReal radius); + + [DllImport("ode", EntryPoint = "dCreateTriMesh"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr CreateTriMesh(IntPtr space, IntPtr data, + TriCallback callback, TriArrayCallback arrayCallback, TriRayCallback rayCallback); + + [DllImport("ode", EntryPoint = "dDot"), SuppressUnmanagedCodeSecurity] + public static extern dReal Dot(ref dReal X0, ref dReal X1, int n); + + [DllImport("ode", EntryPoint = "dDQfromW"), SuppressUnmanagedCodeSecurity] + public static extern void DQfromW(dReal[] dq, ref Vector3 w, ref Quaternion q); + + [DllImport("ode", EntryPoint = "dFactorCholesky"), SuppressUnmanagedCodeSecurity] + public static extern int FactorCholesky(ref dReal A00, int n); + + [DllImport("ode", EntryPoint = "dFactorLDLT"), SuppressUnmanagedCodeSecurity] + public static extern void FactorLDLT(ref dReal A, out dReal d, int n, int nskip); + + [DllImport("ode", EntryPoint = "dGeomBoxGetLengths"), SuppressUnmanagedCodeSecurity] + public static extern void GeomBoxGetLengths(IntPtr geom, out Vector3 len); + + [DllImport("ode", EntryPoint = "dGeomBoxGetLengths"), SuppressUnmanagedCodeSecurity] + public static extern void GeomBoxGetLengths(IntPtr geom, out dReal x); + + [DllImport("ode", EntryPoint = "dGeomBoxPointDepth"), SuppressUnmanagedCodeSecurity] + public static extern dReal GeomBoxPointDepth(IntPtr geom, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dGeomBoxSetLengths"), SuppressUnmanagedCodeSecurity] + public static extern void GeomBoxSetLengths(IntPtr geom, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dGeomCapsuleGetParams"), SuppressUnmanagedCodeSecurity] + public static extern void GeomCapsuleGetParams(IntPtr geom, out dReal radius, out dReal length); + + [DllImport("ode", EntryPoint = "dGeomCapsulePointDepth"), SuppressUnmanagedCodeSecurity] + public static extern dReal GeomCapsulePointDepth(IntPtr geom, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dGeomCapsuleSetParams"), SuppressUnmanagedCodeSecurity] + public static extern void GeomCapsuleSetParams(IntPtr geom, dReal radius, dReal length); + + [DllImport("ode", EntryPoint = "dGeomClearOffset"), SuppressUnmanagedCodeSecurity] + public static extern void GeomClearOffset(IntPtr geom); + + [DllImport("ode", EntryPoint = "dGeomCopyOffsetPosition"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr GeomCopyOffsetPosition(IntPtr geom, ref Vector3 pos); + + [DllImport("ode", EntryPoint = "dGeomCopyOffsetPosition"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr GeomCopyOffsetPosition(IntPtr geom, ref dReal X); + + [DllImport("ode", EntryPoint = "dGeomGetOffsetQuaternion"), SuppressUnmanagedCodeSecurity] + public static extern void GeomCopyOffsetQuaternion(IntPtr geom, ref Quaternion Q); + + [DllImport("ode", EntryPoint = "dGeomGetOffsetQuaternion"), SuppressUnmanagedCodeSecurity] + public static extern void GeomCopyOffsetQuaternion(IntPtr geom, ref dReal X); + + [DllImport("ode", EntryPoint = "dGeomCopyOffsetRotation"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr GeomCopyOffsetRotation(IntPtr geom, ref Matrix3 R); + + [DllImport("ode", EntryPoint = "dGeomCopyOffsetRotation"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr GeomCopyOffsetRotation(IntPtr geom, ref dReal M00); + + [DllImport("ode", EntryPoint = "dGeomCopyPosition"), SuppressUnmanagedCodeSecurity] + public static extern void GeomCopyPosition(IntPtr geom, out Vector3 pos); + + [DllImport("ode", EntryPoint = "dGeomCopyPosition"), SuppressUnmanagedCodeSecurity] + public static extern void GeomCopyPosition(IntPtr geom, out dReal X); + + [DllImport("ode", EntryPoint = "dGeomCopyRotation"), SuppressUnmanagedCodeSecurity] + public static extern void GeomCopyRotation(IntPtr geom, out Matrix3 R); + + [DllImport("ode", EntryPoint = "dGeomCopyRotation"), SuppressUnmanagedCodeSecurity] + public static extern void GeomCopyRotation(IntPtr geom, out dReal M00); + + [DllImport("ode", EntryPoint = "dGeomCylinderGetParams"), SuppressUnmanagedCodeSecurity] + public static extern void GeomCylinderGetParams(IntPtr geom, out dReal radius, out dReal length); + + [DllImport("ode", EntryPoint = "dGeomCylinderSetParams"), SuppressUnmanagedCodeSecurity] + public static extern void GeomCylinderSetParams(IntPtr geom, dReal radius, dReal length); + + [DllImport("ode", EntryPoint = "dGeomDestroy"), SuppressUnmanagedCodeSecurity] + public static extern void GeomDestroy(IntPtr geom); + + [DllImport("ode", EntryPoint = "dGeomDisable"), SuppressUnmanagedCodeSecurity] + public static extern void GeomDisable(IntPtr geom); + + [DllImport("ode", EntryPoint = "dGeomEnable"), SuppressUnmanagedCodeSecurity] + public static extern void GeomEnable(IntPtr geom); + + [DllImport("ode", EntryPoint = "dGeomGetAABB"), SuppressUnmanagedCodeSecurity] + public static extern void GeomGetAABB(IntPtr geom, out AABB aabb); + + [DllImport("ode", EntryPoint = "dGeomGetAABB"), SuppressUnmanagedCodeSecurity] + public static extern void GeomGetAABB(IntPtr geom, out dReal minX); + + [DllImport("ode", EntryPoint = "dGeomGetBody"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr GeomGetBody(IntPtr geom); + + [DllImport("ode", EntryPoint = "dGeomGetCategoryBits"), SuppressUnmanagedCodeSecurity] + public static extern int GeomGetCategoryBits(IntPtr geom); + + [DllImport("ode", EntryPoint = "dGeomGetClassData"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr GeomGetClassData(IntPtr geom); + + [DllImport("ode", EntryPoint = "dGeomGetCollideBits"), SuppressUnmanagedCodeSecurity] + public static extern int GeomGetCollideBits(IntPtr geom); + + [DllImport("ode", EntryPoint = "dGeomGetClass"), SuppressUnmanagedCodeSecurity] + public static extern GeomClassID GeomGetClass(IntPtr geom); + + [DllImport("ode", EntryPoint = "dGeomGetData"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr GeomGetData(IntPtr geom); + +#if !dNO_UNSAFE_CODE + [CLSCompliant(false)] + [DllImport("ode", EntryPoint = "dGeomGetOffsetPosition"), SuppressUnmanagedCodeSecurity] + public extern unsafe static Vector3* GeomGetOffsetPositionUnsafe(IntPtr geom); + public static Vector3 GeomGetOffsetPosition(IntPtr geom) + { + unsafe { return *(GeomGetOffsetPositionUnsafe(geom)); } + } +#endif + +#if !dNO_UNSAFE_CODE + [CLSCompliant(false)] + [DllImport("ode", EntryPoint = "dGeomGetOffsetRotation"), SuppressUnmanagedCodeSecurity] + public extern unsafe static Matrix3* GeomGetOffsetRotationUnsafe(IntPtr geom); + public static Matrix3 GeomGetOffsetRotation(IntPtr geom) + { + unsafe { return *(GeomGetOffsetRotationUnsafe(geom)); } + } +#endif + +#if !dNO_UNSAFE_CODE + [CLSCompliant(false)] + [DllImport("ode", EntryPoint = "dGeomGetPosition"), SuppressUnmanagedCodeSecurity] + public extern unsafe static Vector3* GeomGetPositionUnsafe(IntPtr geom); + public static Vector3 GeomGetPosition(IntPtr geom) + { + unsafe { return *(GeomGetPositionUnsafe(geom)); } + } +#endif + + [DllImport("ode", EntryPoint = "dGeomGetQuaternion"), SuppressUnmanagedCodeSecurity] + public static extern void GeomCopyQuaternion(IntPtr geom, out Quaternion q); + + [DllImport("ode", EntryPoint = "dGeomGetQuaternion"), SuppressUnmanagedCodeSecurity] + public static extern void GeomCopyQuaternion(IntPtr geom, out dReal X); + +#if !dNO_UNSAFE_CODE + [CLSCompliant(false)] + [DllImport("ode", EntryPoint = "dGeomGetRotation"), SuppressUnmanagedCodeSecurity] + public extern unsafe static Matrix3* GeomGetRotationUnsafe(IntPtr geom); + public static Matrix3 GeomGetRotation(IntPtr geom) + { + unsafe { return *(GeomGetRotationUnsafe(geom)); } + } +#endif + + [DllImport("ode", EntryPoint = "dGeomGetSpace"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr GeomGetSpace(IntPtr geom); + + [DllImport("ode", EntryPoint = "dGeomHeightfieldDataBuildByte"), SuppressUnmanagedCodeSecurity] + public static extern void GeomHeightfieldDataBuildByte(IntPtr d, byte[] pHeightData, int bCopyHeightData, + dReal width, dReal depth, int widthSamples, int depthSamples, + dReal scale, dReal offset, dReal thickness, int bWrap); + + [DllImport("ode", EntryPoint = "dGeomHeightfieldDataBuildByte"), SuppressUnmanagedCodeSecurity] + public static extern void GeomHeightfieldDataBuildByte(IntPtr d, IntPtr pHeightData, int bCopyHeightData, + dReal width, dReal depth, int widthSamples, int depthSamples, + dReal scale, dReal offset, dReal thickness, int bWrap); + + [DllImport("ode", EntryPoint = "dGeomHeightfieldDataBuildCallback"), SuppressUnmanagedCodeSecurity] + public static extern void GeomHeightfieldDataBuildCallback(IntPtr d, IntPtr pUserData, HeightfieldGetHeight pCallback, + dReal width, dReal depth, int widthSamples, int depthSamples, + dReal scale, dReal offset, dReal thickness, int bWrap); + + [CLSCompliant(false)] + [DllImport("ode", EntryPoint = "dGeomHeightfieldDataBuildShort"), SuppressUnmanagedCodeSecurity] + public static extern void GeomHeightfieldDataBuildShort(IntPtr d, ushort[] pHeightData, int bCopyHeightData, + dReal width, dReal depth, int widthSamples, int depthSamples, + dReal scale, dReal offset, dReal thickness, int bWrap); + + [DllImport("ode", EntryPoint = "dGeomHeightfieldDataBuildShort"), SuppressUnmanagedCodeSecurity] + public static extern void GeomHeightfieldDataBuildShort(IntPtr d, short[] pHeightData, int bCopyHeightData, + dReal width, dReal depth, int widthSamples, int depthSamples, + dReal scale, dReal offset, dReal thickness, int bWrap); + + [DllImport("ode", EntryPoint = "dGeomHeightfieldDataBuildShort"), SuppressUnmanagedCodeSecurity] + public static extern void GeomHeightfieldDataBuildShort(IntPtr d, IntPtr pHeightData, int bCopyHeightData, + dReal width, dReal depth, int widthSamples, int depthSamples, + dReal scale, dReal offset, dReal thickness, int bWrap); + + [DllImport("ode", EntryPoint = "dGeomHeightfieldDataBuildSingle"), SuppressUnmanagedCodeSecurity] + public static extern void GeomHeightfieldDataBuildSingle(IntPtr d, float[] pHeightData, int bCopyHeightData, + dReal width, dReal depth, int widthSamples, int depthSamples, + dReal scale, dReal offset, dReal thickness, int bWrap); + + [DllImport("ode", EntryPoint = "dGeomHeightfieldDataBuildSingle"), SuppressUnmanagedCodeSecurity] + public static extern void GeomHeightfieldDataBuildSingle(IntPtr d, IntPtr pHeightData, int bCopyHeightData, + dReal width, dReal depth, int widthSamples, int depthSamples, + dReal scale, dReal offset, dReal thickness, int bWrap); + + [DllImport("ode", EntryPoint = "dGeomHeightfieldDataBuildDouble"), SuppressUnmanagedCodeSecurity] + public static extern void GeomHeightfieldDataBuildDouble(IntPtr d, double[] pHeightData, int bCopyHeightData, + dReal width, dReal depth, int widthSamples, int depthSamples, + dReal scale, dReal offset, dReal thickness, int bWrap); + + [DllImport("ode", EntryPoint = "dGeomHeightfieldDataBuildDouble"), SuppressUnmanagedCodeSecurity] + public static extern void GeomHeightfieldDataBuildDouble(IntPtr d, IntPtr pHeightData, int bCopyHeightData, + dReal width, dReal depth, int widthSamples, int depthSamples, + dReal scale, dReal offset, dReal thickness, int bWrap); + + [DllImport("ode", EntryPoint = "dGeomHeightfieldDataCreate"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr GeomHeightfieldDataCreate(); + + [DllImport("ode", EntryPoint = "dGeomHeightfieldDataDestroy"), SuppressUnmanagedCodeSecurity] + public static extern void GeomHeightfieldDataDestroy(IntPtr d); + + [DllImport("ode", EntryPoint = "dGeomHeightfieldDataSetBounds"), SuppressUnmanagedCodeSecurity] + public static extern void GeomHeightfieldDataSetBounds(IntPtr d, dReal minHeight, dReal maxHeight); + + [DllImport("ode", EntryPoint = "dGeomHeightfieldGetHeightfieldData"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr GeomHeightfieldGetHeightfieldData(IntPtr g); + + [DllImport("ode", EntryPoint = "dGeomHeightfieldSetHeightfieldData"), SuppressUnmanagedCodeSecurity] + public static extern void GeomHeightfieldSetHeightfieldData(IntPtr g, IntPtr d); + + [DllImport("ode", EntryPoint = "dGeomIsEnabled"), SuppressUnmanagedCodeSecurity] + public static extern bool GeomIsEnabled(IntPtr geom); + + [DllImport("ode", EntryPoint = "dGeomIsOffset"), SuppressUnmanagedCodeSecurity] + public static extern bool GeomIsOffset(IntPtr geom); + + [DllImport("ode", EntryPoint = "dGeomIsSpace"), SuppressUnmanagedCodeSecurity] + public static extern bool GeomIsSpace(IntPtr geom); + + [DllImport("ode", EntryPoint = "dGeomPlaneGetParams"), SuppressUnmanagedCodeSecurity] + public static extern void GeomPlaneGetParams(IntPtr geom, ref Vector4 result); + + [DllImport("ode", EntryPoint = "dGeomPlaneGetParams"), SuppressUnmanagedCodeSecurity] + public static extern void GeomPlaneGetParams(IntPtr geom, ref dReal A); + + [DllImport("ode", EntryPoint = "dGeomPlanePointDepth"), SuppressUnmanagedCodeSecurity] + public static extern dReal GeomPlanePointDepth(IntPtr geom, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dGeomPlaneSetParams"), SuppressUnmanagedCodeSecurity] + public static extern void GeomPlaneSetParams(IntPtr plane, dReal a, dReal b, dReal c, dReal d); + + [DllImport("ode", EntryPoint = "dGeomRayGet"), SuppressUnmanagedCodeSecurity] + public static extern void GeomRayGet(IntPtr ray, ref Vector3 start, ref Vector3 dir); + + [DllImport("ode", EntryPoint = "dGeomRayGet"), SuppressUnmanagedCodeSecurity] + public static extern void GeomRayGet(IntPtr ray, ref dReal startX, ref dReal dirX); + + [DllImport("ode", EntryPoint = "dGeomRayGetClosestHit"), SuppressUnmanagedCodeSecurity] + public static extern int GeomRayGetClosestHit(IntPtr ray); + + [DllImport("ode", EntryPoint = "dGeomRayGetLength"), SuppressUnmanagedCodeSecurity] + public static extern dReal GeomRayGetLength(IntPtr ray); + + [DllImport("ode", EntryPoint = "dGeomRayGetParams"), SuppressUnmanagedCodeSecurity] + public static extern dReal GeomRayGetParams(IntPtr g, out int firstContact, out int backfaceCull); + + [DllImport("ode", EntryPoint = "dGeomRaySet"), SuppressUnmanagedCodeSecurity] + public static extern void GeomRaySet(IntPtr ray, dReal px, dReal py, dReal pz, dReal dx, dReal dy, dReal dz); + + [DllImport("ode", EntryPoint = "dGeomRaySetClosestHit"), SuppressUnmanagedCodeSecurity] + public static extern void GeomRaySetClosestHit(IntPtr ray, int closestHit); + + [DllImport("ode", EntryPoint = "dGeomRaySetLength"), SuppressUnmanagedCodeSecurity] + public static extern void GeomRaySetLength(IntPtr ray, dReal length); + + [DllImport("ode", EntryPoint = "dGeomRaySetParams"), SuppressUnmanagedCodeSecurity] + public static extern void GeomRaySetParams(IntPtr ray, int firstContact, int backfaceCull); + + [DllImport("ode", EntryPoint = "dGeomSetBody"), SuppressUnmanagedCodeSecurity] + public static extern void GeomSetBody(IntPtr geom, IntPtr body); + + [DllImport("ode", EntryPoint = "dGeomSetCategoryBits"), SuppressUnmanagedCodeSecurity] + public static extern void GeomSetCategoryBits(IntPtr geom, int bits); + + [DllImport("ode", EntryPoint = "dGeomSetCollideBits"), SuppressUnmanagedCodeSecurity] + public static extern void GeomSetCollideBits(IntPtr geom, int bits); + + [DllImport("ode", EntryPoint = "dGeomSetConvex"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr GeomSetConvex(IntPtr geom, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons); + + [DllImport("ode", EntryPoint = "dGeomSetData"), SuppressUnmanagedCodeSecurity] + public static extern void GeomSetData(IntPtr geom, IntPtr data); + + [DllImport("ode", EntryPoint = "dGeomSetOffsetPosition"), SuppressUnmanagedCodeSecurity] + public static extern void GeomSetOffsetPosition(IntPtr geom, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dGeomSetOffsetQuaternion"), SuppressUnmanagedCodeSecurity] + public static extern void GeomSetOffsetQuaternion(IntPtr geom, ref Quaternion Q); + + [DllImport("ode", EntryPoint = "dGeomSetOffsetQuaternion"), SuppressUnmanagedCodeSecurity] + public static extern void GeomSetOffsetQuaternion(IntPtr geom, ref dReal X); + + [DllImport("ode", EntryPoint = "dGeomSetOffsetRotation"), SuppressUnmanagedCodeSecurity] + public static extern void GeomSetOffsetRotation(IntPtr geom, ref Matrix3 R); + + [DllImport("ode", EntryPoint = "dGeomSetOffsetRotation"), SuppressUnmanagedCodeSecurity] + public static extern void GeomSetOffsetRotation(IntPtr geom, ref dReal M00); + + [DllImport("ode", EntryPoint = "dGeomSetOffsetWorldPosition"), SuppressUnmanagedCodeSecurity] + public static extern void GeomSetOffsetWorldPosition(IntPtr geom, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dGeomSetOffsetWorldQuaternion"), SuppressUnmanagedCodeSecurity] + public static extern void GeomSetOffsetWorldQuaternion(IntPtr geom, ref Quaternion Q); + + [DllImport("ode", EntryPoint = "dGeomSetOffsetWorldQuaternion"), SuppressUnmanagedCodeSecurity] + public static extern void GeomSetOffsetWorldQuaternion(IntPtr geom, ref dReal X); + + [DllImport("ode", EntryPoint = "dGeomSetOffsetWorldRotation"), SuppressUnmanagedCodeSecurity] + public static extern void GeomSetOffsetWorldRotation(IntPtr geom, ref Matrix3 R); + + [DllImport("ode", EntryPoint = "dGeomSetOffsetWorldRotation"), SuppressUnmanagedCodeSecurity] + public static extern void GeomSetOffsetWorldRotation(IntPtr geom, ref dReal M00); + + [DllImport("ode", EntryPoint = "dGeomSetPosition"), SuppressUnmanagedCodeSecurity] + public static extern void GeomSetPosition(IntPtr geom, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dGeomSetQuaternion"), SuppressUnmanagedCodeSecurity] + public static extern void GeomSetQuaternion(IntPtr geom, ref Quaternion quat); + + [DllImport("ode", EntryPoint = "dGeomSetQuaternion"), SuppressUnmanagedCodeSecurity] + public static extern void GeomSetQuaternion(IntPtr geom, ref dReal w); + + [DllImport("ode", EntryPoint = "dGeomSetRotation"), SuppressUnmanagedCodeSecurity] + public static extern void GeomSetRotation(IntPtr geom, ref Matrix3 R); + + [DllImport("ode", EntryPoint = "dGeomSetRotation"), SuppressUnmanagedCodeSecurity] + public static extern void GeomSetRotation(IntPtr geom, ref dReal M00); + + [DllImport("ode", EntryPoint = "dGeomSphereGetRadius"), SuppressUnmanagedCodeSecurity] + public static extern dReal GeomSphereGetRadius(IntPtr geom); + + [DllImport("ode", EntryPoint = "dGeomSpherePointDepth"), SuppressUnmanagedCodeSecurity] + public static extern dReal GeomSpherePointDepth(IntPtr geom, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dGeomSphereSetRadius"), SuppressUnmanagedCodeSecurity] + public static extern void GeomSphereSetRadius(IntPtr geom, dReal radius); + + [DllImport("ode", EntryPoint = "dGeomTransformGetCleanup"), SuppressUnmanagedCodeSecurity] + public static extern int GeomTransformGetCleanup(IntPtr geom); + + [DllImport("ode", EntryPoint = "dGeomTransformGetGeom"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr GeomTransformGetGeom(IntPtr geom); + + [DllImport("ode", EntryPoint = "dGeomTransformGetInfo"), SuppressUnmanagedCodeSecurity] + public static extern int GeomTransformGetInfo(IntPtr geom); + + [DllImport("ode", EntryPoint = "dGeomTransformSetCleanup"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTransformSetCleanup(IntPtr geom, int mode); + + [DllImport("ode", EntryPoint = "dGeomTransformSetGeom"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTransformSetGeom(IntPtr geom, IntPtr obj); + + [DllImport("ode", EntryPoint = "dGeomTransformSetInfo"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTransformSetInfo(IntPtr geom, int info); + + [DllImport("ode", EntryPoint = "dGeomTriMeshDataBuildDouble"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTriMeshDataBuildDouble(IntPtr d, + double[] vertices, int vertexStride, int vertexCount, + int[] indices, int indexCount, int triStride); + + [DllImport("ode", EntryPoint = "dGeomTriMeshDataBuildDouble"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTriMeshDataBuildDouble(IntPtr d, + IntPtr vertices, int vertexStride, int vertexCount, + IntPtr indices, int indexCount, int triStride); + + [DllImport("ode", EntryPoint = "dGeomTriMeshDataBuildDouble1"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTriMeshDataBuildDouble1(IntPtr d, + double[] vertices, int vertexStride, int vertexCount, + int[] indices, int indexCount, int triStride, + double[] normals); + + [DllImport("ode", EntryPoint = "dGeomTriMeshDataBuildDouble1"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTriMeshDataBuildDouble(IntPtr d, + IntPtr vertices, int vertexStride, int vertexCount, + IntPtr indices, int indexCount, int triStride, + IntPtr normals); + + [DllImport("ode", EntryPoint = "dGeomTriMeshDataBuildSimple"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTriMeshDataBuildSingle(IntPtr d, + dReal[] vertices, int vertexStride, int vertexCount, + int[] indices, int indexCount, int triStride); + + [DllImport("ode", EntryPoint = "dGeomTriMeshDataBuildSimple"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTriMeshDataBuildSingle(IntPtr d, + IntPtr vertices, int vertexStride, int vertexCount, + IntPtr indices, int indexCount, int triStride); + + [DllImport("ode", EntryPoint = "dGeomTriMeshDataBuildSimple1"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTriMeshDataBuildSingle1(IntPtr d, + dReal[] vertices, int vertexStride, int vertexCount, + int[] indices, int indexCount, int triStride, + dReal[] normals); + + [DllImport("ode", EntryPoint = "dGeomTriMeshDataBuildSimple1"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTriMeshDataBuildSingle1(IntPtr d, + IntPtr vertices, int vertexStride, int vertexCount, + IntPtr indices, int indexCount, int triStride, + IntPtr normals); + + [DllImport("ode", EntryPoint = "dGeomTriMeshDataBuildSingle"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTriMeshDataBuildSimple(IntPtr d, + float[] vertices, int vertexStride, int vertexCount, + int[] indices, int indexCount, int triStride); + + [DllImport("ode", EntryPoint = "dGeomTriMeshDataBuildSingle"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTriMeshDataBuildSimple(IntPtr d, + IntPtr vertices, int vertexStride, int vertexCount, + IntPtr indices, int indexCount, int triStride); + + [DllImport("ode", EntryPoint = "dGeomTriMeshDataBuildSingle1"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTriMeshDataBuildSimple1(IntPtr d, + float[] vertices, int vertexStride, int vertexCount, + int[] indices, int indexCount, int triStride, + float[] normals); + + [DllImport("ode", EntryPoint = "dGeomTriMeshDataBuildSingle1"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTriMeshDataBuildSimple1(IntPtr d, + IntPtr vertices, int vertexStride, int vertexCount, + IntPtr indices, int indexCount, int triStride, + IntPtr normals); + + [DllImport("ode", EntryPoint = "dGeomTriMeshClearTCCache"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTriMeshClearTCCache(IntPtr g); + + [DllImport("ode", EntryPoint = "dGeomTriMeshDataCreate"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr GeomTriMeshDataCreate(); + + [DllImport("ode", EntryPoint = "dGeomTriMeshDataDestroy"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTriMeshDataDestroy(IntPtr d); + + [DllImport("ode", EntryPoint = "dGeomTriMeshDataGet"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr GeomTriMeshDataGet(IntPtr d, int data_id); + + [DllImport("ode", EntryPoint = "dGeomTriMeshDataPreprocess"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTriMeshDataPreprocess(IntPtr d); + + [DllImport("ode", EntryPoint = "dGeomTriMeshDataSet"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTriMeshDataSet(IntPtr d, int data_id, IntPtr in_data); + + [DllImport("ode", EntryPoint = "dGeomTriMeshDataUpdate"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTriMeshDataUpdate(IntPtr d); + + [DllImport("ode", EntryPoint = "dGeomTriMeshEnableTC"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTriMeshEnableTC(IntPtr g, int geomClass, bool enable); + + [DllImport("ode", EntryPoint = "dGeomTriMeshGetArrayCallback"), SuppressUnmanagedCodeSecurity] + public static extern TriArrayCallback GeomTriMeshGetArrayCallback(IntPtr g); + + [DllImport("ode", EntryPoint = "dGeomTriMeshGetCallback"), SuppressUnmanagedCodeSecurity] + public static extern TriCallback GeomTriMeshGetCallback(IntPtr g); + + [DllImport("ode", EntryPoint = "dGeomTriMeshGetData"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr GeomTriMeshGetData(IntPtr g); + +#if !dNO_UNSAFE_CODE + [CLSCompliant(false)] + [DllImport("ode", EntryPoint = "dGeomTriMeshGetLastTransform"), SuppressUnmanagedCodeSecurity] + public extern unsafe static Matrix4* GeomTriMeshGetLastTransformUnsafe(IntPtr geom); + public static Matrix4 GeomTriMeshGetLastTransform(IntPtr geom) + { + unsafe { return *(GeomTriMeshGetLastTransformUnsafe(geom)); } + } +#endif + + [DllImport("ode", EntryPoint = "dGeomTriMeshGetPoint"), SuppressUnmanagedCodeSecurity] + public extern static void GeomTriMeshGetPoint(IntPtr g, int index, dReal u, dReal v, ref Vector3 outVec); + + [DllImport("ode", EntryPoint = "dGeomTriMeshGetRayCallback"), SuppressUnmanagedCodeSecurity] + public static extern TriRayCallback GeomTriMeshGetRayCallback(IntPtr g); + + [DllImport("ode", EntryPoint = "dGeomTriMeshGetTriangle"), SuppressUnmanagedCodeSecurity] + public extern static void GeomTriMeshGetTriangle(IntPtr g, int index, ref Vector3 v0, ref Vector3 v1, ref Vector3 v2); + + [DllImport("ode", EntryPoint = "dGeomTriMeshGetTriangleCount"), SuppressUnmanagedCodeSecurity] + public extern static int GeomTriMeshGetTriangleCount(IntPtr g); + + [DllImport("ode", EntryPoint = "dGeomTriMeshGetTriMeshDataID"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr GeomTriMeshGetTriMeshDataID(IntPtr g); + + [DllImport("ode", EntryPoint = "dGeomTriMeshIsTCEnabled"), SuppressUnmanagedCodeSecurity] + public static extern bool GeomTriMeshIsTCEnabled(IntPtr g, int geomClass); + + [DllImport("ode", EntryPoint = "dGeomTriMeshSetArrayCallback"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTriMeshSetArrayCallback(IntPtr g, TriArrayCallback arrayCallback); + + [DllImport("ode", EntryPoint = "dGeomTriMeshSetCallback"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTriMeshSetCallback(IntPtr g, TriCallback callback); + + [DllImport("ode", EntryPoint = "dGeomTriMeshSetData"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTriMeshSetData(IntPtr g, IntPtr data); + + [DllImport("ode", EntryPoint = "dGeomTriMeshSetLastTransform"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTriMeshSetLastTransform(IntPtr g, ref Matrix4 last_trans); + + [DllImport("ode", EntryPoint = "dGeomTriMeshSetLastTransform"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTriMeshSetLastTransform(IntPtr g, ref dReal M00); + + [DllImport("ode", EntryPoint = "dGeomTriMeshSetRayCallback"), SuppressUnmanagedCodeSecurity] + public static extern void GeomTriMeshSetRayCallback(IntPtr g, TriRayCallback callback); + + [DllImport("ode", EntryPoint = "dHashSpaceCreate"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr HashSpaceCreate(IntPtr space); + + [DllImport("ode", EntryPoint = "dHashSpaceGetLevels"), SuppressUnmanagedCodeSecurity] + public static extern void HashSpaceGetLevels(IntPtr space, out int minlevel, out int maxlevel); + + [DllImport("ode", EntryPoint = "dHashSpaceSetLevels"), SuppressUnmanagedCodeSecurity] + public static extern void HashSpaceSetLevels(IntPtr space, int minlevel, int maxlevel); + + [DllImport("ode", EntryPoint = "dInfiniteAABB"), SuppressUnmanagedCodeSecurity] + public static extern void InfiniteAABB(IntPtr geom, out AABB aabb); + + [DllImport("ode", EntryPoint = "dInitODE"), SuppressUnmanagedCodeSecurity] + public static extern void InitODE(); + + [DllImport("ode", EntryPoint = "dIsPositiveDefinite"), SuppressUnmanagedCodeSecurity] + public static extern int IsPositiveDefinite(ref dReal A, int n); + + [DllImport("ode", EntryPoint = "dInvertPDMatrix"), SuppressUnmanagedCodeSecurity] + public static extern int InvertPDMatrix(ref dReal A, out dReal Ainv, int n); + + [DllImport("ode", EntryPoint = "dJointAddAMotorTorques"), SuppressUnmanagedCodeSecurity] + public static extern void JointAddAMotorTorques(IntPtr joint, dReal torque1, dReal torque2, dReal torque3); + + [DllImport("ode", EntryPoint = "dJointAddHingeTorque"), SuppressUnmanagedCodeSecurity] + public static extern void JointAddHingeTorque(IntPtr joint, dReal torque); + + [DllImport("ode", EntryPoint = "dJointAddHinge2Torque"), SuppressUnmanagedCodeSecurity] + public static extern void JointAddHinge2Torques(IntPtr joint, dReal torque1, dReal torque2); + + [DllImport("ode", EntryPoint = "dJointAddPRTorque"), SuppressUnmanagedCodeSecurity] + public static extern void JointAddPRTorque(IntPtr joint, dReal torque); + + [DllImport("ode", EntryPoint = "dJointAddUniversalTorque"), SuppressUnmanagedCodeSecurity] + public static extern void JointAddUniversalTorques(IntPtr joint, dReal torque1, dReal torque2); + + [DllImport("ode", EntryPoint = "dJointAddSliderForce"), SuppressUnmanagedCodeSecurity] + public static extern void JointAddSliderForce(IntPtr joint, dReal force); + + [DllImport("ode", EntryPoint = "dJointAttach"), SuppressUnmanagedCodeSecurity] + public static extern void JointAttach(IntPtr joint, IntPtr body1, IntPtr body2); + + [DllImport("ode", EntryPoint = "dJointCreateAMotor"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr JointCreateAMotor(IntPtr world, IntPtr group); + + [DllImport("ode", EntryPoint = "dJointCreateBall"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr JointCreateBall(IntPtr world, IntPtr group); + + [DllImport("ode", EntryPoint = "dJointCreateContact"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr JointCreateContact(IntPtr world, IntPtr group, ref Contact contact); + + [DllImport("ode", EntryPoint = "dJointCreateFixed"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr JointCreateFixed(IntPtr world, IntPtr group); + + [DllImport("ode", EntryPoint = "dJointCreateHinge"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr JointCreateHinge(IntPtr world, IntPtr group); + + [DllImport("ode", EntryPoint = "dJointCreateHinge2"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr JointCreateHinge2(IntPtr world, IntPtr group); + + [DllImport("ode", EntryPoint = "dJointCreateLMotor"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr JointCreateLMotor(IntPtr world, IntPtr group); + + [DllImport("ode", EntryPoint = "dJointCreateNull"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr JointCreateNull(IntPtr world, IntPtr group); + + [DllImport("ode", EntryPoint = "dJointCreatePR"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr JointCreatePR(IntPtr world, IntPtr group); + + [DllImport("ode", EntryPoint = "dJointCreatePlane2D"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr JointCreatePlane2D(IntPtr world, IntPtr group); + + [DllImport("ode", EntryPoint = "dJointCreateSlider"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr JointCreateSlider(IntPtr world, IntPtr group); + + [DllImport("ode", EntryPoint = "dJointCreateUniversal"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr JointCreateUniversal(IntPtr world, IntPtr group); + + [DllImport("ode", EntryPoint = "dJointDestroy"), SuppressUnmanagedCodeSecurity] + public static extern void JointDestroy(IntPtr j); + + [DllImport("ode", EntryPoint = "dJointGetAMotorAngle"), SuppressUnmanagedCodeSecurity] + public static extern dReal JointGetAMotorAngle(IntPtr j, int anum); + + [DllImport("ode", EntryPoint = "dJointGetAMotorAngleRate"), SuppressUnmanagedCodeSecurity] + public static extern dReal JointGetAMotorAngleRate(IntPtr j, int anum); + + [DllImport("ode", EntryPoint = "dJointGetAMotorAxis"), SuppressUnmanagedCodeSecurity] + public static extern void JointGetAMotorAxis(IntPtr j, int anum, out Vector3 result); + + [DllImport("ode", EntryPoint = "dJointGetAMotorAxisRel"), SuppressUnmanagedCodeSecurity] + public static extern int JointGetAMotorAxisRel(IntPtr j, int anum); + + [DllImport("ode", EntryPoint = "dJointGetAMotorMode"), SuppressUnmanagedCodeSecurity] + public static extern int JointGetAMotorMode(IntPtr j); + + [DllImport("ode", EntryPoint = "dJointGetAMotorNumAxes"), SuppressUnmanagedCodeSecurity] + public static extern int JointGetAMotorNumAxes(IntPtr j); + + [DllImport("ode", EntryPoint = "dJointGetAMotorParam"), SuppressUnmanagedCodeSecurity] + public static extern dReal JointGetAMotorParam(IntPtr j, int parameter); + + [DllImport("ode", EntryPoint = "dJointGetBallAnchor"), SuppressUnmanagedCodeSecurity] + public static extern void JointGetBallAnchor(IntPtr j, out Vector3 result); + + [DllImport("ode", EntryPoint = "dJointGetBallAnchor2"), SuppressUnmanagedCodeSecurity] + public static extern void JointGetBallAnchor2(IntPtr j, out Vector3 result); + + [DllImport("ode", EntryPoint = "dJointGetBody"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr JointGetBody(IntPtr j); + + [DllImport("ode", EntryPoint = "dJointGetData"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr JointGetData(IntPtr j); + +#if !dNO_UNSAFE_CODE + [CLSCompliant(false)] + [DllImport("ode", EntryPoint = "dJointGetFeedback"), SuppressUnmanagedCodeSecurity] + public extern unsafe static JointFeedback* JointGetFeedbackUnsafe(IntPtr j); + public static JointFeedback JointGetFeedback(IntPtr j) + { + unsafe { return *(JointGetFeedbackUnsafe(j)); } + } +#endif + + [DllImport("ode", EntryPoint = "dJointGetHingeAnchor"), SuppressUnmanagedCodeSecurity] + public static extern void JointGetHingeAnchor(IntPtr j, out Vector3 result); + + [DllImport("ode", EntryPoint = "dJointGetHingeAngle"), SuppressUnmanagedCodeSecurity] + public static extern dReal JointGetHingeAngle(IntPtr j); + + [DllImport("ode", EntryPoint = "dJointGetHingeAngleRate"), SuppressUnmanagedCodeSecurity] + public static extern dReal JointGetHingeAngleRate(IntPtr j); + + [DllImport("ode", EntryPoint = "dJointGetHingeAxis"), SuppressUnmanagedCodeSecurity] + public static extern void JointGetHingeAxis(IntPtr j, out Vector3 result); + + [DllImport("ode", EntryPoint = "dJointGetHingeParam"), SuppressUnmanagedCodeSecurity] + public static extern dReal JointGetHingeParam(IntPtr j, int parameter); + + [DllImport("ode", EntryPoint = "dJointGetHinge2Angle1"), SuppressUnmanagedCodeSecurity] + public static extern dReal JointGetHinge2Angle1(IntPtr j); + + [DllImport("ode", EntryPoint = "dJointGetHinge2Angle1Rate"), SuppressUnmanagedCodeSecurity] + public static extern dReal JointGetHinge2Angle1Rate(IntPtr j); + + [DllImport("ode", EntryPoint = "dJointGetHinge2Angle2Rate"), SuppressUnmanagedCodeSecurity] + public static extern dReal JointGetHinge2Angle2Rate(IntPtr j); + + [DllImport("ode", EntryPoint = "dJointGetHingeAnchor2"), SuppressUnmanagedCodeSecurity] + public static extern void JointGetHingeAnchor2(IntPtr j, out Vector3 result); + + [DllImport("ode", EntryPoint = "dJointGetHinge2Anchor"), SuppressUnmanagedCodeSecurity] + public static extern void JointGetHinge2Anchor(IntPtr j, out Vector3 result); + + [DllImport("ode", EntryPoint = "dJointGetHinge2Anchor2"), SuppressUnmanagedCodeSecurity] + public static extern void JointGetHinge2Anchor2(IntPtr j, out Vector3 result); + + [DllImport("ode", EntryPoint = "dJointGetHinge2Axis1"), SuppressUnmanagedCodeSecurity] + public static extern void JointGetHinge2Axis1(IntPtr j, out Vector3 result); + + [DllImport("ode", EntryPoint = "dJointGetHinge2Axis2"), SuppressUnmanagedCodeSecurity] + public static extern void JointGetHinge2Axis2(IntPtr j, out Vector3 result); + + [DllImport("ode", EntryPoint = "dJointGetHinge2Param"), SuppressUnmanagedCodeSecurity] + public static extern dReal JointGetHinge2Param(IntPtr j, int parameter); + + [DllImport("ode", EntryPoint = "dJointGetLMotorAxis"), SuppressUnmanagedCodeSecurity] + public static extern void JointGetLMotorAxis(IntPtr j, int anum, out Vector3 result); + + [DllImport("ode", EntryPoint = "dJointGetLMotorNumAxes"), SuppressUnmanagedCodeSecurity] + public static extern int JointGetLMotorNumAxes(IntPtr j); + + [DllImport("ode", EntryPoint = "dJointGetLMotorParam"), SuppressUnmanagedCodeSecurity] + public static extern dReal JointGetLMotorParam(IntPtr j, int parameter); + + [DllImport("ode", EntryPoint = "dJointGetPRAnchor"), SuppressUnmanagedCodeSecurity] + public static extern void JointGetPRAnchor(IntPtr j, out Vector3 result); + + [DllImport("ode", EntryPoint = "dJointGetPRAxis1"), SuppressUnmanagedCodeSecurity] + public static extern void JointGetPRAxis1(IntPtr j, out Vector3 result); + + [DllImport("ode", EntryPoint = "dJointGetPRAxis2"), SuppressUnmanagedCodeSecurity] + public static extern void JointGetPRAxis2(IntPtr j, out Vector3 result); + + [DllImport("ode", EntryPoint = "dJointGetPRParam"), SuppressUnmanagedCodeSecurity] + public static extern dReal JointGetPRParam(IntPtr j, int parameter); + + [DllImport("ode", EntryPoint = "dJointGetPRPosition"), SuppressUnmanagedCodeSecurity] + public static extern dReal JointGetPRPosition(IntPtr j); + + [DllImport("ode", EntryPoint = "dJointGetPRPositionRate"), SuppressUnmanagedCodeSecurity] + public static extern dReal JointGetPRPositionRate(IntPtr j); + + [DllImport("ode", EntryPoint = "dJointGetSliderAxis"), SuppressUnmanagedCodeSecurity] + public static extern void JointGetSliderAxis(IntPtr j, out Vector3 result); + + [DllImport("ode", EntryPoint = "dJointGetSliderParam"), SuppressUnmanagedCodeSecurity] + public static extern dReal JointGetSliderParam(IntPtr j, int parameter); + + [DllImport("ode", EntryPoint = "dJointGetSliderPosition"), SuppressUnmanagedCodeSecurity] + public static extern dReal JointGetSliderPosition(IntPtr j); + + [DllImport("ode", EntryPoint = "dJointGetSliderPositionRate"), SuppressUnmanagedCodeSecurity] + public static extern dReal JointGetSliderPositionRate(IntPtr j); + + [DllImport("ode", EntryPoint = "dJointGetType"), SuppressUnmanagedCodeSecurity] + public static extern JointType JointGetType(IntPtr j); + + [DllImport("ode", EntryPoint = "dJointGetUniversalAnchor"), SuppressUnmanagedCodeSecurity] + public static extern void JointGetUniversalAnchor(IntPtr j, out Vector3 result); + + [DllImport("ode", EntryPoint = "dJointGetUniversalAnchor2"), SuppressUnmanagedCodeSecurity] + public static extern void JointGetUniversalAnchor2(IntPtr j, out Vector3 result); + + [DllImport("ode", EntryPoint = "dJointGetUniversalAngle1"), SuppressUnmanagedCodeSecurity] + public static extern dReal JointGetUniversalAngle1(IntPtr j); + + [DllImport("ode", EntryPoint = "dJointGetUniversalAngle1Rate"), SuppressUnmanagedCodeSecurity] + public static extern dReal JointGetUniversalAngle1Rate(IntPtr j); + + [DllImport("ode", EntryPoint = "dJointGetUniversalAngle2"), SuppressUnmanagedCodeSecurity] + public static extern dReal JointGetUniversalAngle2(IntPtr j); + + [DllImport("ode", EntryPoint = "dJointGetUniversalAngle2Rate"), SuppressUnmanagedCodeSecurity] + public static extern dReal JointGetUniversalAngle2Rate(IntPtr j); + + [DllImport("ode", EntryPoint = "dJointGetUniversalAngles"), SuppressUnmanagedCodeSecurity] + public static extern void JointGetUniversalAngles(IntPtr j, out dReal angle1, out dReal angle2); + + [DllImport("ode", EntryPoint = "dJointGetUniversalAxis1"), SuppressUnmanagedCodeSecurity] + public static extern void JointGetUniversalAxis1(IntPtr j, out Vector3 result); + + [DllImport("ode", EntryPoint = "dJointGetUniversalAxis2"), SuppressUnmanagedCodeSecurity] + public static extern void JointGetUniversalAxis2(IntPtr j, out Vector3 result); + + [DllImport("ode", EntryPoint = "dJointGetUniversalParam"), SuppressUnmanagedCodeSecurity] + public static extern dReal JointGetUniversalParam(IntPtr j, int parameter); + + [DllImport("ode", EntryPoint = "dJointGroupCreate"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr JointGroupCreate(int max_size); + + [DllImport("ode", EntryPoint = "dJointGroupDestroy"), SuppressUnmanagedCodeSecurity] + public static extern void JointGroupDestroy(IntPtr group); + + [DllImport("ode", EntryPoint = "dJointGroupEmpty"), SuppressUnmanagedCodeSecurity] + public static extern void JointGroupEmpty(IntPtr group); + + [DllImport("ode", EntryPoint = "dJointSetAMotorAngle"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetAMotorAngle(IntPtr j, int anum, dReal angle); + + [DllImport("ode", EntryPoint = "dJointSetAMotorAxis"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetAMotorAxis(IntPtr j, int anum, int rel, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dJointSetAMotorMode"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetAMotorMode(IntPtr j, int mode); + + [DllImport("ode", EntryPoint = "dJointSetAMotorNumAxes"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetAMotorNumAxes(IntPtr group, int num); + + [DllImport("ode", EntryPoint = "dJointSetAMotorParam"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetAMotorParam(IntPtr group, int parameter, dReal value); + + [DllImport("ode", EntryPoint = "dJointSetBallAnchor"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetBallAnchor(IntPtr j, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dJointSetBallAnchor2"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetBallAnchor2(IntPtr j, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dJointSetData"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetData(IntPtr j, IntPtr data); + + [DllImport("ode", EntryPoint = "dJointSetFeedback"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetFeedback(IntPtr j, out JointFeedback feedback); + + [DllImport("ode", EntryPoint = "dJointSetFixed"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetFixed(IntPtr j); + + [DllImport("ode", EntryPoint = "dJointSetHingeAnchor"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetHingeAnchor(IntPtr j, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dJointSetHingeAnchorDelta"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetHingeAnchorDelta(IntPtr j, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az); + + [DllImport("ode", EntryPoint = "dJointSetHingeAxis"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetHingeAxis(IntPtr j, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dJointSetHingeParam"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetHingeParam(IntPtr j, int parameter, dReal value); + + [DllImport("ode", EntryPoint = "dJointSetHinge2Anchor"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetHinge2Anchor(IntPtr j, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dJointSetHinge2Axis1"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetHinge2Axis1(IntPtr j, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dJointSetHinge2Axis2"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetHinge2Axis2(IntPtr j, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dJointSetHinge2Param"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetHinge2Param(IntPtr j, int parameter, dReal value); + + [DllImport("ode", EntryPoint = "dJointSetLMotorAxis"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetLMotorAxis(IntPtr j, int anum, int rel, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dJointSetLMotorNumAxes"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetLMotorNumAxes(IntPtr j, int num); + + [DllImport("ode", EntryPoint = "dJointSetLMotorParam"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetLMotorParam(IntPtr j, int parameter, dReal value); + + [DllImport("ode", EntryPoint = "dJointSetPlane2DAngleParam"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetPlane2DAngleParam(IntPtr j, int parameter, dReal value); + + [DllImport("ode", EntryPoint = "dJointSetPlane2DXParam"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetPlane2DXParam(IntPtr j, int parameter, dReal value); + + [DllImport("ode", EntryPoint = "dJointSetPlane2DYParam"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetPlane2DYParam(IntPtr j, int parameter, dReal value); + + [DllImport("ode", EntryPoint = "dJointSetPRAnchor"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetPRAnchor(IntPtr j, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dJointSetPRAxis1"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetPRAxis1(IntPtr j, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dJointSetPRAxis2"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetPRAxis2(IntPtr j, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dJointSetPRParam"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetPRParam(IntPtr j, int parameter, dReal value); + + [DllImport("ode", EntryPoint = "dJointSetSliderAxis"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetSliderAxis(IntPtr j, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dJointSetSliderAxisDelta"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetSliderAxisDelta(IntPtr j, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az); + + [DllImport("ode", EntryPoint = "dJointSetSliderParam"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetSliderParam(IntPtr j, int parameter, dReal value); + + [DllImport("ode", EntryPoint = "dJointSetUniversalAnchor"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetUniversalAnchor(IntPtr j, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dJointSetUniversalAxis1"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetUniversalAxis1(IntPtr j, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dJointSetUniversalAxis2"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetUniversalAxis2(IntPtr j, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dJointSetUniversalParam"), SuppressUnmanagedCodeSecurity] + public static extern void JointSetUniversalParam(IntPtr j, int parameter, dReal value); + + [DllImport("ode", EntryPoint = "dLDLTAddTL"), SuppressUnmanagedCodeSecurity] + public static extern void LDLTAddTL(ref dReal L, ref dReal d, ref dReal a, int n, int nskip); + + [DllImport("ode", EntryPoint = "dMassAdd"), SuppressUnmanagedCodeSecurity] + public static extern void MassAdd(ref Mass a, ref Mass b); + + [DllImport("ode", EntryPoint = "dMassAdjust"), SuppressUnmanagedCodeSecurity] + public static extern void MassAdjust(ref Mass m, dReal newmass); + + [DllImport("ode", EntryPoint = "dMassCheck"), SuppressUnmanagedCodeSecurity] + public static extern bool MassCheck(ref Mass m); + + [DllImport("ode", EntryPoint = "dMassRotate"), SuppressUnmanagedCodeSecurity] + public static extern void MassRotate(out Mass mass, ref Matrix3 R); + + [DllImport("ode", EntryPoint = "dMassRotate"), SuppressUnmanagedCodeSecurity] + public static extern void MassRotate(out Mass mass, ref dReal M00); + + [DllImport("ode", EntryPoint = "dMassSetBox"), SuppressUnmanagedCodeSecurity] + public static extern void MassSetBox(out Mass mass, dReal density, dReal lx, dReal ly, dReal lz); + + [DllImport("ode", EntryPoint = "dMassSetBoxTotal"), SuppressUnmanagedCodeSecurity] + public static extern void MassSetBoxTotal(out Mass mass, dReal total_mass, dReal lx, dReal ly, dReal lz); + + [DllImport("ode", EntryPoint = "dMassSetCapsule"), SuppressUnmanagedCodeSecurity] + public static extern void MassSetCapsule(out Mass mass, dReal density, int direction, dReal radius, dReal length); + + [DllImport("ode", EntryPoint = "dMassSetCapsuleTotal"), SuppressUnmanagedCodeSecurity] + public static extern void MassSetCapsuleTotal(out Mass mass, dReal total_mass, int direction, dReal radius, dReal length); + + [DllImport("ode", EntryPoint = "dMassSetCylinder"), SuppressUnmanagedCodeSecurity] + public static extern void MassSetCylinder(out Mass mass, dReal density, int direction, dReal radius, dReal length); + + [DllImport("ode", EntryPoint = "dMassSetCylinderTotal"), SuppressUnmanagedCodeSecurity] + public static extern void MassSetCylinderTotal(out Mass mass, dReal total_mass, int direction, dReal radius, dReal length); + + [DllImport("ode", EntryPoint = "dMassSetParameters"), SuppressUnmanagedCodeSecurity] + public static extern void MassSetParameters(out Mass mass, dReal themass, + dReal cgx, dReal cgy, dReal cgz, + dReal i11, dReal i22, dReal i33, + dReal i12, dReal i13, dReal i23); + + [DllImport("ode", EntryPoint = "dMassSetSphere"), SuppressUnmanagedCodeSecurity] + public static extern void MassSetSphere(out Mass mass, dReal density, dReal radius); + + [DllImport("ode", EntryPoint = "dMassSetSphereTotal"), SuppressUnmanagedCodeSecurity] + public static extern void dMassSetSphereTotal(out Mass mass, dReal total_mass, dReal radius); + + [DllImport("ode", EntryPoint = "dMassSetTrimesh"), SuppressUnmanagedCodeSecurity] + public static extern void MassSetTrimesh(out Mass mass, dReal density, IntPtr g); + + [DllImport("ode", EntryPoint = "dMassSetZero"), SuppressUnmanagedCodeSecurity] + public static extern void MassSetZero(out Mass mass); + + [DllImport("ode", EntryPoint = "dMassTranslate"), SuppressUnmanagedCodeSecurity] + public static extern void MassTranslate(out Mass mass, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dMultiply0"), SuppressUnmanagedCodeSecurity] + public static extern void Multiply0(out dReal A00, ref dReal B00, ref dReal C00, int p, int q, int r); + + [DllImport("ode", EntryPoint = "dMultiply1"), SuppressUnmanagedCodeSecurity] + public static extern void Multiply1(out dReal A00, ref dReal B00, ref dReal C00, int p, int q, int r); + + [DllImport("ode", EntryPoint = "dMultiply2"), SuppressUnmanagedCodeSecurity] + public static extern void Multiply2(out dReal A00, ref dReal B00, ref dReal C00, int p, int q, int r); + + [DllImport("ode", EntryPoint = "dQFromAxisAndAngle"), SuppressUnmanagedCodeSecurity] + public static extern void QFromAxisAndAngle(out Quaternion q, dReal ax, dReal ay, dReal az, dReal angle); + + [DllImport("ode", EntryPoint = "dQfromR"), SuppressUnmanagedCodeSecurity] + public static extern void QfromR(out Quaternion q, ref Matrix3 R); + + [DllImport("ode", EntryPoint = "dQMultiply0"), SuppressUnmanagedCodeSecurity] + public static extern void QMultiply0(out Quaternion qa, ref Quaternion qb, ref Quaternion qc); + + [DllImport("ode", EntryPoint = "dQMultiply1"), SuppressUnmanagedCodeSecurity] + public static extern void QMultiply1(out Quaternion qa, ref Quaternion qb, ref Quaternion qc); + + [DllImport("ode", EntryPoint = "dQMultiply2"), SuppressUnmanagedCodeSecurity] + public static extern void QMultiply2(out Quaternion qa, ref Quaternion qb, ref Quaternion qc); + + [DllImport("ode", EntryPoint = "dQMultiply3"), SuppressUnmanagedCodeSecurity] + public static extern void QMultiply3(out Quaternion qa, ref Quaternion qb, ref Quaternion qc); + + [DllImport("ode", EntryPoint = "dQSetIdentity"), SuppressUnmanagedCodeSecurity] + public static extern void QSetIdentity(out Quaternion q); + + [DllImport("ode", EntryPoint = "dQuadTreeSpaceCreate"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr QuadTreeSpaceCreate(IntPtr space, ref Vector3 center, ref Vector3 extents, int depth); + + [DllImport("ode", EntryPoint = "dQuadTreeSpaceCreate"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr QuadTreeSpaceCreate(IntPtr space, ref dReal centerX, ref dReal extentsX, int depth); + + [DllImport("ode", EntryPoint = "dRandReal"), SuppressUnmanagedCodeSecurity] + public static extern dReal RandReal(); + + [DllImport("ode", EntryPoint = "dRFrom2Axes"), SuppressUnmanagedCodeSecurity] + public static extern void RFrom2Axes(out Matrix3 R, dReal ax, dReal ay, dReal az, dReal bx, dReal by, dReal bz); + + [DllImport("ode", EntryPoint = "dRFromAxisAndAngle"), SuppressUnmanagedCodeSecurity] + public static extern void RFromAxisAndAngle(out Matrix3 R, dReal x, dReal y, dReal z, dReal angle); + + [DllImport("ode", EntryPoint = "dRFromEulerAngles"), SuppressUnmanagedCodeSecurity] + public static extern void RFromEulerAngles(out Matrix3 R, dReal phi, dReal theta, dReal psi); + + [DllImport("ode", EntryPoint = "dRfromQ"), SuppressUnmanagedCodeSecurity] + public static extern void RfromQ(out Matrix3 R, ref Quaternion q); + + [DllImport("ode", EntryPoint = "dRFromZAxis"), SuppressUnmanagedCodeSecurity] + public static extern void RFromZAxis(out Matrix3 R, dReal ax, dReal ay, dReal az); + + [DllImport("ode", EntryPoint = "dRSetIdentity"), SuppressUnmanagedCodeSecurity] + public static extern void RSetIdentity(out Matrix3 R); + + [DllImport("ode", EntryPoint = "dSetValue"), SuppressUnmanagedCodeSecurity] + public static extern void SetValue(out dReal a, int n); + + [DllImport("ode", EntryPoint = "dSetZero"), SuppressUnmanagedCodeSecurity] + public static extern void SetZero(out dReal a, int n); + + [DllImport("ode", EntryPoint = "dSimpleSpaceCreate"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr SimpleSpaceCreate(IntPtr space); + + [DllImport("ode", EntryPoint = "dSolveCholesky"), SuppressUnmanagedCodeSecurity] + public static extern void SolveCholesky(ref dReal L, out dReal b, int n); + + [DllImport("ode", EntryPoint = "dSolveL1"), SuppressUnmanagedCodeSecurity] + public static extern void SolveL1(ref dReal L, out dReal b, int n, int nskip); + + [DllImport("ode", EntryPoint = "dSolveL1T"), SuppressUnmanagedCodeSecurity] + public static extern void SolveL1T(ref dReal L, out dReal b, int n, int nskip); + + [DllImport("ode", EntryPoint = "dSolveLDLT"), SuppressUnmanagedCodeSecurity] + public static extern void SolveLDLT(ref dReal L, ref dReal d, out dReal b, int n, int nskip); + + [DllImport("ode", EntryPoint = "dSpaceAdd"), SuppressUnmanagedCodeSecurity] + public static extern void SpaceAdd(IntPtr space, IntPtr geom); + + [DllImport("ode", EntryPoint = "dSpaceClean"), SuppressUnmanagedCodeSecurity] + public static extern void SpaceClean(IntPtr space); + + [DllImport("ode", EntryPoint = "dSpaceCollide"), SuppressUnmanagedCodeSecurity] + public static extern void SpaceCollide(IntPtr space, IntPtr data, NearCallback callback); + + [DllImport("ode", EntryPoint = "dSpaceCollide2"), SuppressUnmanagedCodeSecurity] + public static extern void SpaceCollide2(IntPtr space1, IntPtr space2, IntPtr data, NearCallback callback); + + [DllImport("ode", EntryPoint = "dSpaceDestroy"), SuppressUnmanagedCodeSecurity] + public static extern void SpaceDestroy(IntPtr space); + + [DllImport("ode", EntryPoint = "dSpaceGetCleanup"), SuppressUnmanagedCodeSecurity] + public static extern bool SpaceGetCleanup(IntPtr space); + + [DllImport("ode", EntryPoint = "dSpaceGetNumGeoms"), SuppressUnmanagedCodeSecurity] + public static extern int SpaceGetNumGeoms(IntPtr space); + + [DllImport("ode", EntryPoint = "dSpaceGetGeom"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr SpaceGetGeom(IntPtr space, int i); + + [DllImport("ode", EntryPoint = "dSpaceQuery"), SuppressUnmanagedCodeSecurity] + public static extern bool SpaceQuery(IntPtr space, IntPtr geom); + + [DllImport("ode", EntryPoint = "dSpaceRemove"), SuppressUnmanagedCodeSecurity] + public static extern void SpaceRemove(IntPtr space, IntPtr geom); + + [DllImport("ode", EntryPoint = "dSpaceSetCleanup"), SuppressUnmanagedCodeSecurity] + public static extern void SpaceSetCleanup(IntPtr space, bool mode); + + [DllImport("ode", EntryPoint = "dVectorScale"), SuppressUnmanagedCodeSecurity] + public static extern void VectorScale(out dReal a, ref dReal d, int n); + + [DllImport("ode", EntryPoint = "dWorldCreate"), SuppressUnmanagedCodeSecurity] + public static extern IntPtr WorldCreate(); + + [DllImport("ode", EntryPoint = "dWorldDestroy"), SuppressUnmanagedCodeSecurity] + public static extern void WorldDestroy(IntPtr world); + + [DllImport("ode", EntryPoint = "dWorldGetAutoDisableAngularThreshold"), SuppressUnmanagedCodeSecurity] + public static extern dReal WorldGetAutoDisableAngularThreshold(IntPtr world); + + [DllImport("ode", EntryPoint = "dWorldGetAutoDisableFlag"), SuppressUnmanagedCodeSecurity] + public static extern bool WorldGetAutoDisableFlag(IntPtr world); + + [DllImport("ode", EntryPoint = "dWorldGetAutoDisableLinearThreshold"), SuppressUnmanagedCodeSecurity] + public static extern dReal WorldGetAutoDisableLinearThreshold(IntPtr world); + + [DllImport("ode", EntryPoint = "dWorldGetAutoDisableSteps"), SuppressUnmanagedCodeSecurity] + public static extern int WorldGetAutoDisableSteps(IntPtr world); + + [DllImport("ode", EntryPoint = "dWorldGetAutoDisableTime"), SuppressUnmanagedCodeSecurity] + public static extern dReal WorldGetAutoDisableTime(IntPtr world); + + [DllImport("ode", EntryPoint = "dWorldGetAutoEnableDepthSF1"), SuppressUnmanagedCodeSecurity] + public static extern int WorldGetAutoEnableDepthSF1(IntPtr world); + + [DllImport("ode", EntryPoint = "dWorldGetCFM"), SuppressUnmanagedCodeSecurity] + public static extern dReal WorldGetCFM(IntPtr world); + + [DllImport("ode", EntryPoint = "dWorldGetERP"), SuppressUnmanagedCodeSecurity] + public static extern dReal WorldGetERP(IntPtr world); + + [DllImport("ode", EntryPoint = "dWorldGetGravity"), SuppressUnmanagedCodeSecurity] + public static extern void WorldGetGravity(IntPtr world, out Vector3 gravity); + + [DllImport("ode", EntryPoint = "dWorldGetGravity"), SuppressUnmanagedCodeSecurity] + public static extern void WorldGetGravity(IntPtr world, out dReal X); + + [DllImport("ode", EntryPoint = "dWorldGetContactMaxCorrectingVel"), SuppressUnmanagedCodeSecurity] + public static extern dReal WorldGetContactMaxCorrectingVel(IntPtr world); + + [DllImport("ode", EntryPoint = "dWorldGetContactSurfaceLayer"), SuppressUnmanagedCodeSecurity] + public static extern dReal WorldGetContactSurfaceLayer(IntPtr world); + + [DllImport("ode", EntryPoint = "dWorldGetQuickStepNumIterations"), SuppressUnmanagedCodeSecurity] + public static extern int WorldGetQuickStepNumIterations(IntPtr world); + + [DllImport("ode", EntryPoint = "dWorldGetQuickStepW"), SuppressUnmanagedCodeSecurity] + public static extern dReal WorldGetQuickStepW(IntPtr world); + + [DllImport("ode", EntryPoint = "dWorldImpulseToForce"), SuppressUnmanagedCodeSecurity] + public static extern void WorldImpulseToForce(IntPtr world, dReal stepsize, dReal ix, dReal iy, dReal iz, out Vector3 force); + + [DllImport("ode", EntryPoint = "dWorldImpulseToForce"), SuppressUnmanagedCodeSecurity] + public static extern void WorldImpulseToForce(IntPtr world, dReal stepsize, dReal ix, dReal iy, dReal iz, out dReal forceX); + + [DllImport("ode", EntryPoint = "dWorldQuickStep"), SuppressUnmanagedCodeSecurity] + public static extern void WorldQuickStep(IntPtr world, dReal stepsize); + + [DllImport("ode", EntryPoint = "dWorldSetAutoDisableAngularThreshold"), SuppressUnmanagedCodeSecurity] + public static extern void WorldSetAutoDisableAngularThreshold(IntPtr world, dReal angular_threshold); + + [DllImport("ode", EntryPoint = "dWorldSetAutoDisableFlag"), SuppressUnmanagedCodeSecurity] + public static extern void WorldSetAutoDisableFlag(IntPtr world, bool do_auto_disable); + + [DllImport("ode", EntryPoint = "dWorldSetAutoDisableLinearThreshold"), SuppressUnmanagedCodeSecurity] + public static extern void WorldSetAutoDisableLinearThreshold(IntPtr world, dReal linear_threshold); + + [DllImport("ode", EntryPoint = "dWorldSetAutoDisableSteps"), SuppressUnmanagedCodeSecurity] + public static extern void WorldSetAutoDisableSteps(IntPtr world, int steps); + + [DllImport("ode", EntryPoint = "dWorldSetAutoDisableTime"), SuppressUnmanagedCodeSecurity] + public static extern void WorldSetAutoDisableTime(IntPtr world, dReal time); + + [DllImport("ode", EntryPoint = "dWorldSetAutoEnableDepthSF1"), SuppressUnmanagedCodeSecurity] + public static extern void WorldSetAutoEnableDepthSF1(IntPtr world, int autoEnableDepth); + + [DllImport("ode", EntryPoint = "dWorldSetCFM"), SuppressUnmanagedCodeSecurity] + public static extern void WorldSetCFM(IntPtr world, dReal cfm); + + [DllImport("ode", EntryPoint = "dWorldSetContactMaxCorrectingVel"), SuppressUnmanagedCodeSecurity] + public static extern void WorldSetContactMaxCorrectingVel(IntPtr world, dReal vel); + + [DllImport("ode", EntryPoint = "dWorldSetContactSurfaceLayer"), SuppressUnmanagedCodeSecurity] + public static extern void WorldSetContactSurfaceLayer(IntPtr world, dReal depth); + + [DllImport("ode", EntryPoint = "dWorldSetERP"), SuppressUnmanagedCodeSecurity] + public static extern void WorldSetERP(IntPtr world, dReal erp); + + [DllImport("ode", EntryPoint = "dWorldSetGravity"), SuppressUnmanagedCodeSecurity] + public static extern void WorldSetGravity(IntPtr world, dReal x, dReal y, dReal z); + + [DllImport("ode", EntryPoint = "dWorldSetQuickStepNumIterations"), SuppressUnmanagedCodeSecurity] + public static extern void WorldSetQuickStepNumIterations(IntPtr world, int num); + + [DllImport("ode", EntryPoint = "dWorldSetQuickStepW"), SuppressUnmanagedCodeSecurity] + public static extern void WorldSetQuickStepW(IntPtr world, dReal over_relaxation); + + [DllImport("ode", EntryPoint = "dWorldStep"), SuppressUnmanagedCodeSecurity] + public static extern void WorldStep(IntPtr world, dReal stepsize); + + [DllImport("ode", EntryPoint = "dWorldStepFast1"), SuppressUnmanagedCodeSecurity] + public static extern void WorldStepFast1(IntPtr world, dReal stepsize, int maxiterations); + } +} diff --git a/libraries/ode-0.9/contrib/Ode.NET/Ode/premake.lua b/libraries/ode-0.9/contrib/Ode.NET/Ode/premake.lua new file mode 100644 index 0000000000..b53d54cfa8 --- /dev/null +++ b/libraries/ode-0.9/contrib/Ode.NET/Ode/premake.lua @@ -0,0 +1,31 @@ +package.name = "Ode.NET" +package.kind = "dll" +package.language = "c#" + +-- Build options + + package.defines = { } + + if (options["with-doubles"]) then + table.insert(package.defines, "dDOUBLE") + else + table.insert(package.defines, "dSINGLE") + end + + if (options["no-unsafe"]) then + table.insert(package.defines, "dNO_UNSAFE_CODE") + else + package.buildflags = { "unsafe" } + end + + +-- Files & Libraries + + package.files = { + "AssemblyInfo.cs", + "Ode.cs" + } + + package.links = { + "System" + } diff --git a/libraries/ode-0.9/contrib/Ode.NET/README.TXT b/libraries/ode-0.9/contrib/Ode.NET/README.TXT new file mode 100644 index 0000000000..e6f1262829 --- /dev/null +++ b/libraries/ode-0.9/contrib/Ode.NET/README.TXT @@ -0,0 +1,73 @@ +Ode.NET - .NET bindings for ODE +Jason Perkins (starkos@gmail.com) + + THIS IS A WORK IN PROGRESS! I'm not done yet! + + +--------------------------------------------------------------------- + INSTALLATION +--------------------------------------------------------------------- + + Note that this binding uses a C# 2.0 feature (the + UnmanagedFunctionPointer attribute). You will need to use + Visual Studio 2005 (C# Express is fine) or Mono's gmcs + compiler. + + Start by getting or building ODE as a shared library (DLL). + + The simplest way to build the bindings is probably to create a + new library assembly in your tool of choice and drop in the files + Ode/Ode.cs and Ode/AssemblyInfo.cs. Define the symbol`dDOUBLE` if + you used double-precision math in your ode.dll. Build, done. + + For testing purposes, I have also created bindings for the + Drawstuff library and a C# version of the BoxStack demo. You can + throw all of these files into a console executable and run it to + see the demo. + + If you happen to have Premake installed (http://premake.sf.net/), + you can generate build scripts for the library with: + + premake --target (toolset) # for single precision + premake --with-doubles --target (toolset) # for double precision + + To build the test application too, use: + + premake --with-tests --target (toolset) + + To build with Mono, you must add the --dotnet parameter to enable + support .NET 2.0: + + premake --dotnet mono2 --target gnu + + +--------------------------------------------------------------------- + USAGE +--------------------------------------------------------------------- + + I have tried to keep things as close to the original C API as I can, + rather than forcing a class structure on everyone. Everything is + contained within the `Ode.NET` namespace inside a static class + named `d`. All ODE IDs are replaced with IntPtrs. A quick example: + + using Ode.NET; + + IntPtr world = d.WorldCreate(); + IntPtr body = d.BodyCreate(world); + + Take a look at Tests/BoxStack.cs for a more complete example. + + +--------------------------------------------------------------------- + KNOWN ISSUES +--------------------------------------------------------------------- + + I'm not done yet, so many functions are still missing. + + It is not possible to implement dBodyGetPosition(), dBodyGetRotation(), + etc. without resorting to unsafe code, which I was trying to avoid. + This binding uses the .NET friendly dBodyCopyPosition(), + dBodyCopyRotation(), etc. instead. + + Collision response (contact joints) do not work when built under + Mono as double-precision. I have not tried to track down why. diff --git a/libraries/ode-0.9/contrib/Ode.NET/Tests/BoxStack.cs b/libraries/ode-0.9/contrib/Ode.NET/Tests/BoxStack.cs new file mode 100644 index 0000000000..10771246e7 --- /dev/null +++ b/libraries/ode-0.9/contrib/Ode.NET/Tests/BoxStack.cs @@ -0,0 +1,260 @@ +using System; +using System.Collections.Generic; +using Drawstuff.NET; + +namespace Ode.NET +{ +#if dDOUBLE + using dReal = System.Double; +#else + using dReal = System.Single; +#endif + + public class TestBoxStack + { + #region Description of convex shape + + static dReal[] planes = + { + 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 + }; + + static dReal[] points = + { + 0.25f, 0.25f, 0.25f, + -0.25f, 0.25f, 0.25f, + 0.25f, -0.25f, 0.25f, + -0.25f, -0.25f, 0.25f, + 0.25f, 0.25f, -0.25f, + -0.25f,0.25f,-0.25f, + 0.25f,-0.25f,-0.25f, + -0.25f,-0.25f,-0.25f, + }; + + static int[] polygons = + { + 4, 0, 2, 6, 4, + 4, 1, 0, 4, 5, + 4, 0, 1, 3, 2, + 4, 3, 1, 5, 7, + 4, 2, 3, 7, 6, + 4, 5, 4, 6, 7, + }; + + #endregion + + const int NUM = 100; + const float DENSITY = 5.0f; + const int MAX_CONTACTS = 8; + + static IntPtr world; + static IntPtr space; + static IntPtr contactgroup; + + static Queue obj = new Queue(); + + static d.Vector3 xyz = new d.Vector3(2.1640f, -1.3079f, 1.7600f); + static d.Vector3 hpr = new d.Vector3(125.5000f, -17.0000f, 0.0000f); + + static d.NearCallback nearCallback = near; + static d.ContactGeom[] contacts = new d.ContactGeom[MAX_CONTACTS]; + static d.Contact contact; + + + // Called when window is opened - sets up viewpoint and prints usage + static void start(int unused) + { + ds.SetViewpoint(ref xyz, ref hpr); + Console.WriteLine("To drop another object, press:"); + Console.WriteLine(" b for box."); + Console.WriteLine(" s for sphere."); + Console.WriteLine(" c for capsule."); + Console.WriteLine(" y for cylinder."); + Console.WriteLine(" v for a convex object."); + Console.WriteLine(" x for a composite object."); + Console.WriteLine("To select an object, press space."); + Console.WriteLine("To disable the selected object, press d."); + Console.WriteLine("To enable the selected object, press e."); + Console.WriteLine("To toggle showing the geom AABBs, press a."); + Console.WriteLine("To toggle showing the contact points, press t."); + Console.WriteLine("To toggle dropping from random position/orientation, press r."); + Console.WriteLine("To save the current state to 'state.dif', press 1."); + } + + + // Near callback - creates contact joints + static void near(IntPtr space, IntPtr g1, IntPtr g2) + { + IntPtr b1 = d.GeomGetBody(g1); + IntPtr b2 = d.GeomGetBody(g2); + if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) + return; + + int count = d.Collide(g1, g2, MAX_CONTACTS, contacts, d.ContactGeom.SizeOf); + for (int i = 0; i < count; ++i) + { + contact.geom = contacts[i]; + IntPtr joint = d.JointCreateContact(world, contactgroup, ref contact); + d.JointAttach(joint, b1, b2); + } + } + + + // Adds a new object to the scene - attaches a body to the geom and + // sets the initial position and orientation + static void addObject(IntPtr geom, d.Mass mass) + { + // Create a body for this object + IntPtr body = d.BodyCreate(world); + d.GeomSetBody(geom, body); + d.BodySetMass(body, ref mass); + obj.Enqueue(geom); + + // Set the position of the new object + d.Matrix3 R; + d.BodySetPosition(body, d.RandReal() * 2 - 1, d.RandReal() * 2 - 1, d.RandReal() + 2); + d.RFromAxisAndAngle(out R, d.RandReal() * 2 - 1, d.RandReal() * 2 - 1, d.RandReal() * 2 - 1, d.RandReal() * 10 - 5); + d.BodySetRotation(body, ref R); + + // Cap the total number of objects + if (obj.Count > NUM) + { + geom = obj.Dequeue(); + body = d.GeomGetBody(geom); + d.BodyDestroy(body); + d.GeomDestroy(geom); + } + } + + + // Keyboard callback + static void command(int cmd) + { + IntPtr geom; + d.Mass mass; + d.Vector3 sides = new d.Vector3(d.RandReal() * 0.5f + 0.1f, d.RandReal() * 0.5f + 0.1f, d.RandReal() * 0.5f + 0.1f); + + Char ch = Char.ToLower((Char)cmd); + switch ((Char)ch) + { + case 'b': + d.MassSetBox(out mass, DENSITY, sides.X, sides.Y, sides.Z); + geom = d.CreateBox(space, sides.X, sides.Y, sides.Z); + addObject(geom, mass); + break; + + case 'c': + sides.X *= 0.5f; + d.MassSetCapsule(out mass, DENSITY, 3, sides.X, sides.Y); + geom = d.CreateCapsule(space, sides.X, sides.Y); + addObject(geom, mass); + break; + + case 'v': + d.MassSetBox(out mass, DENSITY, 0.25f, 0.25f, 0.25f); + geom = d.CreateConvex(space, planes, planes.Length / 4, points, points.Length / 3, polygons); + addObject(geom, mass); + break; + } + } + + + // Draw an object in the scene + static void drawGeom(IntPtr geom) + { + IntPtr body = d.GeomGetBody(geom); + + d.Vector3 pos; + d.BodyCopyPosition(body, out pos); + + d.Matrix3 R; + d.BodyCopyRotation(body, out R); + + d.GeomClassID type = d.GeomGetClass(geom); + switch (type) + { + case d.GeomClassID.BoxClass: + d.Vector3 sides; + d.GeomBoxGetLengths(geom, out sides); + ds.DrawBox(ref pos, ref R, ref sides); + break; + case d.GeomClassID.CapsuleClass: + dReal radius, length; + d.GeomCapsuleGetParams(geom, out radius, out length); + ds.DrawCapsule(ref pos, ref R, length, radius); + break; + case d.GeomClassID.ConvexClass: + ds.DrawConvex(ref pos, ref R, planes, planes.Length / 4, points, points.Length / 3, polygons); + break; + } + } + + + // Called once per frame; updates the scene + static void step(int pause) + { + d.SpaceCollide(space, IntPtr.Zero, nearCallback); + if (pause == 0) + d.WorldQuickStep(world, 0.02f); + d.JointGroupEmpty(contactgroup); + + ds.SetColor(1.0f, 1.0f, 0.0f); + ds.SetTexture(ds.Texture.Wood); + + foreach (IntPtr geom in obj) + { + drawGeom(geom); + } + } + + + static void Main(string[] args) + { + // Setup pointers to drawstuff callback functions + ds.Functions fn; + fn.version = ds.VERSION; + fn.start = new ds.CallbackFunction(start); + fn.step = new ds.CallbackFunction(step); + fn.command = new ds.CallbackFunction(command); + fn.stop = null; + fn.path_to_textures = "../../../../drawstuff/textures"; + if (args.Length > 0) + { + fn.path_to_textures = args[0]; + } + + // Set up contact response parameters + contact.surface.mode = d.ContactFlags.Bounce | d.ContactFlags.SoftCFM; + contact.surface.mu = d.Infinity; + contact.surface.mu2 = 0.0f; + contact.surface.bounce = 0.1f; + contact.surface.bounce_vel = 0.1f; + contact.surface.soft_cfm = 0.01f; + + // Initialize the scene + world = d.WorldCreate(); + space = d.HashSpaceCreate(IntPtr.Zero); + contactgroup = d.JointGroupCreate(0); + d.WorldSetGravity(world, 0.0f, 0.0f, -0.5f); + d.WorldSetCFM(world, 1e-5f); + d.WorldSetAutoDisableFlag(world, true); + d.WorldSetContactMaxCorrectingVel(world, 0.1f); + d.WorldSetContactSurfaceLayer(world, 0.001f); + d.CreatePlane(space, 0, 0, 1, 0); + + // Run the scene + ds.SimulationLoop(args.Length, args, 352, 288, ref fn); + + // Clean up + d.JointGroupDestroy(contactgroup); + d.SpaceDestroy(space); + d.WorldDestroy(world); + d.CloseODE(); + } + } +} diff --git a/libraries/ode-0.9/contrib/Ode.NET/Tests/premake.lua b/libraries/ode-0.9/contrib/Ode.NET/Tests/premake.lua new file mode 100644 index 0000000000..5253ae1759 --- /dev/null +++ b/libraries/ode-0.9/contrib/Ode.NET/Tests/premake.lua @@ -0,0 +1,27 @@ +-- This function creates the test packages +function maketest(name) + + package = newpackage() + package.name = name + package.kind = "exe" + package.language = "c#" + + if (options["with-doubles"]) then + package.defines = { "dDOUBLE" } + else + package.defines = { "dSINGLE " } + end + + package.links = { + "System", + "Ode.NET", + "Drawstuff.NET" + } + + package.files = { + name .. ".cs" + } + +end + +maketest("BoxStack") diff --git a/libraries/ode-0.9/contrib/Ode.NET/premake.lua b/libraries/ode-0.9/contrib/Ode.NET/premake.lua new file mode 100644 index 0000000000..c25a017ab7 --- /dev/null +++ b/libraries/ode-0.9/contrib/Ode.NET/premake.lua @@ -0,0 +1,29 @@ +project.name = "Ode.NET" + +-- Target checking + + if (target and target ~= "vs2005" and target ~= "gnu") then + error("Ode.NET requires a .NET 2.0 compiler") + end + + +-- Project options + + addoption("with-doubles", "Use double instead of float as base numeric type") + addoption("with-tests", "Builds the test applications and DrawStuff library") + addoption("no-unsafe", "Exclude functions using unsafe code (dBodyGetPosition, etc.)") + + +-- Build settings + + project.config["Debug"].bindir = "bin/Debug" + project.config["Release"].bindir = "bin/Release" + + +-- Packages + + if (options["with-tests"]) then + dopackage("Tests") + dopackage("Drawstuff") + end + dopackage("Ode") diff --git a/libraries/ode-0.9/contrib/OdeModelProcessor/LICENSE-BSD.TXT b/libraries/ode-0.9/contrib/OdeModelProcessor/LICENSE-BSD.TXT new file mode 100644 index 0000000000..b2b19952b7 --- /dev/null +++ b/libraries/ode-0.9/contrib/OdeModelProcessor/LICENSE-BSD.TXT @@ -0,0 +1,37 @@ + +This is the BSD-style license for The ODE Model Processor +---------------------------------------------------------- + +The ODE Model Processor +Copyright (c) 2007, Department Of Information Science, +University of Otago, Dunedin, New Zealand. +All rights reserved. + +Author: Richard Barrington + +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 the copyright owner nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/libraries/ode-0.9/contrib/OdeModelProcessor/LICENSE.TXT b/libraries/ode-0.9/contrib/OdeModelProcessor/LICENSE.TXT new file mode 100644 index 0000000000..cfe59bcadb --- /dev/null +++ b/libraries/ode-0.9/contrib/OdeModelProcessor/LICENSE.TXT @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + 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! diff --git a/libraries/ode-0.9/contrib/OdeModelProcessor/OdeModelProcessor.sln b/libraries/ode-0.9/contrib/OdeModelProcessor/OdeModelProcessor.sln new file mode 100644 index 0000000000..6a3f5214f8 --- /dev/null +++ b/libraries/ode-0.9/contrib/OdeModelProcessor/OdeModelProcessor.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual C# Express 2005 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OdeModelProcessor", "OdeModelProcessor\OdeModelProcessor.csproj", "{246F3075-FEE3-45F9-8CB6-47DADBFFD1F2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {246F3075-FEE3-45F9-8CB6-47DADBFFD1F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {246F3075-FEE3-45F9-8CB6-47DADBFFD1F2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {246F3075-FEE3-45F9-8CB6-47DADBFFD1F2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {246F3075-FEE3-45F9-8CB6-47DADBFFD1F2}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/libraries/ode-0.9/contrib/OdeModelProcessor/OdeModelProcessor/OdeModelProcessor.cs b/libraries/ode-0.9/contrib/OdeModelProcessor/OdeModelProcessor/OdeModelProcessor.cs new file mode 100644 index 0000000000..9c974eb425 --- /dev/null +++ b/libraries/ode-0.9/contrib/OdeModelProcessor/OdeModelProcessor/OdeModelProcessor.cs @@ -0,0 +1,354 @@ +/* + * The ODE Model Processor + * ----------------------- + * + * Copyright 2007, Department of Information Science, + * University of Otago, Dunedin, New Zealand. + * + * Author: Richard Barrington + * + * This is a Content Processor and Tag library written for use with + * Microsoft Visual C# 2005 Express Edition and Microsoft XNA Game + * Studio Express 1.0. + * + * It can be used to read .x model vertex and index data before + * insertion into the content pipeline. This is used to build ODE + * Triangle Meshes which are then used for collision detection that + * is more accurate than the default XNA bounding boxes or spheres. + * + * Usage is simple: + * Build the library and reference the DLL in your project. + * Add the DLL to the Content Pipeline + * Set the content processor for you .x models to OdeModelProcessor. + * + * Create triangle meshes as follows: + * 1) Create a space, but only one for all of models. + * 2) Create a triangle data. + * 3) Load the model. + * 4) Retreive the tag from the model. + * 6) Build the triangle mesh by calling d.GeomTriMeshDataBuildSimple. + * + * Eg: + * IntPtr space = d.SimpleSpaceCreate(IntPtr.Zero); + * IntPtr triangleData = d.GeomTriMeshDataCreate(); + * Model obj = content.Load("Content\\mycube"); + * OdeTag tag = (OdeTag)obj.Tag; + * IntPtr vertexArray = tag.getVertices(); + * IntPtr indexArray = tag.getIndices(); + * d.GeomTriMeshDataBuildSimple + * ( + * triangleData, + * vertexArray, tag.getVertexStride(), tag.getVertexCount(), + * indexArray, tag.getIndexCount(), tag.getIndexStride() + * ); + * IntPtr triangleMesh = d.CreateTriMesh(space, triangleData, null, null, null); + * + * You can load multiple models and test for collisions with something + * like this in the update method: + * + * d.GeomSetPosition(odeTri1, obj1Position.X, obj1Position.Y, obj1Position.Z); + * d.GeomSetPosition(odeTri2, obj2Position.X, obj2Position.Y, obj2Position.Z); + * int numberOfContacts = d.Collide(odeTri1, odeTri2, ODE_CONTACTS, + * contactGeom, d.ContactGeom.SizeOf); + * + * Where odeTri1 and odeTri2 are triangle meshes you've created, obj1Position + * and obj2Position are the positions of your rendered models in the scene, + * ODE_CONTACTS is a constant defining the maximum number of contacts + * to test for, contactGeom is a d.ContactGeom[] of length ODE_CONTACTS. + * + * If numberOfContacts is greater than 0, you have a collision. + * + * Other ODE functions such as d.SpaceCollide() also work; see ODE.NET BoxTest.cs. + * + * This library is free software; you can redistribute it and/or + * modify it under the same terms as the ODE and ODE.Net libraries. + * Specifically, the terms are one of EITHER: + * + * (1) The GNU Lesser General Public License as published by the Free + * Software Foundation; either version 2.1 of the License, or (at + * your option) any later version. The text of the GNU Lesser + * General Public License is included with this library in the + * file LICENSE.TXT. + * + * (2) The BSD-style license that is included with this library in + * the file LICENSE-BSD.TXT. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files + * LICENSE.TXT and LICENSE-BSD.TXT for more details. + * + */ + +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Design; +using Microsoft.Xna.Framework.Content.Pipeline; +using Microsoft.Xna.Framework.Content.Pipeline.Graphics; +using Microsoft.Xna.Framework.Content.Pipeline.Processors; +using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler; +using Ode.NET; +using System.Runtime.InteropServices; + +namespace OdeModelProcessor +{ + /* + * Container for vertex and index data in a format + * that ODE.Net can use + */ + public class OdeTag + { + + private float[] vertexData; + private int[] indexData; + private const int indexStride = (sizeof(int)); + private const int vertexStride = (3 * sizeof(float)); + + /* Constructors */ + public OdeTag() + { + vertexData = new float[0]; + indexData = new int[0]; + } + + public OdeTag(float[] vertexData, int[] indexData) + { + this.vertexData = vertexData; + this.indexData = indexData; + } + + /* Data setter */ + public void setData(float[] vertexData, int[] indexData) + { + this.vertexData = vertexData; + this.indexData = indexData; + } + + /* Data appenders */ + public void appendVertexData(float[] vertexData) + { + int newVertexDataLength = vertexData.Length; + float[] tempVertexArray = new float[newVertexDataLength + this.vertexData.Length]; + this.vertexData.CopyTo(tempVertexArray, 0); + vertexData.CopyTo(tempVertexArray, this.vertexData.Length); + this.vertexData = tempVertexArray; + } + + public void appendIndexData(int[] indexData) + { + int newIndexDataLength = indexData.Length; + int[] tempIndexArray = new int[newIndexDataLength + this.indexData.Length]; + this.indexData.CopyTo(tempIndexArray, 0); + indexData.CopyTo(tempIndexArray, this.indexData.Length); + this.indexData = tempIndexArray; + } + + /* Data getters */ + public float[] getVertexData() + { + return this.vertexData; + } + + public int[] getIndexData() + { + return this.indexData; + } + + /* Native data getters */ + public IntPtr getVertices() + { + int count = getVertexData().Length; + int memsize = count * Marshal.SizeOf(getVertexData()[0].GetType()); + IntPtr pointer = Marshal.AllocCoTaskMem(memsize); + Marshal.Copy(getVertexData(), 0, pointer, count); + return pointer; + } + + public IntPtr getIndices() + { + int count = getIndexData().Length; + int memsize = count * Marshal.SizeOf(getIndexData()[0].GetType()); + IntPtr pointer = Marshal.AllocCoTaskMem(memsize); + Marshal.Copy(getIndexData(), 0, pointer, count); + return pointer; + } + + /* Count getters */ + public int getVertexCount() + { + return vertexData.Length/3; + } + + public int getIndexCount() + { + return indexData.Length; + } + + /* Stride getters */ + public int getVertexStride() + { + return vertexStride; + } + + public int getIndexStride() + { + return indexStride; + } + + /* + * Convienience method to build the mesh and return it. The triangleData + * is passed in to allow the calling application to delete it afterwards. + * + * Be sure to destroy the returned TriangleMesh in the client application. + * + * Can't destroy the index and vertex arrays here though, so best to handle + * this manually - only use this method if nothing else makes sense. + */ + public IntPtr getTriangleMesh(IntPtr space, IntPtr triangleData) + { + d.GeomTriMeshDataBuildSimple( + triangleData, + getVertices(), getVertexStride(), getVertexCount(), + getIndices(), getIndexCount(), getIndexStride() + ); + return d.CreateTriMesh(space, triangleData, null, null, null); + } + + } + + /* + * Subclass of the XNA .x model processor, which creates and appends a tag + * containing vertex and index data for ODE.Net to use. + */ + [ContentProcessor] + public class OdeModelProcessor : ModelProcessor + { + private OdeTag tag; + private int indexOffset = 0; + + public override ModelContent Process(NodeContent input, ContentProcessorContext context) + { + tag = new OdeTag(); + GenerateVerticesRecursive( input ); + ModelContent model = base.Process(input, context); + model.Tag = tag; + indexOffset = 0; + return model; + } + + public void GenerateVerticesRecursive(NodeContent input) + { + + MeshContent mesh = input as MeshContent; + + if (mesh != null) + { + GeometryContentCollection gc = mesh.Geometry; + foreach (GeometryContent g in gc) + { + VertexContent vc = g.Vertices; + IndirectPositionCollection ipc = vc.Positions; + IndexCollection ic = g.Indices; + + float[] vertexData = new float[ipc.Count * 3]; + for (int i = 0; i < ipc.Count; i++) + { + + Vector3 v0 = ipc[i]; + vertexData[(i * 3) + 0] = v0.X; + vertexData[(i * 3) + 1] = v0.Y; + vertexData[(i * 3) + 2] = v0.Z; + + } + + int[] indexData = new int[ic.Count]; + for (int j = 0; j < ic.Count; j ++) + { + + indexData[j] = ic[j] + indexOffset; + + } + + tag.appendVertexData(vertexData); + tag.appendIndexData(indexData); + indexOffset += ipc.Count; + } + + } + + foreach (NodeContent child in input.Children) + { + GenerateVerticesRecursive(child); + } + + } + + } + + /* Writer for the OdeTag class */ + [ContentTypeWriter] + public class OdeTagWriter : ContentTypeWriter + { + + protected override void Write(ContentWriter output, OdeTag value) + { + float[] vertexData = value.getVertexData(); + int[] indexData = value.getIndexData(); + output.Write(vertexData.Length); + output.Write(indexData.Length); + for (int j = 0; j < vertexData.Length; j++) + { + output.Write(vertexData[j]); + } + for (int i = 0; i < indexData.Length; i++) + { + output.Write(indexData[i]); + } + } + + public override string GetRuntimeType(TargetPlatform targetPlatform) + { + return typeof(OdeTag).AssemblyQualifiedName; + } + + public override string GetRuntimeReader(TargetPlatform targetPlatform) + { + return "OdeModelProcessor.OdeTagReader, OdeModelProcessor, Version=1.0.0.0, Culture=neutral"; + } + + } + + /* Reader for the OdeTag class */ + public class OdeTagReader : ContentTypeReader + { + protected override OdeTag Read(ContentReader input, OdeTag existingInstance) + { + float[] vertexData = new float[input.ReadInt32()]; + int[] indexData = new int[input.ReadInt32()]; + for (int j = 0; j < vertexData.Length; j++) + { + vertexData[j] = input.ReadSingle(); + } + for (int i = 0; i < indexData.Length; i++) + { + indexData[i] = input.ReadInt32(); + } + + OdeTag tag = null; + if (existingInstance == null) + { + tag = new OdeTag(vertexData, indexData); + } + else + { + tag = existingInstance; + tag.setData(vertexData, indexData); + } + return tag; + } + } +} diff --git a/libraries/ode-0.9/contrib/OdeModelProcessor/OdeModelProcessor/OdeModelProcessor.csproj b/libraries/ode-0.9/contrib/OdeModelProcessor/OdeModelProcessor/OdeModelProcessor.csproj new file mode 100644 index 0000000000..3a36a1251c --- /dev/null +++ b/libraries/ode-0.9/contrib/OdeModelProcessor/OdeModelProcessor/OdeModelProcessor.csproj @@ -0,0 +1,69 @@ + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {246F3075-FEE3-45F9-8CB6-47DADBFFD1F2} + Library + Properties + OdeModelProcessor + OdeModelProcessor + + + true + full + false + bin\Debug\ + DEBUG + prompt + 4 + false + false + + + pdbonly + true + bin\Release\ + + + prompt + 4 + false + false + + + + + + False + ..\..\ODE\Ode.NET-0.8\bin\Release\Ode.NET.dll + + + + + + + + + + True + True + Settings.settings + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + \ No newline at end of file diff --git a/libraries/ode-0.9/contrib/OdeModelProcessor/OdeModelProcessor/Properties/AssemblyInfo.cs b/libraries/ode-0.9/contrib/OdeModelProcessor/OdeModelProcessor/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..1ecad3ecc2 --- /dev/null +++ b/libraries/ode-0.9/contrib/OdeModelProcessor/OdeModelProcessor/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OdeModelProcessor")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OdeModelProcessor")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("29c5609a-cd5f-480b-b4ef-5c11de022268")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/libraries/ode-0.9/contrib/OdeModelProcessor/OdeModelProcessor/Properties/Settings.Designer.cs b/libraries/ode-0.9/contrib/OdeModelProcessor/OdeModelProcessor/Properties/Settings.Designer.cs new file mode 100755 index 0000000000..6ab60a8ee4 --- /dev/null +++ b/libraries/ode-0.9/contrib/OdeModelProcessor/OdeModelProcessor/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.832 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace OdeModelProcessor.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/libraries/ode-0.9/contrib/OdeModelProcessor/OdeModelProcessor/Properties/Settings.settings b/libraries/ode-0.9/contrib/OdeModelProcessor/OdeModelProcessor/Properties/Settings.settings new file mode 100755 index 0000000000..15034e76c4 --- /dev/null +++ b/libraries/ode-0.9/contrib/OdeModelProcessor/OdeModelProcessor/Properties/Settings.settings @@ -0,0 +1,6 @@ + + + + + + diff --git a/libraries/ode-0.9/contrib/OdeModelProcessor/README.TXT b/libraries/ode-0.9/contrib/OdeModelProcessor/README.TXT new file mode 100644 index 0000000000..97683f95bb --- /dev/null +++ b/libraries/ode-0.9/contrib/OdeModelProcessor/README.TXT @@ -0,0 +1,78 @@ +The ODE Model Processor +----------------------- + +Copyright 2007, Department of Information Science, +University of Otago, Dunedin, New Zealand. + +Author: Richard Barrington + +This is a Content Processor and Tag library written for use with +Microsoft Visual C# 2005 Express Edition and Microsoft XNA Game +Studio Express 1.0. + +It can be used to read .x model vertex and index data before +insertion into the content pipeline. This is used to build ODE +Triangle Meshes which are then used for collision detection that +is more accurate than the default XNA bounding boxes or spheres. + +Usage is fairly simple: +Build the library and reference the DLL in your project. +Add the DLL to the Content Pipeline +Set the content processor for you .x models to OdeModelProcessor. + +Create triangle meshes as follows: +1) Create a space, but only one for all of models. +2) Create a triangle data. +3) Load the model. +4) Retreive the tag from the model. +6) Build the triangle mesh by calling d.GeomTriMeshDataBuildSimple. + +Eg: +IntPtr space = d.SimpleSpaceCreate(IntPtr.Zero); +IntPtr triangleData = d.GeomTriMeshDataCreate(); +Model obj = content.Load("Content\\mycube"); +OdeTag tag = (OdeTag)obj.Tag; +IntPtr vertexArray = tag.getVertices(); +IntPtr indexArray = tag.getIndices(); +d.GeomTriMeshDataBuildSimple +( + triangleData, + vertexArray, tag.getVertexStride(), tag.getVertexCount(), + indexArray, tag.getIndexCount(), tag.getIndexStride() +); +IntPtr triangleMesh = d.CreateTriMesh(space, triangleData, null, null, null); + +You can load multiple models and test for collisions with something +like this in the update method: + +d.GeomSetPosition(odeTri1, obj1Position.X, obj1Position.Y, obj1Position.Z); +d.GeomSetPosition(odeTri2, obj2Position.X, obj2Position.Y, obj2Position.Z); +int numberOfContacts = d.Collide(odeTri1, odeTri2, ODE_CONTACTS, + contactGeom, d.ContactGeom.SizeOf); + +Where odeTri1 and odeTri2 are triangle meshes you've created, obj1Position +and obj2Position are the positions of your rendered models in the scene, +ODE_CONTACTS is a constant defining the maximum number of contacts +to test for, contactGeom is a d.ContactGeom[] of length ODE_CONTACTS. + +If numberOfContacts is greater than 0, you have a collision. + +Other ODE functions such as d.SpaceCollide() also work; see ODE.NET BoxTest.cs. + +This library is free software; you can redistribute it and/or +modify it under the same terms as the ODE and ODE.Net libraries. +Specifically, the terms are one of EITHER: + + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file LICENSE.TXT. + + (2) The BSD-style license that is included with this library in + the file LICENSE-BSD.TXT. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files +LICENSE.TXT and LICENSE-BSD.TXT for more details. diff --git a/libraries/ode-0.9/contrib/README b/libraries/ode-0.9/contrib/README new file mode 100644 index 0000000000..dbfaf7f365 --- /dev/null +++ b/libraries/ode-0.9/contrib/README @@ -0,0 +1,19 @@ +This directory contains ODE-related things that have been generously +contributed by ODE's users. Why is this stuff here and not integrated +into the main ODE source tree? There may be several reasons: + + * The author(s) and ODE maintainers(s) may not have had time to do + the job. + + * It may not be finished. + + * It may contribute functionality that is useful but not considered + to be part of ODE's core. + +No guarantees are made about the code in this directory - it may not +be documented, it may not have been tested, and it may not even +compile for you. + +Each package has its own subdirectory, with a README file in that +directory explaining what the package is. + diff --git a/libraries/ode-0.9/contrib/TerrainAndCone/collision_std_internal.h b/libraries/ode-0.9/contrib/TerrainAndCone/collision_std_internal.h new file mode 100644 index 0000000000..b445353533 --- /dev/null +++ b/libraries/ode-0.9/contrib/TerrainAndCone/collision_std_internal.h @@ -0,0 +1,100 @@ +//Benoit CHAPEROT 2003-2004 www.jstarlab.com +#ifndef _ODE_COLLISION_STD_INTERNAL_H_ +#define _ODE_COLLISION_STD_INTERNAL_H_ + +#include +#include "collision_kernel.h" + +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 dxCCylinder : public dxGeom { + dReal radius,lz; // radius, length along z axis + dxCCylinder (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 dxCylinder : public dxGeom { + dReal radius,lz; // radius, length along z axis + dxCylinder (dSpaceID space, dReal _radius, dReal _length); + void computeAABB(); +}; + +struct dxCone : public dxGeom { + dReal radius,lz; + dxCone(dSpaceID space, dReal _radius,dReal _length); + ~dxCone(); + void computeAABB(); +}; + +struct dxRay : public dxGeom { + dReal length; + dxRay (dSpaceID space, dReal _length); + void computeAABB(); +}; + +struct dxTerrainY : public dxGeom { + dReal m_vLength; + dReal *m_pHeights; + dReal m_vMinHeight; + dReal m_vMaxHeight; + dReal m_vNodeLength; + int m_nNumNodesPerSide; + int m_nNumNodesPerSideShift; + int m_nNumNodesPerSideMask; + int m_bFinite; + dxTerrainY(dSpaceID space, dReal *pHeights,dReal vLength,int nNumNodesPerSide, int bFinite, int bPlaceable); + ~dxTerrainY(); + void computeAABB(); + dReal GetHeight(dReal x,dReal z); + dReal GetHeight(int x,int z); + int dCollideTerrainUnit(int x,int z,dxGeom *o2,int numMaxContacts,int flags,dContactGeom *contact, int skip); + bool IsOnTerrain(int nx,int nz,int w,dReal *pos); +}; + +struct dxTerrainZ : public dxGeom { + dReal m_vLength; + dReal *m_pHeights; + dReal m_vMinHeight; + dReal m_vMaxHeight; + dReal m_vNodeLength; + int m_nNumNodesPerSide; + int m_nNumNodesPerSideShift; + int m_nNumNodesPerSideMask; + int m_bFinite; + dxTerrainZ(dSpaceID space, dReal *pHeights,dReal vLength,int nNumNodesPerSide, int bFinite, int bPlaceable); + ~dxTerrainZ(); + void computeAABB(); + dReal GetHeight(dReal x,dReal y); + dReal GetHeight(int x,int y); + int dCollideTerrainUnit(int x,int y,dxGeom *o2,int numMaxContacts,int flags,dContactGeom *contact, int skip); + bool IsOnTerrain(int nx,int ny,int w,dReal *pos); +}; + +#ifndef MIN +#define MIN(a,b) ((ab)?a:b) +#endif + +#endif //_ODE_COLLISION_STD_INTERNAL_H_ \ No newline at end of file diff --git a/libraries/ode-0.9/contrib/TerrainAndCone/dCone.cpp b/libraries/ode-0.9/contrib/TerrainAndCone/dCone.cpp new file mode 100644 index 0000000000..8c5c3be99f --- /dev/null +++ b/libraries/ode-0.9/contrib/TerrainAndCone/dCone.cpp @@ -0,0 +1,504 @@ +//Benoit CHAPEROT 2003-2004 www.jstarlab.com +//some code inspired by Magic Software +#include +#include +#include +#include +#include +#include "collision_kernel.h" +#include "collision_std.h" +#include "collision_std_internal.h" +#include "collision_util.h" +#include +#include "windows.h" +#include "ode\ode.h" + +#define CONTACT(p,skip) ((dContactGeom*) (((char*)p) + (skip))) +const dReal fEPSILON = 1e-9f; + +dxCone::dxCone (dSpaceID space, dReal _radius,dReal _length) : +dxGeom (space,1) +{ + dAASSERT(_radius > 0.f); + dAASSERT(_length > 0.f); + type = dConeClass; + radius = _radius; + lz = _length; +} + +dxCone::~dxCone() +{ +} + +void dxCone::computeAABB() +{ + const dMatrix3& R = final_posr->R; + const dVector3& pos = final_posr->pos; + + dReal xrange = dFabs(R[2] * lz) + radius; + dReal yrange = dFabs(R[6] * lz) + radius; + dReal zrange = dFabs(R[10] * lz) + 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 dCreateCone(dSpaceID space, dReal _radius,dReal _length) +{ + return new dxCone(space,_radius,_length); +} + +void dGeomConeSetParams (dGeomID g, dReal _radius, dReal _length) +{ + dUASSERT (g && g->type == dConeClass,"argument not a cone"); + dAASSERT (_radius > 0.f); + dAASSERT (_length > 0.f); + g->recomputePosr(); + dxCone *c = (dxCone*) g; + c->radius = _radius; + c->lz = _length; + dGeomMoved (g); +} + + +void dGeomConeGetParams (dGeomID g, dReal *_radius, dReal *_length) +{ + dUASSERT (g && g->type == dConeClass,"argument not a cone"); + g->recomputePosr(); + dxCone *c = (dxCone*) g; + *_radius = c->radius; + *_length = c->lz; +} + +//positive inside +dReal dGeomConePointDepth(dGeomID g, dReal x, dReal y, dReal z) +{ + dUASSERT (g && g->type == dConeClass,"argument not a cone"); + + g->recomputePosr(); + dxCone *cone = (dxCone*) g; + + dVector3 tmp,q; + tmp[0] = x - cone->final_posr->pos[0]; + tmp[1] = y - cone->final_posr->pos[1]; + tmp[2] = z - cone->final_posr->pos[2]; + dMULTIPLY1_331 (q,cone->final_posr->R,tmp); + + dReal r = cone->radius; + dReal h = cone->lz; + + dReal d0 = (r - r*q[2]/h) - dSqrt(q[0]*q[0]+q[1]*q[1]); + dReal d1 = q[2]; + dReal d2 = h-q[2]; + + if (d0 < d1) { + if (d0 < d2) return d0; else return d2; + } + else { + if (d1 < d2) return d1; else return d2; + } +} + +//plane plane +bool FindIntersectionPlanePlane(const dReal Plane0[4], const dReal Plane1[4], + dVector3 LinePos,dVector3 LineDir) +{ + // If Cross(N0,N1) is zero, then either planes are parallel and separated + // or the same plane. In both cases, 'false' is returned. Otherwise, + // the intersection line is + // + // L(t) = t*Cross(N0,N1) + c0*N0 + c1*N1 + // + // for some coefficients c0 and c1 and for t any real number (the line + // parameter). Taking dot products with the normals, + // + // d0 = Dot(N0,L) = c0*Dot(N0,N0) + c1*Dot(N0,N1) + // d1 = Dot(N1,L) = c0*Dot(N0,N1) + c1*Dot(N1,N1) + // + // which are two equations in two unknowns. The solution is + // + // c0 = (Dot(N1,N1)*d0 - Dot(N0,N1)*d1)/det + // c1 = (Dot(N0,N0)*d1 - Dot(N0,N1)*d0)/det + // + // where det = Dot(N0,N0)*Dot(N1,N1)-Dot(N0,N1)^2. +/* + Real fN00 = rkPlane0.Normal().SquaredLength(); + Real fN01 = rkPlane0.Normal().Dot(rkPlane1.Normal()); + Real fN11 = rkPlane1.Normal().SquaredLength(); + Real fDet = fN00*fN11 - fN01*fN01; + + if ( Math::FAbs(fDet) < gs_fEpsilon ) + return false; + + Real fInvDet = 1.0f/fDet; + Real fC0 = (fN11*rkPlane0.Constant() - fN01*rkPlane1.Constant())*fInvDet; + Real fC1 = (fN00*rkPlane1.Constant() - fN01*rkPlane0.Constant())*fInvDet; + + rkLine.Direction() = rkPlane0.Normal().Cross(rkPlane1.Normal()); + rkLine.Origin() = fC0*rkPlane0.Normal() + fC1*rkPlane1.Normal(); + return true; +*/ + dReal fN00 = dLENGTHSQUARED(Plane0); + dReal fN01 = dDOT(Plane0,Plane1); + dReal fN11 = dLENGTHSQUARED(Plane1); + dReal fDet = fN00*fN11 - fN01*fN01; + + if ( fabs(fDet) < fEPSILON) + return false; + + dReal fInvDet = 1.0f/fDet; + dReal fC0 = (fN11*Plane0[3] - fN01*Plane1[3])*fInvDet; + dReal fC1 = (fN00*Plane1[3] - fN01*Plane0[3])*fInvDet; + + dCROSS(LineDir,=,Plane0,Plane1); + dNormalize3(LineDir); + + dVector3 Temp0,Temp1; + dOPC(Temp0,*,Plane0,fC0); + dOPC(Temp1,*,Plane1,fC1); + dOP(LinePos,+,Temp0,Temp1); + + return true; +} + +//plane ray +bool FindIntersectionPlaneRay(const dReal Plane[4], + const dVector3 &LinePos,const dVector3 &LineDir, + dReal &u,dVector3 &Pos) +{ +/* + u = (A*X1 + B*Y1 + C*Z1 + D) / (A*(X1-X2) + B*(Y1-Y2)+C*(Z1-Z2)) +*/ + dReal fDet = -dDot(Plane,LineDir,3); + + if ( fabs(fDet) < fEPSILON) + return false; + + u = (dDot(Plane,LinePos,3) - Plane[3]) / fDet; + dOPC(Pos,*,LineDir,u); + dOPE(Pos,+=,LinePos); + + return true; +} + +int SolveQuadraticPolynomial(dReal a,dReal b,dReal c,dReal &x0,dReal &x1) +{ + dReal d = b*b - 4*a*c; + int NumRoots = 0; + dReal dr; + + if (d < 0.f) + return NumRoots; + + if (d == 0.f) + { + NumRoots = 1; + dr = 0.f; + } + else + { + NumRoots = 2; + dr = sqrtf(d); + } + + x0 = (-b -dr) / (2.f * a); + x1 = (-b +dr) / (2.f * a); + + return NumRoots; +} +/* +const int VALID_INTERSECTION = 1<<0; +const int POS_TEST_FAILEDT0 = 1<<0; +const int POS_TEST_FAILEDT1 = 1<<1; +*/ +int ProcessConeRayIntersectionPoint( dReal r,dReal h, + const dVector3 &q,const dVector3 &v,dReal t, + dVector3 &p, + dVector3 &n, + int &f) +{ + dOPC(p,*,v,t); + dOPE(p,+=,q); + n[0] = 2*p[0]; + n[1] = 2*p[1]; + n[2] = -2*p[2]*r*r/(h*h); + + f = 0; + if (p[2] > h) return 0; + if (p[2] < 0) return 0; + if (t > 1) return 0; + if (t < 0) return 0; + + return 1; +} + +//cone ray +//line in cone space (position,direction) +//distance from line position (direction normalized)(if any) +//return the number of intersection +int FindIntersectionConeRay(dReal r,dReal h, + const dVector3 &q,const dVector3 &v,dContactGeom *pContact) +{ + dVector3 qp,vp; + dOPE(qp,=,q); + dOPE(vp,=,v); + qp[2] = h-q[2]; + vp[2] = -v[2]; + dReal ts = (r/h); + ts *= ts; + dReal a = vp[0]*vp[0] + vp[1]*vp[1] - ts*vp[2]*vp[2]; + dReal b = 2.f*qp[0]*vp[0] + 2.f*qp[1]*vp[1] - 2.f*ts*qp[2]*vp[2]; + dReal c = qp[0]*qp[0] + qp[1]*qp[1] - ts*qp[2]*qp[2]; + +/* + dReal a = v[0]*v[0] + v[1]*v[1] - (v[2]*v[2]*r*r) / (h*h); + dReal b = 2.f*q[0]*v[0] + 2.f*q[1]*v[1] + 2.f*r*r*v[2]/h - 2*r*r*q[0]*v[0]/(h*h); + dReal c = q[0]*q[0] + q[1]*q[1] + 2*r*r*q[2]/h - r*r*q[2]/(h*h) - r*r; +*/ + int nNumRoots=SolveQuadraticPolynomial(a,b,c,pContact[0].depth,pContact[1].depth); + int flag = 0; + + dContactGeom ValidContact[2]; + + int nNumValidContacts = 0; + for (int i=0;i=0) && (d<=1)) + { + dOPC(vp,*,v,d); + dOP(qp,+,q,vp); + + if (qp[0]*qp[0]+qp[1]*qp[1] < r*r) + { + dOPE(ValidContact[nNumValidContacts].pos,=,qp); + ValidContact[nNumValidContacts].normal[0] = 0.f; + ValidContact[nNumValidContacts].normal[1] = 0.f; + ValidContact[nNumValidContacts].normal[2] = -1.f; + ValidContact[nNumValidContacts].depth = d; + nNumValidContacts++; + } + } + } + + if (nNumValidContacts == 2) + { + if (ValidContact[0].depth > ValidContact[1].depth) + { + pContact[0] = ValidContact[1]; + pContact[1] = ValidContact[0]; + } + else + { + pContact[0] = ValidContact[0]; + pContact[1] = ValidContact[1]; + } + } + else if (nNumValidContacts == 1) + { + pContact[0] = ValidContact[0]; + } + + return nNumValidContacts; +} + +int dCollideConePlane (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dConeClass); + dIASSERT (o2->type == dPlaneClass); + dxCone *cone = (dxCone*) o1; + dxPlane *plane = (dxPlane*) o2; + + contact->g1 = o1; + contact->g2 = o2; + + dVector3 p0,p1,pp0,pp1; + dOPE(p0,=,cone->final_posr->pos); + p1[0] = cone->final_posr->R[0*4+2] * cone->lz + p0[0]; + p1[1] = cone->final_posr->R[1*4+2] * cone->lz + p0[1]; + p1[2] = cone->final_posr->R[2*4+2] * cone->lz + p0[2]; + + dReal u; + FindIntersectionPlaneRay(plane->p,p0,plane->p,u,pp0); + FindIntersectionPlaneRay(plane->p,p1,plane->p,u,pp1); + + if (dDISTANCE(pp0,pp1) < fEPSILON) + { + p1[0] = cone->final_posr->R[0*4+0] * cone->lz + p0[0]; + p1[1] = cone->final_posr->R[1*4+0] * cone->lz + p0[1]; + p1[2] = cone->final_posr->R[2*4+0] * cone->lz + p0[2]; + FindIntersectionPlaneRay(plane->p,p1,plane->p,u,pp1); + dIASSERT(dDISTANCE(pp0,pp1) >= fEPSILON); + } + dVector3 h,r0,r1; + h[0] = cone->final_posr->R[0*4+2]; + h[1] = cone->final_posr->R[1*4+2]; + h[2] = cone->final_posr->R[2*4+2]; + + dOP(r0,-,pp0,pp1); + dCROSS(r1,=,h,r0); + dCROSS(r0,=,r1,h); + dNormalize3(r0); + dOPEC(h,*=,cone->lz); + dOPEC(r0,*=,cone->radius); + + dVector3 p[3]; + dOP(p[0],+,cone->final_posr->pos,h); + dOP(p[1],+,cone->final_posr->pos,r0); + dOP(p[2],-,cone->final_posr->pos,r0); + + int numMaxContacts = flags & 0xffff; + if (numMaxContacts == 0) + numMaxContacts = 1; + + int n=0; + for (int i=0;i<3;i++) + { + dReal d = dGeomPlanePointDepth(o2, p[i][0], p[i][1], p[i][2]); + + if (d>0.f) + { + CONTACT(contact,n*skip)->g1 = o1; + CONTACT(contact,n*skip)->g2 = o2; + dOPE(CONTACT(contact,n*skip)->normal,=,plane->p); + dOPE(CONTACT(contact,n*skip)->pos,=,p[i]); + CONTACT(contact,n*skip)->depth = d; + n++; + + if (n == numMaxContacts) + return n; + } + } + + return n; +} + +int dCollideRayCone (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dRayClass); + dIASSERT (o2->type == dConeClass); + dxRay *ray = (dxRay*) o1; + dxCone *cone = (dxCone*) o2; + + contact->g1 = o1; + contact->g2 = o2; + + dVector3 tmp,q,v; + tmp[0] = ray->final_posr->pos[0] - cone->final_posr->pos[0]; + tmp[1] = ray->final_posr->pos[1] - cone->final_posr->pos[1]; + tmp[2] = ray->final_posr->pos[2] - cone->final_posr->pos[2]; + dMULTIPLY1_331 (q,cone->final_posr->R,tmp); + tmp[0] = ray->final_posr->R[0*4+2] * ray->length; + tmp[1] = ray->final_posr->R[1*4+2] * ray->length; + tmp[2] = ray->final_posr->R[2*4+2] * ray->length; + dMULTIPLY1_331 (v,cone->final_posr->R,tmp); + + dReal r = cone->radius; + dReal h = cone->lz; + + dContactGeom Contact[2]; + + if (FindIntersectionConeRay(r,h,q,v,Contact)) + { + dMULTIPLY0_331(contact->normal,cone->final_posr->R,Contact[0].normal); + dMULTIPLY0_331(contact->pos,cone->final_posr->R,Contact[0].pos); + dOPE(contact->pos,+=,cone->final_posr->pos); + contact->depth = Contact[0].depth * dLENGTH(v); +/* + dMatrix3 RI; + dRSetIdentity (RI); + dVector3 ss; + ss[0] = 0.01f; + ss[1] = 0.01f; + ss[2] = 0.01f; + + dsSetColorAlpha (1,0,0,0.8f); + dsDrawBox(contact->pos,RI,ss); +*/ + return 1; + } + + return 0; +} + +int dCollideConeSphere(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dConeClass); + dIASSERT (o2->type == dSphereClass); + dxCone *cone = (dxCone*) o1; + + dxSphere ASphere(0,cone->radius); + dGeomSetRotation(&ASphere,cone->final_posr->R); + dGeomSetPosition(&ASphere,cone->final_posr->pos[0],cone->final_posr->pos[1],cone->final_posr->pos[2]); + + return dCollideSphereSphere(&ASphere, o2, flags, contact, skip); +} + +int dCollideConeBox(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dConeClass); + dIASSERT (o2->type == dBoxClass); + dxCone *cone = (dxCone*) o1; + + dxSphere ASphere(0,cone->radius); + dGeomSetRotation(&ASphere,cone->final_posr->R); + dGeomSetPosition(&ASphere,cone->final_posr->pos[0],cone->final_posr->pos[1],cone->final_posr->pos[2]); + + return dCollideSphereBox(&ASphere, o2, flags, contact, skip); +} + +int dCollideCCylinderCone(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dCCylinderClass); + dIASSERT (o2->type == dConeClass); + dxCone *cone = (dxCone*) o2; + + dxSphere ASphere(0,cone->radius); + dGeomSetRotation(&ASphere,cone->final_posr->R); + dGeomSetPosition(&ASphere,cone->final_posr->pos[0],cone->final_posr->pos[1],cone->final_posr->pos[2]); + + return dCollideCCylinderSphere(o1, &ASphere, flags, contact, skip); +} + +extern int dCollideSTL(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip); + +int dCollideTriMeshCone(dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dTriMeshClass); + dIASSERT (o2->type == dConeClass); + dxCone *cone = (dxCone*) o2; + + dxSphere ASphere(0,cone->radius); + dGeomSetRotation(&ASphere,cone->final_posr->R); + dGeomSetPosition(&ASphere,cone->final_posr->pos[0],cone->final_posr->pos[1],cone->final_posr->pos[2]); + + return dCollideSTL(o1, &ASphere, flags, contact, skip); +} + + + + + diff --git a/libraries/ode-0.9/contrib/TerrainAndCone/dTerrainY.cpp b/libraries/ode-0.9/contrib/TerrainAndCone/dTerrainY.cpp new file mode 100644 index 0000000000..ff779ace4e --- /dev/null +++ b/libraries/ode-0.9/contrib/TerrainAndCone/dTerrainY.cpp @@ -0,0 +1,662 @@ +//Benoit CHAPEROT 2003-2004 www.jstarlab.com +//some code inspired by Magic Software +#include +#include +#include +#include +#include +#include "collision_kernel.h" +#include "collision_std.h" +#include "collision_std_internal.h" +#include "collision_util.h" +//#include +#include "windows.h" +#include "ode\ode.h" + +#define CONTACT(p,skip) ((dContactGeom*) (((char*)p) + (skip))) +#define MAXCONTACT 10 +#define TERRAINTOL 0.0f + +static bool IsAPowerOfTwo(int f) +{ + dAASSERT(f!=0); + while ((f&1) != 1) + f >>= 1; + + return (f == 1); +} + +static int GetPowerOfTwo(int f) +{ + dAASSERT(f!=0); + int n = 0; + while ((f&1) != 1) + { + n++; + f >>= 1; + } + + return n; +} + +dxTerrainY::dxTerrainY (dSpaceID space, dReal *pHeights,dReal vLength,int nNumNodesPerSide, int bFinite, int bPlaceable) : +dxGeom (space,bPlaceable) +{ + dIASSERT(IsAPowerOfTwo(nNumNodesPerSide)); + dIASSERT(pHeights); + dIASSERT(vLength > 0.f); + dIASSERT(nNumNodesPerSide > 0); + type = dTerrainYClass; + m_vLength = vLength; + m_pHeights = new dReal[nNumNodesPerSide * nNumNodesPerSide]; + dIASSERT(m_pHeights); + m_nNumNodesPerSide = nNumNodesPerSide; + m_vNodeLength = m_vLength / m_nNumNodesPerSide; + m_nNumNodesPerSideShift = GetPowerOfTwo(m_nNumNodesPerSide); + m_nNumNodesPerSideMask = m_nNumNodesPerSide - 1; + m_vMinHeight = dInfinity; + m_vMaxHeight = -dInfinity; + m_bFinite = bFinite; + + for (int i=0;i m_vMaxHeight) m_vMaxHeight = m_pHeights[i]; + } +} + +dxTerrainY::~dxTerrainY() +{ + dIASSERT(m_pHeights); + delete [] m_pHeights; +} + +void dxTerrainY::computeAABB() +{ + if (m_bFinite) + { + if (gflags & GEOM_PLACEABLE) + { + dReal dx[6],dy[6],dz[6]; + dx[0] = 0; + dx[1] = final_posr->R[0] * m_vLength; + dx[2] = final_posr->R[1] * m_vMinHeight; + dx[3] = final_posr->R[1] * m_vMaxHeight; + dx[4] = 0; + dx[5] = final_posr->R[2] * m_vLength; + + dy[0] = 0; + dy[1] = final_posr->R[4] * m_vLength; + dy[2] = final_posr->R[5] * m_vMinHeight; + dy[3] = final_posr->R[5] * m_vMaxHeight; + dy[4] = 0; + dy[5] = final_posr->R[6] * m_vLength; + + dz[0] = 0; + dz[1] = final_posr->R[8] * m_vLength; + dz[2] = final_posr->R[9] * m_vMinHeight; + dz[3] = final_posr->R[9] * m_vMaxHeight; + dz[4] = 0; + dz[5] = final_posr->R[10] * m_vLength; + + aabb[0] = final_posr->pos[0] + MIN(dx[0],dx[1]) + MIN(dx[2],dx[3]) + MIN(dx[4],dx[5]); + aabb[1] = final_posr->pos[0] + MAX(dx[0],dx[1]) + MAX(dx[2],dx[3]) + MAX(dx[4],dx[5]); + aabb[2] = final_posr->pos[1] + MIN(dy[0],dy[1]) + MIN(dy[2],dy[3]) + MIN(dy[4],dy[5]); + aabb[3] = final_posr->pos[1] + MAX(dy[0],dy[1]) + MAX(dy[2],dy[3]) + MAX(dy[4],dy[5]); + aabb[4] = final_posr->pos[2] + MIN(dz[0],dz[1]) + MIN(dz[2],dz[3]) + MIN(dz[4],dz[5]); + aabb[5] = final_posr->pos[2] + MAX(dz[0],dz[1]) + MAX(dz[2],dz[3]) + MAX(dz[4],dz[5]); + } + else + { + aabb[0] = 0; + aabb[1] = m_vLength; + aabb[2] = m_vMinHeight; + aabb[3] = m_vMaxHeight; + aabb[4] = 0; + aabb[5] = m_vLength; + } + } + else + { + 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] = m_vMinHeight; + aabb[3] = m_vMaxHeight; + aabb[4] = -dInfinity; + aabb[5] = dInfinity; + } + } +} + +dReal dxTerrainY::GetHeight(int x,int z) +{ + return m_pHeights[ (((unsigned int)(z) & m_nNumNodesPerSideMask) << m_nNumNodesPerSideShift) + + ((unsigned int)(x) & m_nNumNodesPerSideMask)]; +} + +dReal dxTerrainY::GetHeight(dReal x,dReal z) +{ + int nX = int(floor(x / m_vNodeLength)); + int nZ = int(floor(z / m_vNodeLength)); + dReal dx = (x - (dReal(nX) * m_vNodeLength)) / m_vNodeLength; + dReal dz = (z - (dReal(nZ) * m_vNodeLength)) / m_vNodeLength; + dIASSERT((dx >= 0.f) && (dx <= 1.f)); + dIASSERT((dz >= 0.f) && (dz <= 1.f)); + + dReal y,y0; + + if (dx + dz < 1.f) + { + 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) * (1.f - dz) + + (GetHeight(nX,nZ+1) - y0) * (1.f - dx); + } + + return y; +} + +bool dxTerrainY::IsOnTerrain(int nx,int nz,int w,dReal *pos) +{ + dVector3 Min,Max; + Min[0] = nx * m_vNodeLength; + Min[2] = nz * m_vNodeLength; + Max[0] = (nx+1) * m_vNodeLength; + Max[2] = (nz+1) * m_vNodeLength; + dReal Tol = m_vNodeLength * TERRAINTOL; + + if ((pos[0]Max[0]+Tol)) + return false; + + if ((pos[2]Max[2]+Tol)) + return false; + + dReal dx = (pos[0] - (dReal(nx) * m_vNodeLength)) / m_vNodeLength; + dReal dz = (pos[2] - (dReal(nz) * m_vNodeLength)) / m_vNodeLength; + + if ((w == 0) && (dx + dz > 1.f+TERRAINTOL)) + return false; + + if ((w == 1) && (dx + dz < 1.f-TERRAINTOL)) + return false; + + return true; +} + +dGeomID dCreateTerrainY(dSpaceID space, dReal *pHeights,dReal vLength,int nNumNodesPerSide, int bFinite, int bPlaceable) +{ + return new dxTerrainY(space, pHeights,vLength,nNumNodesPerSide,bFinite,bPlaceable); +} + +dReal dGeomTerrainYPointDepth (dGeomID g, dReal x, dReal y, dReal z) +{ + dUASSERT (g && g->type == dTerrainYClass,"argument not a terrain"); + g->recomputePosr(); + dxTerrainY *t = (dxTerrainY*) g; + return t->GetHeight(x,z) - y; +} + +typedef dReal dGetDepthFn(dGeomID g, dReal x, dReal y, dReal z); +#define RECOMPUTE_RAYNORMAL +//#define DO_RAYDEPTH + +#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]); +/* +(y is up) + +A-B-E.x +|/| +C-D +| +F +. +z +*/ +int dxTerrainY::dCollideTerrainUnit( + int x,int z,dxGeom *o2,int numMaxContacts, + int flags,dContactGeom *contact, int skip) +{ + dColliderFn *CollideRayN; + dColliderFn *CollideNPlane; + dGetDepthFn *GetDepth; + int numContacts = 0; + int numPlaneContacts = 0; + int i; + + if (numContacts == numMaxContacts) + return numContacts; + + dContactGeom PlaneContact[MAXCONTACT]; + flags = (flags & 0xffff0000) | MAXCONTACT; + + switch (o2->type) + { + case dSphereClass: + CollideRayN = dCollideRaySphere; + CollideNPlane = dCollideSpherePlane; + GetDepth = dGeomSpherePointDepth; + break; + case dBoxClass: + CollideRayN = dCollideRayBox; + CollideNPlane = dCollideBoxPlane; + GetDepth = dGeomBoxPointDepth; + break; + case dCCylinderClass: + CollideRayN = dCollideRayCCylinder; + CollideNPlane = dCollideCCylinderPlane; + GetDepth = dGeomCCylinderPointDepth; + break; + case dRayClass: + CollideRayN = NULL; + CollideNPlane = dCollideRayPlane; + GetDepth = NULL; + break; + case dConeClass: + CollideRayN = dCollideRayCone; + CollideNPlane = dCollideConePlane; + GetDepth = dGeomConePointDepth; + break; + default: + dIASSERT(0); + } + + dReal Plane[4],lBD,lCD,lBC; + dVector3 A,B,C,D,BD,CD,BC,AB,AC; + A[0] = x * m_vNodeLength; + A[2] = z* m_vNodeLength; + A[1] = GetHeight(x,z); + B[0] = (x+1) * m_vNodeLength; + B[2] = z * m_vNodeLength; + B[1] = GetHeight(x+1,z); + C[0] = x * m_vNodeLength; + C[2] = (z+1) * m_vNodeLength; + C[1] = GetHeight(x,z+1); + D[0] = (x+1) * m_vNodeLength; + D[2] = (z+1) * m_vNodeLength; + D[1] = GetHeight(x+1,z+1); + + dOP(BC,-,C,B); + lBC = dLENGTH(BC); + dOPEC(BC,/=,lBC); + + dOP(BD,-,D,B); + lBD = dLENGTH(BD); + dOPEC(BD,/=,lBD); + + dOP(CD,-,D,C); + lCD = dLENGTH(CD); + dOPEC(CD,/=,lCD); + + dOP(AB,-,B,A); + dNormalize3(AB); + + dOP(AC,-,C,A); + dNormalize3(AC); + + if (CollideRayN) + { +#ifdef RECOMPUTE_RAYNORMAL + dVector3 E,F; + dVector3 CE,FB,AD; + dVector3 Normal[3]; + E[0] = (x+2) * m_vNodeLength; + E[2] = z * m_vNodeLength; + E[1] = GetHeight(x+2,z); + F[0] = x * m_vNodeLength; + F[2] = (z+2) * m_vNodeLength; + F[1] = GetHeight(x,z+2); + dOP(AD,-,D,A); + dNormalize3(AD); + dOP(CE,-,E,C); + dNormalize3(CE); + dOP(FB,-,B,F); + dNormalize3(FB); + + //BC + dCROSS(Normal[0],=,BC,AD); + dNormalize3(Normal[0]); + + //BD + dCROSS(Normal[1],=,BD,CE); + dNormalize3(Normal[1]); + + //CD + dCROSS(Normal[2],=,CD,FB); + dNormalize3(Normal[2]); +#endif + int nA[3],nB[3]; + dContactGeom ContactA[3],ContactB[3]; + dxRay rayBC(0,lBC); + dGeomRaySet(&rayBC, B[0], B[1], B[2], BC[0], BC[1], BC[2]); + nA[0] = CollideRayN(&rayBC,o2,flags,&ContactA[0],sizeof(dContactGeom)); + dGeomRaySet(&rayBC, C[0], C[1], C[2], -BC[0], -BC[1], -BC[2]); + nB[0] = CollideRayN(&rayBC,o2,flags,&ContactB[0],sizeof(dContactGeom)); + + dxRay rayBD(0,lBD); + dGeomRaySet(&rayBD, B[0], B[1], B[2], BD[0], BD[1], BD[2]); + nA[1] = CollideRayN(&rayBD,o2,flags,&ContactA[1],sizeof(dContactGeom)); + dGeomRaySet(&rayBD, D[0], D[1], D[2], -BD[0], -BD[1], -BD[2]); + nB[1] = CollideRayN(&rayBD,o2,flags,&ContactB[1],sizeof(dContactGeom)); + + dxRay rayCD(0,lCD); + dGeomRaySet(&rayCD, C[0], C[1], C[2], CD[0], CD[1], CD[2]); + nA[2] = CollideRayN(&rayCD,o2,flags,&ContactA[2],sizeof(dContactGeom)); + dGeomRaySet(&rayCD, D[0], D[1], D[2], -CD[0], -CD[1], -CD[2]); + nB[2] = CollideRayN(&rayCD,o2,flags,&ContactB[2],sizeof(dContactGeom)); + + for (i=0;i<3;i++) + { + if (nA[i] & nB[i]) + { + dContactGeom *pContact = CONTACT(contact,numContacts*skip); + pContact->pos[0] = (ContactA[i].pos[0] + ContactB[i].pos[0])/2; + pContact->pos[1] = (ContactA[i].pos[1] + ContactB[i].pos[1])/2; + pContact->pos[2] = (ContactA[i].pos[2] + ContactB[i].pos[2])/2; +#ifdef RECOMPUTE_RAYNORMAL + pContact->normal[0] = -Normal[i][0]; + pContact->normal[1] = -Normal[i][1]; + pContact->normal[2] = -Normal[i][2]; +#else + pContact->normal[0] = (ContactA[i].normal[0] + ContactB[i].normal[0])/2; //0.f; + pContact->normal[1] = (ContactA[i].normal[1] + ContactB[i].normal[1])/2; //0.f; + pContact->normal[2] = (ContactA[i].normal[2] + ContactB[i].normal[2])/2; //-1.f; + dNormalize3(pContact->normal); +#endif +#ifdef DO_RAYDEPTH + dxRay rayV(0,1000.f); + dGeomRaySet(&rayV, pContact->pos[0], + pContact->pos[1], + pContact->pos[2], + -pContact->normal[0], + -pContact->normal[1], + -pContact->normal[2]); + + dContactGeom ContactV; + if (CollideRayN(&rayV,o2,flags,&ContactV,sizeof(dContactGeom))) + { + pContact->depth = ContactV.depth; + numContacts++; + } +#else + + if (GetDepth == NULL) + { + dxRay rayV(0,1000.f); + dGeomRaySet(&rayV, pContact->pos[0], + pContact->pos[1], + pContact->pos[2], + -pContact->normal[0], + -pContact->normal[1], + -pContact->normal[2]); + + dContactGeom ContactV; + + if (CollideRayN(&rayV,o2,flags,&ContactV,sizeof(dContactGeom))) + { + pContact->depth = ContactV.depth; + numContacts++; + } + } + else + { + pContact->depth = GetDepth(o2, + pContact->pos[0], + pContact->pos[1], + pContact->pos[2]); + numContacts++; + } + +#endif + if (numContacts == numMaxContacts) + return numContacts; + + } + } + } + + dCROSS(Plane,=,AC,AB); + dNormalize3(Plane); + Plane[3] = Plane[0] * A[0] + Plane[1] * A[1] + Plane[2] * A[2]; + dxPlane planeABC(0,Plane[0],Plane[1],Plane[2],Plane[3]); + numPlaneContacts = CollideNPlane(o2,&planeABC,flags,PlaneContact,sizeof(dContactGeom)); + + for (i=0;ipos[0] = PlaneContact[i].pos[0]; + pContact->pos[1] = PlaneContact[i].pos[1]; + pContact->pos[2] = PlaneContact[i].pos[2]; + pContact->normal[0] = -PlaneContact[i].normal[0]; + pContact->normal[1] = -PlaneContact[i].normal[1]; + pContact->normal[2] = -PlaneContact[i].normal[2]; + pContact->depth = PlaneContact[i].depth; + + //DMESS(0); + numContacts++; + + if (numContacts == numMaxContacts) + return numContacts; + } + } + + dCROSS(Plane,=,BD,CD); + dNormalize3(Plane); + Plane[3] = Plane[0] * D[0] + Plane[1] * D[1] + Plane[2] * D[2]; + dxPlane planeDCB(0,Plane[0],Plane[1],Plane[2],Plane[3]); + numPlaneContacts = CollideNPlane(o2,&planeDCB,flags,PlaneContact,sizeof(dContactGeom)); + + for (i=0;ipos[0] = PlaneContact[i].pos[0]; + pContact->pos[1] = PlaneContact[i].pos[1]; + pContact->pos[2] = PlaneContact[i].pos[2]; + pContact->normal[0] = -PlaneContact[i].normal[0]; + pContact->normal[1] = -PlaneContact[i].normal[1]; + pContact->normal[2] = -PlaneContact[i].normal[2]; + pContact->depth = PlaneContact[i].depth; + //DMESS(1); + numContacts++; + + if (numContacts == numMaxContacts) + return numContacts; + } + } + + return numContacts; +} + +int dCollideTerrainY(dxGeom *o1, dxGeom *o2, int flags,dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dTerrainYClass); + int i,j; + + if ((flags & 0xffff) == 0) + flags = (flags & 0xffff0000) | 1; + + int numMaxTerrainContacts = (flags & 0xffff); + dxTerrainY *terrain = (dxTerrainY*) o1; + + dReal aabbbak[6]; + int gflagsbak; + + dVector3 pos0; + int numTerrainContacts = 0; + + dxPosR *bak; + dxPosR X1; + + if (terrain->gflags & GEOM_PLACEABLE) + { + dOP(pos0,-,o2->final_posr->pos,terrain->final_posr->pos); + dMULTIPLY1_331(X1.pos,terrain->final_posr->R,pos0); + dMULTIPLY1_333(X1.R,terrain->final_posr->R,o2->final_posr->R); + bak = o2->final_posr; + o2->final_posr = &X1; + memcpy(aabbbak,o2->aabb,sizeof(dReal)*6); + gflagsbak = o2->gflags; + o2->computeAABB(); + } + + int nMinX = int(floor(o2->aabb[0] / terrain->m_vNodeLength)); + int nMaxX = int(floor(o2->aabb[1] / terrain->m_vNodeLength)) + 1; + int nMinZ = int(floor(o2->aabb[4] / terrain->m_vNodeLength)); + int nMaxZ = int(floor(o2->aabb[5] / terrain->m_vNodeLength)) + 1; + + if (terrain->m_bFinite) + { + nMinX = MAX(nMinX,0); + nMaxX = MIN(nMaxX,terrain->m_nNumNodesPerSide); + nMinZ = MAX(nMinZ,0); + nMaxZ = MIN(nMaxZ,terrain->m_nNumNodesPerSide); + + if ((nMinX >= nMaxX) || (nMinZ >= nMaxZ)) + goto dCollideTerrainYExit; + } + + dVector3 AabbTop; + AabbTop[0] = (o2->aabb[0]+o2->aabb[1]) / 2; + AabbTop[2] = (o2->aabb[4]+o2->aabb[5]) / 2; + AabbTop[1] = o2->aabb[3]; + if (o2->type != dRayClass) + { + dReal AabbTopDepth = terrain->GetHeight(AabbTop[0],AabbTop[2]) - AabbTop[1]; + if (AabbTopDepth > 0.f) + { + contact->depth = AabbTopDepth; + dReal MaxDepth = (o2->aabb[3]-o2->aabb[2]) / 2; + if (contact->depth > MaxDepth) + contact->depth = MaxDepth; + contact->g1 = o1; + contact->g2 = o2; + dOPE(contact->pos,=,AabbTop); + contact->normal[0] = 0.f; + contact->normal[1] = -1.f; + contact->normal[2] = 0.f; + + numTerrainContacts = 1; + goto dCollideTerrainYExit; + } + } + + for (i=nMinX;idCollideTerrainUnit( + i,j,o2,numMaxTerrainContacts - numTerrainContacts, + flags,CONTACT(contact,numTerrainContacts*skip),skip ); + } + } + + dIASSERT(numTerrainContacts <= numMaxTerrainContacts); + + for (i=0; ig1 = o1; + CONTACT(contact,i*skip)->g2 = o2; + } + +dCollideTerrainYExit: + + if (terrain->gflags & GEOM_PLACEABLE) + { + o2->final_posr = bak; + memcpy(o2->aabb,aabbbak,sizeof(dReal)*6); + o2->gflags = gflagsbak; + + for (i=0; ipos); + dMULTIPLY0_331(CONTACT(contact,i*skip)->pos,terrain->final_posr->R,pos0); + dOP(CONTACT(contact,i*skip)->pos,+,CONTACT(contact,i*skip)->pos,terrain->final_posr->pos); + + dOPE(pos0,=,CONTACT(contact,i*skip)->normal); + dMULTIPLY0_331(CONTACT(contact,i*skip)->normal,terrain->final_posr->R,pos0); + } + } + + return numTerrainContacts; +} +/* +void dsDrawTerrainY(int x,int z,float vLength,float vNodeLength,int nNumNodesPerSide,float *pHeights,const float *pR,const float *ppos) +{ + float A[3],B[3],C[3],D[3]; + float R[12]; + float pos[3]; + if (pR) + memcpy(R,pR,sizeof(R)); + else + { + memset(R,0,sizeof(R)); + R[0] = 1.f; + R[5] = 1.f; + R[10] = 1.f; + } + + if (ppos) + memcpy(pos,ppos,sizeof(pos)); + else + memset(pos,0,sizeof(pos)); + + float vx,vz; + vx = vLength * x; + vz = vLength * z; + + int i; + for (i=0;i +#include +#include +#include +#include +#include "collision_kernel.h" +#include "collision_std.h" +#include "collision_std_internal.h" +#include "collision_util.h" +//#include +#include "windows.h" +#include "ode\ode.h" + +#define CONTACT(p,skip) ((dContactGeom*) (((char*)p) + (skip))) +#define MAXCONTACT 10 +#define TERRAINTOL 0.0f + +static bool IsAPowerOfTwo(int f) +{ + dAASSERT(f!=0); + while ((f&1) != 1) + f >>= 1; + + return (f == 1); +} + +static int GetPowerOfTwo(int f) +{ + dAASSERT(f!=0); + int n = 0; + while ((f&1) != 1) + { + n++; + f >>= 1; + } + + return n; +} + +dxTerrainZ::dxTerrainZ (dSpaceID space, dReal *pHeights,dReal vLength,int nNumNodesPerSide, int bFinite, int bPlaceable) : +dxGeom (space,bPlaceable) +{ + dIASSERT(IsAPowerOfTwo(nNumNodesPerSide)); + dIASSERT(pHeights); + dIASSERT(vLength > 0.f); + dIASSERT(nNumNodesPerSide > 0); + type = dTerrainZClass; + m_vLength = vLength; + m_pHeights = new dReal[nNumNodesPerSide * nNumNodesPerSide]; + dIASSERT(m_pHeights); + m_nNumNodesPerSide = nNumNodesPerSide; + m_vNodeLength = m_vLength / m_nNumNodesPerSide; + m_nNumNodesPerSideShift = GetPowerOfTwo(m_nNumNodesPerSide); + m_nNumNodesPerSideMask = m_nNumNodesPerSide - 1; + m_vMinHeight = dInfinity; + m_vMaxHeight = -dInfinity; + m_bFinite = bFinite; + + for (int i=0;i m_vMaxHeight) m_vMaxHeight = m_pHeights[i]; + } +} + +dxTerrainZ::~dxTerrainZ() +{ + dIASSERT(m_pHeights); + delete [] m_pHeights; +} + +void dxTerrainZ::computeAABB() +{ + if (m_bFinite) + { + if (gflags & GEOM_PLACEABLE) + { + dReal dx[6],dy[6],dz[6]; + dx[0] = 0; + dx[1] = final_posr->R[0] * m_vLength; + dx[2] = 0; + dx[3] = final_posr->R[1] * m_vLength; + dx[4] = final_posr->R[2] * m_vMinHeight; + dx[5] = final_posr->R[2] * m_vMaxHeight; + + dy[0] = 0; + dy[1] = final_posr->R[4] * m_vLength; + dy[2] = 0; + dy[3] = final_posr->R[5] * m_vLength; + dy[4] = final_posr->R[6] * m_vMinHeight; + dy[5] = final_posr->R[6] * m_vMaxHeight; + + dz[0] = 0; + dz[1] = final_posr->R[8] * m_vLength; + dz[2] = 0; + dz[3] = final_posr->R[9] * m_vLength; + dz[4] = final_posr->R[10] * m_vMinHeight; + dz[5] = final_posr->R[10] * m_vMaxHeight; + + aabb[0] = final_posr->pos[0] + MIN(dx[0],dx[1]) + MIN(dx[2],dx[3]) + MIN(dx[4],dx[5]); + aabb[1] = final_posr->pos[0] + MAX(dx[0],dx[1]) + MAX(dx[2],dx[3]) + MAX(dx[4],dx[5]); + aabb[2] = final_posr->pos[1] + MIN(dy[0],dy[1]) + MIN(dy[2],dy[3]) + MIN(dy[4],dy[5]); + aabb[3] = final_posr->pos[1] + MAX(dy[0],dy[1]) + MAX(dy[2],dy[3]) + MAX(dy[4],dy[5]); + aabb[4] = final_posr->pos[2] + MIN(dz[0],dz[1]) + MIN(dz[2],dz[3]) + MIN(dz[4],dz[5]); + aabb[5] = final_posr->pos[2] + MAX(dz[0],dz[1]) + MAX(dz[2],dz[3]) + MAX(dz[4],dz[5]); + } + else + { + aabb[0] = 0; + aabb[1] = m_vLength; + aabb[2] = 0; + aabb[3] = m_vLength; + aabb[4] = m_vMinHeight; + aabb[5] = m_vMaxHeight; + } + } + else + { + 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] = -dInfinity; + aabb[3] = dInfinity; + aabb[4] = m_vMinHeight; + aabb[5] = m_vMaxHeight; + } + } +} + +dReal dxTerrainZ::GetHeight(int x,int y) +{ + return m_pHeights[ (((unsigned int)(y) & m_nNumNodesPerSideMask) << m_nNumNodesPerSideShift) + + ((unsigned int)(x) & m_nNumNodesPerSideMask)]; +} + +dReal dxTerrainZ::GetHeight(dReal x,dReal y) +{ + int nX = int(floor(x / m_vNodeLength)); + int nY = int(floor(y / m_vNodeLength)); + dReal dx = (x - (dReal(nX) * m_vNodeLength)) / m_vNodeLength; + dReal dy = (y - (dReal(nY) * m_vNodeLength)) / m_vNodeLength; + dIASSERT((dx >= 0.f) && (dx <= 1.f)); + dIASSERT((dy >= 0.f) && (dy <= 1.f)); + + dReal z,z0; + + if (dx + dy < 1.f) + { + z0 = GetHeight(nX,nY); + z = z0 + + (GetHeight(nX+1,nY) - z0) * dx + + (GetHeight(nX,nY+1) - z0) * dy; + } + else + { + z0 = GetHeight(nX+1,nY+1); + z = z0 + + (GetHeight(nX+1,nY) - z0) * (1.f - dy) + + (GetHeight(nX,nY+1) - z0) * (1.f - dx); + } + + return z; +} + +bool dxTerrainZ::IsOnTerrain(int nx,int ny,int w,dReal *pos) +{ + dVector3 Min,Max; + Min[0] = nx * m_vNodeLength; + Min[1] = ny * m_vNodeLength; + Max[0] = (nx+1) * m_vNodeLength; + Max[1] = (ny+1) * m_vNodeLength; + dReal Tol = m_vNodeLength * TERRAINTOL; + + if ((pos[0]Max[0]+Tol)) + return false; + + if ((pos[1]Max[1]+Tol)) + return false; + + dReal dx = (pos[0] - (dReal(nx) * m_vNodeLength)) / m_vNodeLength; + dReal dy = (pos[1] - (dReal(ny) * m_vNodeLength)) / m_vNodeLength; + + if ((w == 0) && (dx + dy > 1.f+TERRAINTOL)) + return false; + + if ((w == 1) && (dx + dy < 1.f-TERRAINTOL)) + return false; + + return true; +} + +dGeomID dCreateTerrainZ(dSpaceID space, dReal *pHeights,dReal vLength,int nNumNodesPerSide, int bFinite, int bPlaceable) +{ + return new dxTerrainZ(space, pHeights,vLength,nNumNodesPerSide, bFinite, bPlaceable); +} + +dReal dGeomTerrainZPointDepth (dGeomID g, dReal x, dReal y, dReal z) +{ + dUASSERT (g && g->type == dTerrainZClass,"argument not a terrain"); + g->recomputePosr(); + dxTerrainZ *t = (dxTerrainZ*) g; + return t->GetHeight(x,y) - z; +} + +typedef dReal dGetDepthFn(dGeomID g, dReal x, dReal y, dReal z); +#define RECOMPUTE_RAYNORMAL +//#define DO_RAYDEPTH + +#define DMESS(A) \ + dMessage(0,"Contact Plane (%d %d %d) %.5e %.5e (%.5e %.5e %.5e)(%.5e %.5e %.5e)).", \ + x,y,A, \ + pContact->depth, \ + dGeomSphereGetRadius(o2), \ + pContact->pos[0], \ + pContact->pos[1], \ + pContact->pos[2], \ + pContact->normal[0], \ + pContact->normal[1], \ + pContact->normal[2]); +/* +(z is up) + +y +. +F +| +C-D +|\| +A-B-E.x +*/ +int dxTerrainZ::dCollideTerrainUnit( + int x,int y,dxGeom *o2,int numMaxContacts, + int flags,dContactGeom *contact, int skip) +{ + dColliderFn *CollideRayN; + dColliderFn *CollideNPlane; + dGetDepthFn *GetDepth; + int numContacts = 0; + int numPlaneContacts = 0; + int i; + + if (numContacts == numMaxContacts) + return numContacts; + + dContactGeom PlaneContact[MAXCONTACT]; + flags = (flags & 0xffff0000) | MAXCONTACT; + + switch (o2->type) + { + case dSphereClass: + CollideRayN = dCollideRaySphere; + CollideNPlane = dCollideSpherePlane; + GetDepth = dGeomSpherePointDepth; + break; + case dBoxClass: + CollideRayN = dCollideRayBox; + CollideNPlane = dCollideBoxPlane; + GetDepth = dGeomBoxPointDepth; + break; + case dCCylinderClass: + CollideRayN = dCollideRayCCylinder; + CollideNPlane = dCollideCCylinderPlane; + GetDepth = dGeomCCylinderPointDepth; + break; + case dRayClass: + CollideRayN = NULL; + CollideNPlane = dCollideRayPlane; + GetDepth = NULL; + break; + case dConeClass: + CollideRayN = dCollideRayCone; + CollideNPlane = dCollideConePlane; + GetDepth = dGeomConePointDepth; + break; + default: + dIASSERT(0); + } + + dReal Plane[4],lBD,lCD,lBC; + dVector3 A,B,C,D,BD,CD,BC,AB,AC; + A[0] = x * m_vNodeLength; + A[1] = y * m_vNodeLength; + A[2] = GetHeight(x,y); + B[0] = (x+1) * m_vNodeLength; + B[1] = y * m_vNodeLength; + B[2] = GetHeight(x+1,y); + C[0] = x * m_vNodeLength; + C[1] = (y+1) * m_vNodeLength; + C[2] = GetHeight(x,y+1); + D[0] = (x+1) * m_vNodeLength; + D[1] = (y+1) * m_vNodeLength; + D[2] = GetHeight(x+1,y+1); + + dOP(BC,-,C,B); + lBC = dLENGTH(BC); + dOPEC(BC,/=,lBC); + + dOP(BD,-,D,B); + lBD = dLENGTH(BD); + dOPEC(BD,/=,lBD); + + dOP(CD,-,D,C); + lCD = dLENGTH(CD); + dOPEC(CD,/=,lCD); + + dOP(AB,-,B,A); + dNormalize3(AB); + + dOP(AC,-,C,A); + dNormalize3(AC); + + if (CollideRayN) + { +#ifdef RECOMPUTE_RAYNORMAL + dVector3 E,F; + dVector3 CE,FB,AD; + dVector3 Normal[3]; + E[0] = (x+2) * m_vNodeLength; + E[1] = y * m_vNodeLength; + E[2] = GetHeight(x+2,y); + F[0] = x * m_vNodeLength; + F[1] = (y+2) * m_vNodeLength; + F[2] = GetHeight(x,y+2); + dOP(AD,-,D,A); + dNormalize3(AD); + dOP(CE,-,E,C); + dNormalize3(CE); + dOP(FB,-,B,F); + dNormalize3(FB); + + //BC + dCROSS(Normal[0],=,AD,BC); + dNormalize3(Normal[0]); + + //BD + dCROSS(Normal[1],=,CE,BD); + dNormalize3(Normal[1]); + + //CD + dCROSS(Normal[2],=,FB,CD); + dNormalize3(Normal[2]); +#endif + int nA[3],nB[3]; + dContactGeom ContactA[3],ContactB[3]; + dxRay rayBC(0,lBC); + dGeomRaySet(&rayBC, B[0], B[1], B[2], BC[0], BC[1], BC[2]); + nA[0] = CollideRayN(&rayBC,o2,flags,&ContactA[0],sizeof(dContactGeom)); + dGeomRaySet(&rayBC, C[0], C[1], C[2], -BC[0], -BC[1], -BC[2]); + nB[0] = CollideRayN(&rayBC,o2,flags,&ContactB[0],sizeof(dContactGeom)); + + dxRay rayBD(0,lBD); + dGeomRaySet(&rayBD, B[0], B[1], B[2], BD[0], BD[1], BD[2]); + nA[1] = CollideRayN(&rayBD,o2,flags,&ContactA[1],sizeof(dContactGeom)); + dGeomRaySet(&rayBD, D[0], D[1], D[2], -BD[0], -BD[1], -BD[2]); + nB[1] = CollideRayN(&rayBD,o2,flags,&ContactB[1],sizeof(dContactGeom)); + + dxRay rayCD(0,lCD); + dGeomRaySet(&rayCD, C[0], C[1], C[2], CD[0], CD[1], CD[2]); + nA[2] = CollideRayN(&rayCD,o2,flags,&ContactA[2],sizeof(dContactGeom)); + dGeomRaySet(&rayCD, D[0], D[1], D[2], -CD[0], -CD[1], -CD[2]); + nB[2] = CollideRayN(&rayCD,o2,flags,&ContactB[2],sizeof(dContactGeom)); + + for (i=0;i<3;i++) + { + if (nA[i] & nB[i]) + { + dContactGeom *pContact = CONTACT(contact,numContacts*skip); + pContact->pos[0] = (ContactA[i].pos[0] + ContactB[i].pos[0])/2; + pContact->pos[1] = (ContactA[i].pos[1] + ContactB[i].pos[1])/2; + pContact->pos[2] = (ContactA[i].pos[2] + ContactB[i].pos[2])/2; +#ifdef RECOMPUTE_RAYNORMAL + pContact->normal[0] = -Normal[i][0]; + pContact->normal[1] = -Normal[i][1]; + pContact->normal[2] = -Normal[i][2]; +#else + pContact->normal[0] = (ContactA[i].normal[0] + ContactB[i].normal[0])/2; //0.f; + pContact->normal[1] = (ContactA[i].normal[1] + ContactB[i].normal[1])/2; //0.f; + pContact->normal[2] = (ContactA[i].normal[2] + ContactB[i].normal[2])/2; //-1.f; + dNormalize3(pContact->normal); +#endif +#ifdef DO_RAYDEPTH + dxRay rayV(0,1000.f); + dGeomRaySet(&rayV, pContact->pos[0], + pContact->pos[1], + pContact->pos[2], + -pContact->normal[0], + -pContact->normal[1], + -pContact->normal[2]); + + dContactGeom ContactV; + if (CollideRayN(&rayV,o2,flags,&ContactV,sizeof(dContactGeom))) + { + pContact->depth = ContactV.depth; + numContacts++; + } +#else + if (GetDepth == NULL) + { + dxRay rayV(0,1000.f); + dGeomRaySet(&rayV, pContact->pos[0], + pContact->pos[1], + pContact->pos[2], + -pContact->normal[0], + -pContact->normal[1], + -pContact->normal[2]); + + dContactGeom ContactV; + if (CollideRayN(&rayV,o2,flags,&ContactV,sizeof(dContactGeom))) + { + pContact->depth = ContactV.depth; + numContacts++; + } + } + else + { + pContact->depth = GetDepth(o2, + pContact->pos[0], + pContact->pos[1], + pContact->pos[2]); + numContacts++; + } +#endif + if (numContacts == numMaxContacts) + return numContacts; + + } + } + } + + dCROSS(Plane,=,AB,AC); + dNormalize3(Plane); + Plane[3] = Plane[0] * A[0] + Plane[1] * A[1] + Plane[2] * A[2]; + dxPlane planeABC(0,Plane[0],Plane[1],Plane[2],Plane[3]); + numPlaneContacts = CollideNPlane(o2,&planeABC,flags,PlaneContact,sizeof(dContactGeom)); + + for (i=0;ipos[0] = PlaneContact[i].pos[0]; + pContact->pos[1] = PlaneContact[i].pos[1]; + pContact->pos[2] = PlaneContact[i].pos[2]; + pContact->normal[0] = -PlaneContact[i].normal[0]; + pContact->normal[1] = -PlaneContact[i].normal[1]; + pContact->normal[2] = -PlaneContact[i].normal[2]; + pContact->depth = PlaneContact[i].depth; + + //DMESS(0); + numContacts++; + + if (numContacts == numMaxContacts) + return numContacts; + } + } + + dCROSS(Plane,=,CD,BD); + dNormalize3(Plane); + Plane[3] = Plane[0] * D[0] + Plane[1] * D[1] + Plane[2] * D[2]; + dxPlane planeDCB(0,Plane[0],Plane[1],Plane[2],Plane[3]); + numPlaneContacts = CollideNPlane(o2,&planeDCB,flags,PlaneContact,sizeof(dContactGeom)); + + for (i=0;ipos[0] = PlaneContact[i].pos[0]; + pContact->pos[1] = PlaneContact[i].pos[1]; + pContact->pos[2] = PlaneContact[i].pos[2]; + pContact->normal[0] = -PlaneContact[i].normal[0]; + pContact->normal[1] = -PlaneContact[i].normal[1]; + pContact->normal[2] = -PlaneContact[i].normal[2]; + pContact->depth = PlaneContact[i].depth; + //DMESS(1); + numContacts++; + + if (numContacts == numMaxContacts) + return numContacts; + } + } + + return numContacts; +} + +int dCollideTerrainZ(dxGeom *o1, dxGeom *o2, int flags,dContactGeom *contact, int skip) +{ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (o1->type == dTerrainZClass); + int i,j; + + if ((flags & 0xffff) == 0) + flags = (flags & 0xffff0000) | 1; + + int numMaxTerrainContacts = (flags & 0xffff); + dxTerrainZ *terrain = (dxTerrainZ*) o1; + + dReal aabbbak[6]; + int gflagsbak; + + dVector3 pos0; + int numTerrainContacts = 0; + + dxPosR *bak; + dxPosR X1; + + if (terrain->gflags & GEOM_PLACEABLE) + { + dOP(pos0,-,o2->final_posr->pos,terrain->final_posr->pos); + dMULTIPLY1_331(X1.pos,terrain->final_posr->R,pos0); + dMULTIPLY1_333(X1.R,terrain->final_posr->R,o2->final_posr->R); + bak = o2->final_posr; + o2->final_posr = &X1; + memcpy(aabbbak,o2->aabb,sizeof(dReal)*6); + gflagsbak = o2->gflags; + o2->computeAABB(); + } + + int nMinX = int(floor(o2->aabb[0] / terrain->m_vNodeLength)); + int nMaxX = int(floor(o2->aabb[1] / terrain->m_vNodeLength)) + 1; + int nMinY = int(floor(o2->aabb[2] / terrain->m_vNodeLength)); + int nMaxY = int(floor(o2->aabb[3] / terrain->m_vNodeLength)) + 1; + + if (terrain->m_bFinite) + { + nMinX = MAX(nMinX,0); + nMaxX = MIN(nMaxX,terrain->m_nNumNodesPerSide); + nMinY = MAX(nMinY,0); + nMaxY = MIN(nMaxY,terrain->m_nNumNodesPerSide); + + if ((nMinX >= nMaxX) || (nMinY >= nMaxY)) + goto dCollideTerrainZExit; + } + + dVector3 AabbTop; + AabbTop[0] = (o2->aabb[0]+o2->aabb[1]) / 2; + AabbTop[1] = (o2->aabb[2]+o2->aabb[3]) / 2; + AabbTop[2] = o2->aabb[5]; + if (o2->type != dRayClass) + { + dReal AabbTopDepth = terrain->GetHeight(AabbTop[0],AabbTop[1]) - AabbTop[2]; + if (AabbTopDepth > 0.f) + { + contact->depth = AabbTopDepth; + dReal MaxDepth = (o2->aabb[5]-o2->aabb[4]) / 2; + if (contact->depth > MaxDepth) + contact->depth = MaxDepth; + contact->g1 = o1; + contact->g2 = o2; + dOPE(contact->pos,=,AabbTop); + contact->normal[0] = 0.f; + contact->normal[1] = 0.f; + contact->normal[2] = -1.f; + + numTerrainContacts = 1; + goto dCollideTerrainZExit; + } + } + + for (i=nMinX;idCollideTerrainUnit( + i,j,o2,numMaxTerrainContacts - numTerrainContacts, + flags,CONTACT(contact,numTerrainContacts*skip),skip ); + } + } + + dIASSERT(numTerrainContacts <= numMaxTerrainContacts); + + for (i=0; ig1 = o1; + CONTACT(contact,i*skip)->g2 = o2; + } + +dCollideTerrainZExit: + + if (terrain->gflags & GEOM_PLACEABLE) + { + o2->final_posr = bak; + memcpy(o2->aabb,aabbbak,sizeof(dReal)*6); + o2->gflags = gflagsbak; + + for (i=0; ipos); + dMULTIPLY0_331(CONTACT(contact,i*skip)->pos,terrain->final_posr->R,pos0); + dOP(CONTACT(contact,i*skip)->pos,+,CONTACT(contact,i*skip)->pos,terrain->final_posr->pos); + + dOPE(pos0,=,CONTACT(contact,i*skip)->normal); + dMULTIPLY0_331(CONTACT(contact,i*skip)->normal,terrain->final_posr->R,pos0); + } + } + + return numTerrainContacts; +} +/* +void dsDrawTerrainZ(int x,int z,float vLength,float vNodeLength,int nNumNodesPerSide,float *pHeights,const float *pR,const float *ppos) +{ + float A[3],B[3],C[3],D[3]; + float R[12]; + float pos[3]; + if (pR) + memcpy(R,pR,sizeof(R)); + else + { + memset(R,0,sizeof(R)); + R[0] = 1.f; + R[5] = 1.f; + R[10] = 1.f; + } + + if (ppos) + memcpy(pos,ppos,sizeof(pos)); + else + memset(pos,0,sizeof(pos)); + + float vx,vz; + vx = vLength * x; + vz = vLength * z; + + int i; + for (i=0;i edit each .cpp file and comment out #include "windows.h" & #include "ode\ode.h" + + +*** add to drawstuff\src\drawstuff.cpp: + +static void drawCone(float l, float r) +{ + int i; + float tmp,ny,nz,a,ca,sa; + const int n = 24; // number of sides to the cone (divisible by 4) + + a = float(M_PI*2.0)/float(n); + sa = (float) sin(a); + ca = (float) cos(a); + + // draw top + glShadeModel (GL_FLAT); + ny=1; nz=0; // normal vector = (0,ny,nz) + glBegin (GL_TRIANGLE_FAN); + glNormal3d (0,0,1); + glVertex3d (0,0,l); + 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 (ny*r,nz*r,0); + glVertex3d (ny*r,nz*r,0); + 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 + ny=1; nz=0; // normal vector = (0,ny,nz) + glBegin (GL_TRIANGLE_FAN); + glNormal3d (0,0,-1); + glVertex3d (0,0,0); + 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,0); + 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(); +} + +void dsDrawCone (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); + drawCone (length,radius); + glPopMatrix(); + + if (use_shadows) { + setShadowDrawingMode(); + setShadowTransform(); + setTransform (pos,R); + drawCone (length,radius); + glPopMatrix(); + glPopMatrix(); + glDepthRange (0,1); + } +} + +void dsDrawConeD (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]; + dsDrawCone(pos2,R2,length,radius); +} + +static float GetHeight(int x,int y,int nNumNodesPerSide,float *pHeights) +{ + int nNumNodesPerSideMask = nNumNodesPerSide - 1; + return pHeights[ (((unsigned int)(y) & nNumNodesPerSideMask) * nNumNodesPerSide) + + ((unsigned int)(x) & nNumNodesPerSideMask)]; +} + +void dsDrawTerrainY(int x,int z,float vLength,float vNodeLength,int nNumNodesPerSide,float *pHeights,const float *pR,const float *ppos) +{ + float A[3],B[3],C[3],D[3]; + float R[12]; + float pos[3]; + if (pR) + memcpy(R,pR,sizeof(R)); + else + { + memset(R,0,sizeof(R)); + R[0] = 1.f; + R[5] = 1.f; + R[10] = 1.f; + } + + if (ppos) + memcpy(pos,ppos,sizeof(pos)); + else + memset(pos,0,sizeof(pos)); + + float vx,vz; + vx = vLength * x; + vz = vLength * z; + + int i; + for (i=0;i add dCone.cpp, dTerrainY.cpp and dTerrainZ.cpp to the the libode_a_SOURCES variable in the ode/src/Makefile.am file. + +*** now you can now test using file test_boxstackb.cpp (to add in folder ode\test). + diff --git a/libraries/ode-0.9/contrib/TerrainAndCone/test_boxstackb.cpp b/libraries/ode-0.9/contrib/TerrainAndCone/test_boxstackb.cpp new file mode 100644 index 0000000000..f1fa592988 --- /dev/null +++ b/libraries/ode-0.9/contrib/TerrainAndCone/test_boxstackb.cpp @@ -0,0 +1,1375 @@ +/************************************************************************* + + +* * + + +* Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + + +* All rights reserved. Email: russ@q12.org Web: www.q12.org * + + +* * + + +* This library is free software; you can redistribute it and/or * + + +* modify it under the terms of EITHER: * + + +* (1) The GNU Lesser General Public License as published by the Free * + + +* Software Foundation; either version 2.1 of the License, or (at * + + +* your option) any later version. The text of the GNU Lesser * + + +* General Public License is included with this library in the * + + +* file LICENSE.TXT. * + + +* (2) The BSD-style license that is included with this library in * + + +* the file LICENSE-BSD.TXT. * + + +* * + + +* This library is distributed in the hope that it will be useful, * + + +* but WITHOUT ANY WARRANTY; without 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 + + + + + +#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 dsDrawCappedCylinder dsDrawCappedCylinderD + + +#endif + + + + + + + + +// some constants + + + + + +const dReal vTerrainLength = 4.f; + + +const dReal vTerrainHeight = 0.5f; + + +const int TERRAINNODES = 4; + + +dReal pTerrainHeights[TERRAINNODES*TERRAINNODES]; + + + + + +dGeomID terrainZ = NULL; + + +dGeomID terrainY = NULL; + + + + + +#define NUM 20 // 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 + + + + + + + + +// 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? + + + + + + + + +// 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()+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,maxheight+1,maxheight+3); + + + 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; + + + dMassSetCappedCylinder (&m,DENSITY,3,sides[0],sides[1]); + + + obj[i].geom[0] = dCreateCCylinder (space,sides[0],sides[1]); + + + } + + + /* + + + // cylinder option not yet implemented + + + else if (cmd == 'l') { + + + sides[1] *= 0.5; + + + dMassSetCappedCylinder (&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) + + +{ + + + 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 == dCCylinderClass) { + + + dReal radius,length; + + + dGeomCCylinderGetParams (g,&radius,&length); + + + dsDrawCappedCylinder (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 (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) dWorldStep (world,0.05); + + + + + + dAASSERT(terrainY); + + + dAASSERT(terrainZ); + + + dsSetColor (0,1,0); + + + dsDrawTerrainY(0,0,vTerrainLength,vTerrainLength/TERRAINNODES,TERRAINNODES,pTerrainHeights,dGeomGetRotation(terrainY),dGeomGetPosition(terrainY)); + + + dsDrawTerrainZ(0,0,vTerrainLength,vTerrainLength/TERRAINNODES,TERRAINNODES,pTerrainHeights,dGeomGetRotation(terrainZ),dGeomGetPosition(terrainZ)); + + + + + + if (show_aabb) + + + { + + + dReal aabb[6]; + + + dGeomGetAABB (terrainY,aabb); + + + dVector3 bbpos; + + + int i; + + + 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); + + + + + + dGeomGetAABB (terrainZ,aabb); + + + for (i=0; i<3; i++) bbpos[i] = 0.5*(aabb[i*2] + aabb[i*2+1]); + + + for (i=0; i<3; i++) bbsides[i] = aabb[i*2+1] - aabb[i*2]; + + + dsDrawBox (bbpos,RI,bbsides); + + + } + + + + + + dsSetColor (1,1,0); + + + + + + // remove all contact joints + + + dJointGroupEmpty (contactgroup); + + + + + + dsSetColor (1,1,0); + + + dsSetTexture (DS_WOOD); + + + for (int i=0; i +#include "dCylinder.h" +// given a pointer `p' to a dContactGeom, return the dContactGeom at +// p + skip bytes. + +struct dxCylinder { // cylinder + dReal radius,lz; // radius, length along y axis // +}; + +int dCylinderClassUser = -1; + +#define NUMC_MASK (0xffff) + +#define CONTACT(p,skip) ((dContactGeom*) (((char*)p) + (skip))) + +///////////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////circleIntersection////////////////////////////////////////////////// +//this does following: +//takes two circles as normals to planes n1,n2, center points cp1,cp2,and radiuses r1,r2 +//finds line on which circles' planes intersect +//finds four points O1,O2 - intersection between the line and sphere with center cp1 radius r1 +// O3,O4 - intersection between the line and sphere with center cp2 radius r2 +//returns false if there is no intersection +//computes distances O1-O3, O1-O4, O2-O3, O2-O4 +//in "point" returns mean point between intersection points with smallest distance +///////////////////////////////////////////////////////////////////////////////////////////////// +inline bool circleIntersection(const dReal* n1,const dReal* cp1,dReal r1,const dReal* n2,const dReal* cp2,dReal r2,dVector3 point){ +dReal c1=dDOT14(cp1,n1); +dReal c2=dDOT14(cp2,n2); +dReal cos=dDOT44(n1,n2); +dReal cos_2=cos*cos; +dReal sin_2=1-cos_2; +dReal p1=(c1-c2*cos)/sin_2; +dReal p2=(c2-c1*cos)/sin_2; +dVector3 lp={p1*n1[0]+p2*n2[0],p1*n1[4]+p2*n2[4],p1*n1[8]+p2*n2[8]}; +dVector3 n; +dCROSS144(n,=,n1,n2); +dVector3 LC1={lp[0]-cp1[0],lp[1]-cp1[1],lp[2]-cp1[2]}; +dVector3 LC2={lp[0]-cp2[0],lp[1]-cp2[1],lp[2]-cp2[2]}; +dReal A,B,C,B_A,B_A_2,D; +dReal t1,t2,t3,t4; +A=dDOT(n,n); +B=dDOT(LC1,n); +C=dDOT(LC1,LC1)-r1*r1; +B_A=B/A; +B_A_2=B_A*B_A; +D=B_A_2-C; +if(D<0.f){ //somewhat strange solution + //- it is needed to set some + //axis to sepparate cylinders + //when their edges approach + t1=-B_A+sqrtf(-D); + t2=-B_A-sqrtf(-D); +// return false; + } +else{ +t1=-B_A-sqrtf(D); +t2=-B_A+sqrtf(D); +} +B=dDOT(LC2,n); +C=dDOT(LC2,LC2)-r2*r2; +B_A=B/A; +B_A_2=B_A*B_A; +D=B_A_2-C; + +if(D<0.f) { + t3=-B_A+sqrtf(-D); + t4=-B_A-sqrtf(-D); +// return false; + } +else{ +t3=-B_A-sqrtf(D); +t4=-B_A+sqrtf(D); +} +dVector3 O1={lp[0]+n[0]*t1,lp[1]+n[1]*t1,lp[2]+n[2]*t1}; +dVector3 O2={lp[0]+n[0]*t2,lp[1]+n[1]*t2,lp[2]+n[2]*t2}; + +dVector3 O3={lp[0]+n[0]*t3,lp[1]+n[1]*t3,lp[2]+n[2]*t3}; +dVector3 O4={lp[0]+n[0]*t4,lp[1]+n[1]*t4,lp[2]+n[2]*t4}; + +dVector3 L1_3={O3[0]-O1[0],O3[1]-O1[1],O3[2]-O1[2]}; +dVector3 L1_4={O4[0]-O1[0],O4[1]-O1[1],O4[2]-O1[2]}; + +dVector3 L2_3={O3[0]-O2[0],O3[1]-O2[1],O3[2]-O2[2]}; +dVector3 L2_4={O4[0]-O2[0],O4[1]-O2[1],O4[2]-O2[2]}; + + +dReal l1_3=dDOT(L1_3,L1_3); +dReal l1_4=dDOT(L1_4,L1_4); + +dReal l2_3=dDOT(L2_3,L2_3); +dReal l2_4=dDOT(L2_4,L2_4); + + +if (l1_3 0) return 0; \ + if (s2 > s) { \ + s = s2; \ + normalR = norm; \ + invert_normal = ((expr1) < 0); \ + *code = (cc); \ + } + + s = -dInfinity; + invert_normal = 0; + *code = 0; + + // separating axis = cylinder ax u2 + //used when a box vertex touches a flat face of the cylinder + TEST (pp[1],(hlz + B1*Q21 + B2*Q22 + B3*Q23),R1+1,0); + + + // separating axis = box axis v1,v2,v3 + //used when cylinder edge touches box face + //there is two ways to compute sQ: sQ21=sqrtf(1.f-Q21*Q21); or sQ21=sqrtf(Q23*Q23+Q22*Q22); + //if we did not need Q23 and Q22 the first way might be used to quiken the routine but then it need to + //check if Q21<=1.f, becouse it may slightly exeed 1.f. + + + sQ21=sqrtf(Q23*Q23+Q22*Q22); + TEST (dDOT41(R2+0,p),(radius*sQ21 + hlz*Q21 + B1),R2+0,1); + + sQ22=sqrtf(Q23*Q23+Q21*Q21); + TEST (dDOT41(R2+1,p),(radius*sQ22 + hlz*Q22 + B2),R2+1,2); + + sQ23=sqrtf(Q22*Q22+Q21*Q21); + TEST (dDOT41(R2+2,p),(radius*sQ23 + hlz*Q23 + B3),R2+2,3); + + +#undef TEST +#define TEST(expr1,expr2,n1,n2,n3,cc) \ + s2 = dFabs(expr1) - (expr2); \ + if (s2 > 0) return 0; \ + if (s2 > s) { \ + s = s2; \ + normalR = 0; \ + normalC[0] = (n1); normalC[1] = (n2); normalC[2] = (n3); \ + invert_normal = ((expr1) < 0); \ + *code = (cc); \ + } + + + +// separating axis is a normal to the cylinder axis passing across the nearest box vertex +//used when a box vertex touches the lateral surface of the cylinder + +dReal proj,boxProj,cos,sin,cos1,cos3; +dVector3 tAx,Ax,pb; +{ +//making Ax which is perpendicular to cyl ax to box position// +proj=dDOT14(p2,R1+1)-dDOT14(p1,R1+1); + +Ax[0]=p2[0]-p1[0]-R1[1]*proj; +Ax[1]=p2[1]-p1[1]-R1[5]*proj; +Ax[2]=p2[2]-p1[2]-R1[9]*proj; +dNormalize3(Ax); +//using Ax find box vertex which is nearest to the cylinder axis + dReal sign; + + for (i=0; i<3; i++) pb[i] = p2[i]; + sign = (dDOT14(Ax,R2+0) > 0) ? REAL(-1.0) : REAL(1.0); + for (i=0; i<3; i++) pb[i] += sign * B1 * R2[i*4]; + sign = (dDOT14(Ax,R2+1) > 0) ? REAL(-1.0) : REAL(1.0); + for (i=0; i<3; i++) pb[i] += sign * B2 * R2[i*4+1]; + sign = (dDOT14(Ax,R2+2) > 0) ? REAL(-1.0) : REAL(1.0); + for (i=0; i<3; i++) pb[i] += sign * B3 * R2[i*4+2]; + +//building axis which is normal to cylinder ax to the nearest box vertex +proj=dDOT14(pb,R1+1)-dDOT14(p1,R1+1); + +Ax[0]=pb[0]-p1[0]-R1[1]*proj; +Ax[1]=pb[1]-p1[1]-R1[5]*proj; +Ax[2]=pb[2]-p1[2]-R1[9]*proj; +dNormalize3(Ax); +} + +boxProj=dFabs(dDOT14(Ax,R2+0)*B1)+ + dFabs(dDOT14(Ax,R2+1)*B2)+ + dFabs(dDOT14(Ax,R2+2)*B3); + +TEST(p[0]*Ax[0]+p[1]*Ax[1]+p[2]*Ax[2],(radius+boxProj),Ax[0],Ax[1],Ax[2],4); + + +//next three test used to handle collisions between cylinder circles and box ages +proj=dDOT14(p1,R2+0)-dDOT14(p2,R2+0); + +tAx[0]=-p1[0]+p2[0]+R2[0]*proj; +tAx[1]=-p1[1]+p2[1]+R2[4]*proj; +tAx[2]=-p1[2]+p2[2]+R2[8]*proj; +dNormalize3(tAx); + +//now tAx is normal to first ax of the box to cylinder center +//making perpendicular to tAx lying in the plane which is normal to the cylinder axis +//it is tangent in the point where projection of tAx on cylinder's ring intersect edge circle + +cos=dDOT14(tAx,R1+0); +sin=dDOT14(tAx,R1+2); +tAx[0]=R1[2]*cos-R1[0]*sin; +tAx[1]=R1[6]*cos-R1[4]*sin; +tAx[2]=R1[10]*cos-R1[8]*sin; + + +//use cross between tAx and first ax of the box as separating axix + +dCROSS114(Ax,=,tAx,R2+0); +dNormalize3(Ax); + +boxProj=dFabs(dDOT14(Ax,R2+1)*B2)+ + dFabs(dDOT14(Ax,R2+0)*B1)+ + dFabs(dDOT14(Ax,R2+2)*B3); + + cos=dFabs(dDOT14(Ax,R1+1)); + cos1=dDOT14(Ax,R1+0); + cos3=dDOT14(Ax,R1+2); + sin=sqrtf(cos1*cos1+cos3*cos3); + +TEST(p[0]*Ax[0]+p[1]*Ax[1]+p[2]*Ax[2],(sin*radius+cos*hlz+boxProj),Ax[0],Ax[1],Ax[2],5); + + +//same thing with the second axis of the box +proj=dDOT14(p1,R2+1)-dDOT14(p2,R2+1); + +tAx[0]=-p1[0]+p2[0]+R2[1]*proj; +tAx[1]=-p1[1]+p2[1]+R2[5]*proj; +tAx[2]=-p1[2]+p2[2]+R2[9]*proj; +dNormalize3(tAx); + + +cos=dDOT14(tAx,R1+0); +sin=dDOT14(tAx,R1+2); +tAx[0]=R1[2]*cos-R1[0]*sin; +tAx[1]=R1[6]*cos-R1[4]*sin; +tAx[2]=R1[10]*cos-R1[8]*sin; + +dCROSS114(Ax,=,tAx,R2+1); +dNormalize3(Ax); + +boxProj=dFabs(dDOT14(Ax,R2+0)*B1)+ + dFabs(dDOT14(Ax,R2+1)*B2)+ + dFabs(dDOT14(Ax,R2+2)*B3); + + cos=dFabs(dDOT14(Ax,R1+1)); + cos1=dDOT14(Ax,R1+0); + cos3=dDOT14(Ax,R1+2); + sin=sqrtf(cos1*cos1+cos3*cos3); +TEST(p[0]*Ax[0]+p[1]*Ax[1]+p[2]*Ax[2],(sin*radius+cos*hlz+boxProj),Ax[0],Ax[1],Ax[2],6); + +//same thing with the third axis of the box +proj=dDOT14(p1,R2+2)-dDOT14(p2,R2+2); + +Ax[0]=-p1[0]+p2[0]+R2[2]*proj; +Ax[1]=-p1[1]+p2[1]+R2[6]*proj; +Ax[2]=-p1[2]+p2[2]+R2[10]*proj; +dNormalize3(tAx); + +cos=dDOT14(tAx,R1+0); +sin=dDOT14(tAx,R1+2); +tAx[0]=R1[2]*cos-R1[0]*sin; +tAx[1]=R1[6]*cos-R1[4]*sin; +tAx[2]=R1[10]*cos-R1[8]*sin; + +dCROSS114(Ax,=,tAx,R2+2); +dNormalize3(Ax); +boxProj=dFabs(dDOT14(Ax,R2+1)*B2)+ + dFabs(dDOT14(Ax,R2+2)*B3)+ + dFabs(dDOT14(Ax,R2+0)*B1); + + cos=dFabs(dDOT14(Ax,R1+1)); + cos1=dDOT14(Ax,R1+0); + cos3=dDOT14(Ax,R1+2); + sin=sqrtf(cos1*cos1+cos3*cos3); +TEST(p[0]*Ax[0]+p[1]*Ax[1]+p[2]*Ax[2],(sin*radius+cos*hlz+boxProj),Ax[0],Ax[1],Ax[2],7); + + +#undef TEST + +// note: cross product axes need to be scaled when s is computed. +// normal (n1,n2,n3) is relative to box 1. + +#define TEST(expr1,expr2,n1,n2,n3,cc) \ + s2 = dFabs(expr1) - (expr2); \ + if (s2 > 0) return 0; \ + l = dSqrt ((n1)*(n1) + (n2)*(n2) + (n3)*(n3)); \ + if (l > 0) { \ + s2 /= l; \ + if (s2 > s) { \ + s = s2; \ + normalR = 0; \ + normalC[0] = (n1)/l; normalC[1] = (n2)/l; normalC[2] = (n3)/l; \ + invert_normal = ((expr1) < 0); \ + *code = (cc); \ + } \ + } + +//crosses between cylinder axis and box axes + // separating axis = u2 x (v1,v2,v3) + TEST(pp[0]*R31-pp[2]*R11,(radius+B2*Q23+B3*Q22),R31,0,-R11,8); + TEST(pp[0]*R32-pp[2]*R12,(radius+B1*Q23+B3*Q21),R32,0,-R12,9); + TEST(pp[0]*R33-pp[2]*R13,(radius+B1*Q22+B2*Q21),R33,0,-R13,10); + + +#undef TEST + + // 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 { + if(*code>7) dMULTIPLY0_331 (normal,R1,normalC); + else {normal[0] =normalC[0];normal[1] = normalC[1];normal[2] = normalC[2];} + } + if (invert_normal) { + normal[0] = -normal[0]; + normal[1] = -normal[1]; + normal[2] = -normal[2]; + } + *depth = -s; + + // compute contact point(s) + + if (*code > 7) { + //find point on the cylinder pa deepest along normal + dVector3 pa; + dReal sign, cos1,cos3,factor; + + + for (i=0; i<3; i++) pa[i] = p1[i]; + + cos1 = dDOT14(normal,R1+0); + cos3 = dDOT14(normal,R1+2) ; + factor=sqrtf(cos1*cos1+cos3*cos3); + + cos1/=factor; + cos3/=factor; + + for (i=0; i<3; i++) pa[i] += cos1 * radius * R1[i*4]; + + sign = (dDOT14(normal,R1+1) > 0) ? REAL(1.0) : REAL(-1.0); + for (i=0; i<3; i++) pa[i] += sign * hlz * R1[i*4+1]; + + + for (i=0; i<3; i++) pa[i] += cos3 * radius * R1[i*4+2]; + + // find vertex of the box deepest along normal + dVector3 pb; + for (i=0; i<3; i++) pb[i] = p2[i]; + sign = (dDOT14(normal,R2+0) > 0) ? REAL(-1.0) : REAL(1.0); + for (i=0; i<3; i++) pb[i] += sign * B1 * R2[i*4]; + sign = (dDOT14(normal,R2+1) > 0) ? REAL(-1.0) : REAL(1.0); + for (i=0; i<3; i++) pb[i] += sign * B2 * R2[i*4+1]; + sign = (dDOT14(normal,R2+2) > 0) ? REAL(-1.0) : REAL(1.0); + for (i=0; i<3; i++) pb[i] += sign * B3 * R2[i*4+2]; + + + dReal alpha,beta; + dVector3 ua,ub; + for (i=0; i<3; i++) ua[i] = R1[1 + i*4]; + for (i=0; i<3; i++) ub[i] = R2[*code-8 + i*4]; + + lineClosestApproach (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; + + for (i=0; i<3; i++) contact[0].pos[i] = REAL(0.5)*(pa[i]+pb[i]); + contact[0].depth = *depth; + return 1; + } + + + if(*code==4){ + for (i=0; i<3; i++) contact[0].pos[i] = pb[i]; + contact[0].depth = *depth; + return 1; + } + + + dVector3 vertex; + if (*code == 0) { + + dReal sign; + for (i=0; i<3; i++) vertex[i] = p2[i]; + sign = (dDOT14(normal,R2+0) > 0) ? REAL(-1.0) : REAL(1.0); + for (i=0; i<3; i++) vertex[i] += sign * B1 * R2[i*4]; + sign = (dDOT14(normal,R2+1) > 0) ? REAL(-1.0) : REAL(1.0); + for (i=0; i<3; i++) vertex[i] += sign * B2 * R2[i*4+1]; + sign = (dDOT14(normal,R2+2) > 0) ? REAL(-1.0) : REAL(1.0); + for (i=0; i<3; i++) vertex[i] += sign * B3 * R2[i*4+2]; + } + else { + + dReal sign,cos1,cos3,factor; + for (i=0; i<3; i++) vertex[i] = p1[i]; + cos1 = dDOT14(normal,R1+0) ; + cos3 = dDOT14(normal,R1+2); + factor=sqrtf(cos1*cos1+cos3*cos3); + factor= factor ? factor : 1.f; + cos1/=factor; + cos3/=factor; + for (i=0; i<3; i++) vertex[i] += cos1 * radius * R1[i*4]; + + sign = (dDOT14(normal,R1+1) > 0) ? REAL(1.0) : REAL(-1.0); + for (i=0; i<3; i++) vertex[i] += sign * hlz * R1[i*4+1]; + + for (i=0; i<3; i++) vertex[i] += cos3 * radius * R1[i*4+2]; + } + for (i=0; i<3; i++) contact[0].pos[i] = vertex[i]; + contact[0].depth = *depth; + return 1; +} + +//**************************************************************************** + +extern "C" int dCylCyl (const dVector3 p1, const dMatrix3 R1, + const dReal radius1,const dReal lz1, const dVector3 p2, + const dMatrix3 R2, const dReal radius2,const dReal lz2, + dVector3 normal, dReal *depth, int *code, + int maxc, dContactGeom *contact, int skip) +{ + dVector3 p,pp1,pp2,normalC; + const dReal *normalR = 0; + dReal hlz1,hlz2,s,s2; + int i,invert_normal; + + // 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 (pp1,R1,p); // get pp1 = p relative to body 1 + dMULTIPLY1_331 (pp2,R2,p); + // get side lengths / 2 + hlz1 = lz1*REAL(0.5); + hlz2 = lz2*REAL(0.5); + + dReal proj,cos,sin,cos1,cos3; + + + +#define TEST(expr1,expr2,norm,cc) \ + s2 = dFabs(expr1) - (expr2); \ + if (s2 > 0) return 0; \ + if (s2 > s) { \ + s = s2; \ + normalR = norm; \ + invert_normal = ((expr1) < 0); \ + *code = (cc); \ + } + + s = -dInfinity; + invert_normal = 0; + *code = 0; + + cos=dFabs(dDOT44(R1+1,R2+1)); + sin=sqrtf(1.f-(cos>1.f ? 1.f : cos)); + + TEST (pp1[1],(hlz1 + radius2*sin + hlz2*cos ),R1+1,0);//pp + + TEST (pp2[1],(radius1*sin + hlz1*cos + hlz2),R2+1,1); + + + + // note: cross product axes need to be scaled when s is computed. + +#undef TEST +#define TEST(expr1,expr2,n1,n2,n3,cc) \ + s2 = dFabs(expr1) - (expr2); \ + if (s2 > 0) return 0; \ + if (s2 > s) { \ + s = s2; \ + normalR = 0; \ + normalC[0] = (n1); normalC[1] = (n2); normalC[2] = (n3); \ + invert_normal = ((expr1) < 0); \ + *code = (cc); \ + } + + +dVector3 tAx,Ax,pa,pb; + +//cross between cylinders' axes +dCROSS144(Ax,=,R1+1,R2+1); +dNormalize3(Ax); +TEST(p[0]*Ax[0]+p[1]*Ax[1]+p[2]*Ax[2],radius1+radius2,Ax[0],Ax[1],Ax[2],6); + + +{ + + dReal sign, factor; + + //making ax which is perpendicular to cyl1 ax passing across cyl2 position// + //(project p on cyl1 flat surface ) + for (i=0; i<3; i++) pb[i] = p2[i]; + //cos1 = dDOT14(p,R1+0); + //cos3 = dDOT14(p,R1+2) ; + tAx[0]=pp1[0]*R1[0]+pp1[2]*R1[2]; + tAx[1]=pp1[0]*R1[4]+pp1[2]*R1[6]; + tAx[2]=pp1[0]*R1[8]+pp1[2]*R1[10]; + dNormalize3(tAx); + +//find deepest point pb of cyl2 on opposite direction of tAx + cos1 = dDOT14(tAx,R2+0); + cos3 = dDOT14(tAx,R2+2) ; + factor=sqrtf(cos1*cos1+cos3*cos3); + cos1/=factor; + cos3/=factor; + for (i=0; i<3; i++) pb[i] -= cos1 * radius2 * R2[i*4]; + + sign = (dDOT14(tAx,R2+1) > 0) ? REAL(1.0) : REAL(-1.0); + for (i=0; i<3; i++) pb[i] -= sign * hlz2 * R2[i*4+1]; + + for (i=0; i<3; i++) pb[i] -= cos3 * radius2 * R2[i*4+2]; + +//making perpendicular to cyl1 ax passing across pb + proj=dDOT14(pb,R1+1)-dDOT14(p1,R1+1); + + Ax[0]=pb[0]-p1[0]-R1[1]*proj; + Ax[1]=pb[1]-p1[1]-R1[5]*proj; + Ax[2]=pb[2]-p1[2]-R1[9]*proj; + +} + +dNormalize3(Ax); + + + cos=dFabs(dDOT14(Ax,R2+1)); + cos1=dDOT14(Ax,R2+0); + cos3=dDOT14(Ax,R2+2); + sin=sqrtf(cos1*cos1+cos3*cos3); + +TEST(p[0]*Ax[0]+p[1]*Ax[1]+p[2]*Ax[2],radius1+cos*hlz2+sin*radius2,Ax[0],Ax[1],Ax[2],3); + + + +{ + + dReal sign, factor; + + for (i=0; i<3; i++) pa[i] = p1[i]; + + //making ax which is perpendicular to cyl2 ax passing across cyl1 position// + //(project p on cyl2 flat surface ) + //cos1 = dDOT14(p,R2+0); + //cos3 = dDOT14(p,R2+2) ; + tAx[0]=pp2[0]*R2[0]+pp2[2]*R2[2]; + tAx[1]=pp2[0]*R2[4]+pp2[2]*R2[6]; + tAx[2]=pp2[0]*R2[8]+pp2[2]*R2[10]; + dNormalize3(tAx); + + cos1 = dDOT14(tAx,R1+0); + cos3 = dDOT14(tAx,R1+2) ; + factor=sqrtf(cos1*cos1+cos3*cos3); + cos1/=factor; + cos3/=factor; + +//find deepest point pa of cyl2 on direction of tAx + for (i=0; i<3; i++) pa[i] += cos1 * radius1 * R1[i*4]; + + sign = (dDOT14(tAx,R1+1) > 0) ? REAL(1.0) : REAL(-1.0); + for (i=0; i<3; i++) pa[i] += sign * hlz1 * R1[i*4+1]; + + + for (i=0; i<3; i++) pa[i] += cos3 * radius1 * R1[i*4+2]; + + proj=dDOT14(pa,R2+1)-dDOT14(p2,R2+1); + + Ax[0]=pa[0]-p2[0]-R2[1]*proj; + Ax[1]=pa[1]-p2[1]-R2[5]*proj; + Ax[2]=pa[2]-p2[2]-R2[9]*proj; + +} +dNormalize3(Ax); + + + + cos=dFabs(dDOT14(Ax,R1+1)); + cos1=dDOT14(Ax,R1+0); + cos3=dDOT14(Ax,R1+2); + sin=sqrtf(cos1*cos1+cos3*cos3); + +TEST(p[0]*Ax[0]+p[1]*Ax[1]+p[2]*Ax[2],radius2+cos*hlz1+sin*radius1,Ax[0],Ax[1],Ax[2],4); + + +////test circl + +//@ this needed to set right normal when cylinders edges intersect +//@ the most precise axis for this test may be found as a line between nearest points of two +//@ circles. But it needs comparatively a lot of computation. +//@ I use a trick which lets not to solve quadric equation. +//@ In the case when cylinder eidges touches the test below rather accurate. +//@ I still not sure about problems with sepparation but they have not been revealed during testing. +dVector3 point; +{ + dVector3 ca,cb; + dReal sign; + for (i=0; i<3; i++) ca[i] = p1[i]; + for (i=0; i<3; i++) cb[i] = p2[i]; +//find two nearest flat rings + sign = (pp1[1] > 0) ? REAL(1.0) : REAL(-1.0); + for (i=0; i<3; i++) ca[i] += sign * hlz1 * R1[i*4+1]; + + sign = (pp2[1] > 0) ? REAL(1.0) : REAL(-1.0); + for (i=0; i<3; i++) cb[i] -= sign * hlz2 * R2[i*4+1]; + + dVector3 tAx,tAx1; + circleIntersection(R1+1,ca,radius1,R2+1,cb,radius2,point); + + Ax[0]=point[0]-ca[0]; + Ax[1]=point[1]-ca[1]; + Ax[2]=point[2]-ca[2]; + + cos1 = dDOT14(Ax,R1+0); + cos3 = dDOT14(Ax,R1+2) ; + + tAx[0]=cos3*R1[0]-cos1*R1[2]; + tAx[1]=cos3*R1[4]-cos1*R1[6]; + tAx[2]=cos3*R1[8]-cos1*R1[10]; + + Ax[0]=point[0]-cb[0]; + Ax[1]=point[1]-cb[1]; + Ax[2]=point[2]-cb[2]; + + + cos1 = dDOT14(Ax,R2+0); + cos3 = dDOT14(Ax,R2+2) ; + + tAx1[0]=cos3*R2[0]-cos1*R2[2]; + tAx1[1]=cos3*R2[4]-cos1*R2[6]; + tAx1[2]=cos3*R2[8]-cos1*R2[10]; + dCROSS(Ax,=,tAx,tAx1); + + + + +dNormalize3(Ax); +dReal cyl1Pr,cyl2Pr; + + cos=dFabs(dDOT14(Ax,R1+1)); + cos1=dDOT14(Ax,R1+0); + cos3=dDOT14(Ax,R1+2); + sin=sqrtf(cos1*cos1+cos3*cos3); + cyl1Pr=cos*hlz1+sin*radius1; + + cos=dFabs(dDOT14(Ax,R2+1)); + cos1=dDOT14(Ax,R2+0); + cos3=dDOT14(Ax,R2+2); + sin=sqrtf(cos1*cos1+cos3*cos3); + cyl2Pr=cos*hlz2+sin*radius2; +TEST(p[0]*Ax[0]+p[1]*Ax[1]+p[2]*Ax[2],cyl1Pr+cyl2Pr,Ax[0],Ax[1],Ax[2],5); + + +} + + +#undef TEST + + + + // if we get to this point, the cylinders interpenetrate. compute the normal + // in global coordinates. + if (normalR) { + normal[0] = normalR[0]; + normal[1] = normalR[4]; + normal[2] = normalR[8]; + } + else { + normal[0] =normalC[0];normal[1] = normalC[1];normal[2] = normalC[2]; + } + if (invert_normal) { + normal[0] = -normal[0]; + normal[1] = -normal[1]; + normal[2] = -normal[2]; + } + + *depth = -s; + + // compute contact point(s) + + if(*code==3){ + for (i=0; i<3; i++) contact[0].pos[i] = pb[i]; + contact[0].depth = *depth; + return 1; + } + + if(*code==4){ + for (i=0; i<3; i++) contact[0].pos[i] = pa[i]; + contact[0].depth = *depth; + return 1; + } + + if(*code==5){ + for (i=0; i<3; i++) contact[0].pos[i] = point[i]; + contact[0].depth = *depth; + return 1; + } + +if (*code == 6) { + dVector3 pa; + dReal sign, cos1,cos3,factor; + + + for (i=0; i<3; i++) pa[i] = p1[i]; + + cos1 = dDOT14(normal,R1+0); + cos3 = dDOT14(normal,R1+2) ; + factor=sqrtf(cos1*cos1+cos3*cos3); + + cos1/=factor; + cos3/=factor; + + for (i=0; i<3; i++) pa[i] += cos1 * radius1 * R1[i*4]; + + sign = (dDOT14(normal,R1+1) > 0) ? REAL(1.0) : REAL(-1.0); + for (i=0; i<3; i++) pa[i] += sign * hlz1 * R1[i*4+1]; + + + for (i=0; i<3; i++) pa[i] += cos3 * radius1 * R1[i*4+2]; + + // find a point pb on the intersecting edge of cylinder 2 + dVector3 pb; + for (i=0; i<3; i++) pb[i] = p2[i]; + cos1 = dDOT14(normal,R2+0); + cos3 = dDOT14(normal,R2+2) ; + factor=sqrtf(cos1*cos1+cos3*cos3); + + cos1/=factor; + cos3/=factor; + + for (i=0; i<3; i++) pb[i] -= cos1 * radius2 * R2[i*4]; + + sign = (dDOT14(normal,R2+1) > 0) ? REAL(1.0) : REAL(-1.0); + for (i=0; i<3; i++) pb[i] -= sign * hlz2 * R2[i*4+1]; + + + for (i=0; i<3; i++) pb[i] -= cos3 * radius2 * R2[i*4+2]; + + + dReal alpha,beta; + dVector3 ua,ub; + for (i=0; i<3; i++) ua[i] = R1[1 + i*4]; + for (i=0; i<3; i++) ub[i] = R2[1 + i*4]; + lineClosestApproach (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; + + for (i=0; i<3; i++) contact[0].pos[i] = REAL(0.5)*(pa[i]+pb[i]); + contact[0].depth = *depth; + return 1; + } + + // okay, we have a face-something intersection (because the separating + // axis is perpendicular to a face). + + // @@@ temporary: make deepest point on the "other" cylinder the contact point. + // @@@ this kind of works, but we need multiple contact points for stability, + // @@@ especially for face-face contact. + + dVector3 vertex; + if (*code == 0) { + // flat face from cylinder 1 touches a edge/face from cylinder 2. + dReal sign,cos1,cos3,factor; + for (i=0; i<3; i++) vertex[i] = p2[i]; + cos1 = dDOT14(normal,R2+0) ; + cos3 = dDOT14(normal,R2+2); + factor=sqrtf(cos1*cos1+cos3*cos3); + + cos1/=factor; + cos3/=factor; + for (i=0; i<3; i++) vertex[i] -= cos1 * radius2 * R2[i*4]; + + sign = (dDOT14(normal,R1+1) > 0) ? REAL(1.0) : REAL(-1.0); + for (i=0; i<3; i++) vertex[i] -= sign * hlz2 * R2[i*4+1]; + + for (i=0; i<3; i++) vertex[i] -= cos3 * radius2 * R2[i*4+2]; + } + else { + // flat face from cylinder 2 touches a edge/face from cylinder 1. + dReal sign,cos1,cos3,factor; + for (i=0; i<3; i++) vertex[i] = p1[i]; + cos1 = dDOT14(normal,R1+0) ; + cos3 = dDOT14(normal,R1+2); + factor=sqrtf(cos1*cos1+cos3*cos3); + + cos1/=factor; + cos3/=factor; + for (i=0; i<3; i++) vertex[i] += cos1 * radius1 * R1[i*4]; + + sign = (dDOT14(normal,R1+1) > 0) ? REAL(1.0) : REAL(-1.0); + for (i=0; i<3; i++) vertex[i] += sign * hlz1 * R1[i*4+1]; + + for (i=0; i<3; i++) vertex[i] += cos3 * radius1 * R1[i*4+2]; + } + for (i=0; i<3; i++) contact[0].pos[i] = vertex[i]; + contact[0].depth = *depth; + return 1; +} + +//**************************************************************************** + + +int dCollideCylS (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip) +{ + + + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (dGeomGetClass(o2) == dSphereClass); + dIASSERT (dGeomGetClass(o1) == dCylinderClassUser); + const dReal* p1=dGeomGetPosition(o1); + const dReal* p2=dGeomGetPosition(o2); + const dReal* R=dGeomGetRotation(o1); + dVector3 p,normalC,normal; + const dReal *normalR = 0; + dReal cylRadius; + dReal hl; + dGeomCylinderGetParams(o1,&cylRadius,&hl); + dReal sphereRadius; + sphereRadius=dGeomSphereGetRadius(o2); + + int i,invert_normal; + + // get vector from centers of cyl to shere + p[0] = p2[0] - p1[0]; + p[1] = p2[1] - p1[1]; + p[2] = p2[2] - p1[2]; + +dReal s,s2; +unsigned char code; +#define TEST(expr1,expr2,norm,cc) \ + s2 = dFabs(expr1) - (expr2); \ + if (s2 > 0) return 0; \ + if (s2 > s) { \ + s = s2; \ + normalR = norm; \ + invert_normal = ((expr1) < 0); \ + code = (cc); \ + } + + s = -dInfinity; + invert_normal = 0; + code = 0; + + // separating axis cyl ax + + TEST (dDOT14(p,R+1),sphereRadius+hl,R+1,2); + // note: cross product axes need to be scaled when s is computed. + // normal (n1,n2,n3) is relative to +#undef TEST +#define TEST(expr1,expr2,n1,n2,n3,cc) \ + s2 = dFabs(expr1) - (expr2); \ + if (s2 > 0) return 0; \ + if (s2 > s) { \ + s = s2; \ + normalR = 0; \ + normalC[0] = (n1); normalC[1] = (n2); normalC[2] = (n3); \ + invert_normal = ((expr1) < 0); \ + code = (cc); \ + } + +//making ax which is perpendicular to cyl1 ax to sphere center// + +dReal proj,cos,sin,cos1,cos3; +dVector3 Ax; + proj=dDOT14(p2,R+1)-dDOT14(p1,R+1); + + Ax[0]=p2[0]-p1[0]-R[1]*proj; + Ax[1]=p2[1]-p1[1]-R[5]*proj; + Ax[2]=p2[2]-p1[2]-R[9]*proj; +dNormalize3(Ax); +TEST(dDOT(p,Ax),sphereRadius+cylRadius,Ax[0],Ax[1],Ax[2],9); + + +Ax[0]=p[0]; +Ax[1]=p[1]; +Ax[2]=p[2]; +dNormalize3(Ax); + + dVector3 pa; + dReal sign, factor; + for (i=0; i<3; i++) pa[i] = p1[i]; + + cos1 = dDOT14(Ax,R+0); + cos3 = dDOT14(Ax,R+2) ; + factor=sqrtf(cos1*cos1+cos3*cos3); + cos1/=factor; + cos3/=factor; + for (i=0; i<3; i++) pa[i] += cos1 * cylRadius * R[i*4]; + sign = (dDOT14(normal,R+1) > 0) ? REAL(1.0) : REAL(-1.0); + for (i=0; i<3; i++) pa[i] += sign * hl * R[i*4+1]; + for (i=0; i<3; i++) pa[i] += cos3 * cylRadius * R[i*4+2]; + +Ax[0]=p2[0]-pa[0]; +Ax[1]=p2[1]-pa[1]; +Ax[2]=p2[2]-pa[2]; +dNormalize3(Ax); + + cos=dFabs(dDOT14(Ax,R+1)); + cos1=dDOT14(Ax,R+0); + cos3=dDOT14(Ax,R+2); + sin=sqrtf(cos1*cos1+cos3*cos3); +TEST(dDOT(p,Ax),sphereRadius+cylRadius*sin+hl*cos,Ax[0],Ax[1],Ax[2],14); + + +#undef TEST + + if (normalR) { + normal[0] = normalR[0]; + normal[1] = normalR[4]; + normal[2] = normalR[8]; + } + else { + + normal[0] = normalC[0]; + normal[1] = normalC[1]; + normal[2] = normalC[2]; + } + if (invert_normal) { + normal[0] = -normal[0]; + normal[1] = -normal[1]; + normal[2] = -normal[2]; + } + // compute contact point(s) +contact->depth=-s; +contact->normal[0]=-normal[0]; +contact->normal[1]=-normal[1]; +contact->normal[2]=-normal[2]; +contact->g1=const_cast (o1); +contact->g2=const_cast (o2); +contact->pos[0]=p2[0]-normal[0]*sphereRadius; +contact->pos[1]=p2[1]-normal[1]*sphereRadius; +contact->pos[2]=p2[2]-normal[2]*sphereRadius; +return 1; +} + + + +int dCollideCylB (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip) +{ + dVector3 normal; + dReal depth; + int code; + dReal cylRadius,cylLength; + dVector3 boxSides; + dGeomCylinderGetParams(o1,&cylRadius,&cylLength); + dGeomBoxGetLengths(o2,boxSides); + int num = dCylBox(dGeomGetPosition(o1),dGeomGetRotation(o1),cylRadius,cylLength, + dGeomGetPosition(o2),dGeomGetRotation(o2),boxSides, + normal,&depth,&code,flags & NUMC_MASK,contact,skip); + for (int i=0; inormal[0] = -normal[0]; + CONTACT(contact,i*skip)->normal[1] = -normal[1]; + CONTACT(contact,i*skip)->normal[2] = -normal[2]; + CONTACT(contact,i*skip)->g1 = const_cast (o1); + CONTACT(contact,i*skip)->g2 = const_cast (o2); + } + return num; +} + +int dCollideCylCyl (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip) +{ + dVector3 normal; + dReal depth; + int code; +dReal cylRadius1,cylRadius2; +dReal cylLength1,cylLength2; +dGeomCylinderGetParams(o1,&cylRadius1,&cylLength1); +dGeomCylinderGetParams(o2,&cylRadius2,&cylLength2); +int num = dCylCyl (dGeomGetPosition(o1),dGeomGetRotation(o1),cylRadius1,cylLength1, + dGeomGetPosition(o2),dGeomGetRotation(o2),cylRadius2,cylLength2, + normal,&depth,&code,flags & NUMC_MASK,contact,skip); + + for (int i=0; inormal[0] = -normal[0]; + CONTACT(contact,i*skip)->normal[1] = -normal[1]; + CONTACT(contact,i*skip)->normal[2] = -normal[2]; + CONTACT(contact,i*skip)->g1 = const_cast (o1); + CONTACT(contact,i*skip)->g2 = const_cast (o2); + } + return num; +} + +struct dxPlane { + dReal p[4]; +}; + + +int dCollideCylPlane + ( + dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip){ + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (dGeomGetClass(o1) == dCylinderClassUser); + dIASSERT (dGeomGetClass(o2) == dPlaneClass); + contact->g1 = const_cast (o1); + contact->g2 = const_cast (o2); + + unsigned int ret = 0; + + dReal radius; + dReal hlz; + dGeomCylinderGetParams(o1,&radius,&hlz); + hlz /= 2; + + const dReal *R = dGeomGetRotation(o1);// rotation of cylinder + const dReal* p = dGeomGetPosition(o1); + dVector4 n; // normal vector + dReal pp; + dGeomPlaneGetParams (o2, n); + pp=n[3]; + dReal cos1,sin1; + cos1=dFabs(dDOT14(n,R+1)); + +cos1=cos10 ? hlz*R[1]:-hlz*R[1]; + pos[1]-= A2>0 ? hlz*R[5]:-hlz*R[5]; + pos[2]-= A2>0 ? hlz*R[9]:-hlz*R[9]; + + + + contact->pos[0] = pos[0]; + contact->pos[1] = pos[1]; + contact->pos[2] = pos[2]; + contact->depth = outDepth; + ret=1; + +if(dFabs(Q2)>M_SQRT1_2){ + + CONTACT(contact,ret*skip)->pos[0]=pos[0]+2.f*A1*R[0]; + CONTACT(contact,ret*skip)->pos[1]=pos[1]+2.f*A1*R[4]; + CONTACT(contact,ret*skip)->pos[2]=pos[2]+2.f*A1*R[8]; + CONTACT(contact,ret*skip)->depth=outDepth-dFabs(Q1*2.f*A1); + + if(CONTACT(contact,ret*skip)->depth>0.f) + ret++; + + + CONTACT(contact,ret*skip)->pos[0]=pos[0]+2.f*A3*R[2]; + CONTACT(contact,ret*skip)->pos[1]=pos[1]+2.f*A3*R[6]; + CONTACT(contact,ret*skip)->pos[2]=pos[2]+2.f*A3*R[10]; + CONTACT(contact,ret*skip)->depth=outDepth-dFabs(Q3*2.f*A3); + + if(CONTACT(contact,ret*skip)->depth>0.f) ret++; +} else { + + CONTACT(contact,ret*skip)->pos[0]=pos[0]+2.f*(A2>0 ? hlz*R[1]:-hlz*R[1]); + CONTACT(contact,ret*skip)->pos[1]=pos[1]+2.f*(A2>0 ? hlz*R[5]:-hlz*R[5]); + CONTACT(contact,ret*skip)->pos[2]=pos[2]+2.f*(A2>0 ? hlz*R[9]:-hlz*R[9]); + CONTACT(contact,ret*skip)->depth=outDepth-dFabs(Q2*2.f*A2); + + if(CONTACT(contact,ret*skip)->depth>0.f) ret++; +} + + + + for (unsigned int i=0; ig1 = const_cast (o1); + CONTACT(contact,i*skip)->g2 = const_cast (o2); + CONTACT(contact,i*skip)->normal[0] =n[0]; + CONTACT(contact,i*skip)->normal[1] =n[1]; + CONTACT(contact,i*skip)->normal[2] =n[2]; + } + return ret; +} + +int dCollideCylRay(dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip) { + dIASSERT (skip >= (int)sizeof(dContactGeom)); + dIASSERT (dGeomGetClass(o1) == dCylinderClassUser); + dIASSERT (dGeomGetClass(o2) == dRayClass); + contact->g1 = const_cast (o1); + contact->g2 = const_cast (o2); + dReal radius; + dReal lz; + dGeomCylinderGetParams(o1,&radius,&lz); + dReal lz2=lz*REAL(0.5); + const dReal *R = dGeomGetRotation(o1); // rotation of the cylinder + const dReal *p = dGeomGetPosition(o1); // position of the cylinder + dVector3 start,dir; + dGeomRayGet(o2,start,dir); // position and orientation of the ray + dReal length = dGeomRayGetLength(o2); + + // compute some useful info + dVector3 cs,q,r; + dReal C,k; + cs[0] = start[0] - p[0]; + cs[1] = start[1] - p[1]; + cs[2] = start[2] - p[2]; + k = dDOT41(R+1,cs); // position of ray start along cyl axis (Y) + q[0] = k*R[0*4+1] - cs[0]; + q[1] = k*R[1*4+1] - cs[1]; + q[2] = k*R[2*4+1] - cs[2]; + C = dDOT(q,q) - radius*radius; + // if C < 0 then ray start position within infinite extension of cylinder + // if ray start position is inside the cylinder + int inside_cyl=0; + if (C<0 && !(k<-lz2 || k>lz2)) inside_cyl=1; + // compute ray collision with infinite cylinder, except for the case where + // the ray is outside the cylinder but within the infinite cylinder + // (it that case the ray can only hit endcaps) + if (!inside_cyl && C < 0) { + // set k to cap position to check + if (k < 0) k = -lz2; else k = lz2; + } + else { + dReal uv = dDOT41(R+1,dir); + r[0] = uv*R[0*4+1] - dir[0]; + r[1] = uv*R[1*4+1] - dir[1]; + r[2] = uv*R[2*4+1] - dir[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_cyl) 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>length) return 0; + // the ray intersects the infinite cylinder. check to see if the + // intersection point is between the caps + contact->pos[0] = start[0] + alpha*dir[0]; + contact->pos[1] = start[1] + alpha*dir[1]; + contact->pos[2] = start[2] + alpha*dir[2]; + q[0] = contact->pos[0] - p[0]; + q[1] = contact->pos[1] - p[1]; + q[2] = contact->pos[2] - p[2]; + k = dDOT14(q,R+1); + dReal nsign = inside_cyl ? -1 : 1; + if (k >= -lz2 && k <= lz2) { + contact->normal[0] = nsign * (contact->pos[0] - + (p[0] + k*R[0*4+1])); + contact->normal[1] = nsign * (contact->pos[1] - + (p[1] + k*R[1*4+1])); + contact->normal[2] = nsign * (contact->pos[2] - + (p[2] + k*R[2*4+1])); + 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 + // perform a ray plan interesection + // R+1 is the plan normal + q[0] = start[0] - (p[0] + k*R[0*4+1]); + q[1] = start[1] - (p[1] + k*R[1*4+1]); + q[2] = start[2] - (p[2] + k*R[2*4+1]); + dReal alpha = -dDOT14(q,R+1); + dReal k2 = dDOT14(dir,R+1); + if (k2==0) return 0; // ray parallel to the plane + alpha/=k2; + if (alpha<0 || alpha>length) return 0; // too short + contact->pos[0]=start[0]+alpha*dir[0]; + contact->pos[1]=start[1]+alpha*dir[1]; + contact->pos[2]=start[2]+alpha*dir[2]; + dReal nsign = (k<0)?-1:1; + contact->normal[0]=nsign*R[0*4+1]; + contact->normal[1]=nsign*R[1*4+1]; + contact->normal[2]=nsign*R[2*4+1]; + contact->depth=alpha; + return 1; +} + +static dColliderFn * dCylinderColliderFn (int num) +{ + if (num == dBoxClass) return (dColliderFn *) &dCollideCylB; + else if (num == dSphereClass) return (dColliderFn *) &dCollideCylS; + else if (num == dCylinderClassUser) return (dColliderFn *) &dCollideCylCyl; + else if (num == dPlaneClass) return (dColliderFn *) &dCollideCylPlane; + else if (num == dRayClass) return (dColliderFn *) &dCollideCylRay; + return 0; +} + + +static void dCylinderAABB (dxGeom *geom, dReal aabb[6]) +{ + dReal radius,lz; + dGeomCylinderGetParams(geom,&radius,&lz); +const dReal* R= dGeomGetRotation(geom); +const dReal* pos= dGeomGetPosition(geom); + dReal xrange = dFabs (R[0] *radius) + + REAL(0.5) *dFabs (R[1] * lz) + dFabs (R[2] * radius); + + dReal yrange = dFabs (R[4] *radius) + + REAL(0.5) * dFabs (R[5] * lz) + dFabs (R[6] * radius); + + dReal zrange = dFabs (R[8] * radius) + + REAL(0.5) *dFabs (R[9] * lz) + dFabs (R[10] * 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; +} + +dxGeom *dCreateCylinder (dSpaceID space, dReal r, dReal lz) +{ + dAASSERT (r > 0 && lz > 0); + if (dCylinderClassUser == -1) + { + dGeomClass c; + c.bytes = sizeof (dxCylinder); + c.collider = &dCylinderColliderFn; + c.aabb = &dCylinderAABB; + c.aabb_test = 0; + c.dtor = 0; + dCylinderClassUser=dCreateGeomClass (&c); + + } + + dGeomID g = dCreateGeom (dCylinderClassUser); + if (space) dSpaceAdd (space,g); + dxCylinder *c = (dxCylinder*) dGeomGetClassData(g); + + c->radius = r; + c->lz = lz; + return g; +} + + + +void dGeomCylinderSetParams (dGeomID g, dReal radius, dReal length) +{ + dUASSERT (g && dGeomGetClass(g) == dCylinderClassUser,"argument not a cylinder"); + dAASSERT (radius > 0 && length > 0); + dxCylinder *c = (dxCylinder*) dGeomGetClassData(g); + c->radius = radius; + c->lz = length; +} + + + +void dGeomCylinderGetParams (dGeomID g, dReal *radius, dReal *length) +{ + dUASSERT (g && dGeomGetClass(g) == dCylinderClassUser ,"argument not a cylinder"); + dxCylinder *c = (dxCylinder*) dGeomGetClassData(g); + *radius = c->radius; + *length = c->lz; +} + +/* +void dMassSetCylinder (dMass *m, dReal density, + dReal radius, dReal length) +{ + dAASSERT (m); + dMassSetZero (m); + dReal M = length*M_PI*radius*radius*density; + m->mass = M; + m->_I(0,0) = M/REAL(4.0) * (ly*ly + lz*lz); + m->_I(1,1) = M/REAL(12.0) * (lx*lx + lz*lz); + m->_I(2,2) = M/REAL(4.0) * (lx*lx + ly*ly); + +# ifndef dNODEBUG + checkMass (m); +# endif +} +*/ diff --git a/libraries/ode-0.9/contrib/dCylinder/dCylinder.h b/libraries/ode-0.9/contrib/dCylinder/dCylinder.h new file mode 100644 index 0000000000..06e3a0b564 --- /dev/null +++ b/libraries/ode-0.9/contrib/dCylinder/dCylinder.h @@ -0,0 +1,14 @@ + +#ifndef dCylinder_h +#define dCylinder_h + +struct dxCylinder; +extern int dCylinderClassUser; + + +dxGeom *dCreateCylinder (dSpaceID space, dReal r, dReal lz); +void dGeomCylinderSetParams (dGeomID g, dReal radius, dReal length); + +void dGeomCylinderGetParams (dGeomID g, dReal *radius, dReal *length); +#endif //dCylinder_h + diff --git a/libraries/ode-0.9/contrib/dCylinder/readme.txt b/libraries/ode-0.9/contrib/dCylinder/readme.txt new file mode 100644 index 0000000000..facd13ed78 --- /dev/null +++ b/libraries/ode-0.9/contrib/dCylinder/readme.txt @@ -0,0 +1,62 @@ +readme.txt + +WARNING: THIS IS NOT VERY RELIABLE CODE. IT HAS BUGS. YOUR + SUCCESS MAY VARY. CONTRIBUTIONS OF FIXES/REWRITES ARE + WELCOME. + +/////////////////////////////////////////////////////////////////////// + +Cylinder geometry class. + +New in this version: + +Cylinder class implemented as User Geometry Class so it now can be +used with old and new ODE collision detection. + +Cylinder - Ray has been contributed by Olivier Michel. + +THE IDENTIFIER dCylinderClass HAS BEEN REPLACED BY dCylinderClassUser + +to avoid conflict with dCylinderClass in the enum definite in collision.h + +/////////////////////////////////////////////////////////////////////// +The dCylinder class includes the following collisions: + +Cylinder - Box +Cylinder - Cylinder +Cylinder - Sphere +Cylinder - Plane +Cylinder - Ray (contributed by Olivier Michel) + +Cylinder aligned along axis - Y when created. (Not like Capped +Cylinder which aligned along axis - Z). + +Interface is just the same as Capped Cylinder has. + +Use functions which have one "C" instead of double "C". + +to create: +dGeomID dCreateCylinder (dSpaceID space, dReal radius, dReal length); + +to set params: +void dGeomCylinderSetParams (dGeomID cylinder, + dReal radius, dReal length); + + +to get params: +void dGeomCylinderGetParams (dGeomID cylinder, + dReal *radius, dReal *length); + +Return in radius and length the parameters of the given cylinder. + +Identification number of the class: + dCylinderClassUser + + I do not include a function that sets inertia tensor for cylinder. + One may use existing ODE functions dMassSetCappedCylinder or dMassSetBox. + To set exact tensor for cylinder use dMassSetParameters. + Remember cylinder aligned along axis - Y. + + /////////////////////////////////////////////////////////////////////////// + Konstantin Slipchenko + February 5, 2002 diff --git a/libraries/ode-0.9/contrib/dRay/Include/dRay.h b/libraries/ode-0.9/contrib/dRay/Include/dRay.h new file mode 100644 index 0000000000..f6caea8542 --- /dev/null +++ b/libraries/ode-0.9/contrib/dRay/Include/dRay.h @@ -0,0 +1,15 @@ +#include "ode\ode.h" + +/* Class ID */ +extern int dRayClass; + +/* Creates a ray */ +dxGeom* dGeomCreateRay(dSpaceID space, dReal Length); + +/* Set/Get length */ +void dGeomRaySetLength(dxGeom* g, dReal Length); +dReal dGeomRayGetLength(dxGeom* g); + +/* Utility function to override the ray's pos + rot */ +void dGeomRaySet(dxGeom* g, dVector3 Origin, dVector3 Direction); +void dGeomRayGet(dxGeom* g, dVector3 Origin, dVector3 Direction); diff --git a/libraries/ode-0.9/contrib/dRay/README.txt b/libraries/ode-0.9/contrib/dRay/README.txt new file mode 100644 index 0000000000..899720823e --- /dev/null +++ b/libraries/ode-0.9/contrib/dRay/README.txt @@ -0,0 +1,16 @@ +From: "Erwin de Vries" +To: +Subject: [ODE] dRay class +Date: Thu, 25 Jul 2002 13:05:28 +0200 + +Yesterday and today i've written a dRay class. It interacts with dPlane, +dSphere, dBox and dCCylinder. It does not generate full contact information. +It only generates the pos member. I dont think its useful to anyone to go +through hoops and find a reasonable normal and penetration depth, as i dont +think anyone will want to use it for dynamics. Just for CD. + +It should compile in single and double precision mode, and should be +platform independant. I hope. + +The next Tri-Collider release using Opcode 1.1 will also implement a ray +collision function along with some other not too interesting improvements. diff --git a/libraries/ode-0.9/contrib/dRay/Test/test_ray.cpp b/libraries/ode-0.9/contrib/dRay/Test/test_ray.cpp new file mode 100644 index 0000000000..faa8b14b8b --- /dev/null +++ b/libraries/ode-0.9/contrib/dRay/Test/test_ray.cpp @@ -0,0 +1,1372 @@ +/************************************************************************* + + + * * + + + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + + + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + + + * * + + + * This library is free software; you can redistribute it and/or * + + + * modify it under the terms of EITHER: * + + + * (1) The GNU Lesser General Public License as published by the Free * + + + * Software Foundation; either version 2.1 of the License, or (at * + + + * your option) any later version. The text of the GNU Lesser * + + + * General Public License is included with this library in the * + + + * file LICENSE.TXT. * + + + * (2) The BSD-style license that is included with this library in * + + + * the file LICENSE-BSD.TXT. * + + + * * + + + * This library is distributed in the hope that it will be useful, * + + + * but WITHOUT ANY WARRANTY; without 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 + + + + + +#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 dsDrawCappedCylinder dsDrawCappedCylinderD + + +#endif + + + + + + + + +// some constants + + + + + +#define NUM 20 // max number of objects + + +#define DENSITY (5.0) // density of all objects + + +#define GPB 3 // maximum number of geometries 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 dGeomID* Rays; + + +static int RayCount; + + + + + +// 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 && dAreConnected (b1,b2)) return; + + + + + + dContact contact[32]; // up to 3 contacts per box + + + for (i=0; i<32; i++) { + + + contact[i].surface.mode = dContactBounce; //dContactMu2; + + + contact[i].surface.mu = dInfinity; + + + contact[i].surface.mu2 = 0; + + + contact[i].surface.bounce = 0.5; + + + contact[i].surface.bounce_vel = 0.1; + + + } + + + if (int numc = dCollide (o1,o2,3,&contact[0].geom,sizeof(dContact))) { + + + dMatrix3 RI; + + + dRSetIdentity (RI); + + + const dReal ss[3] = {0.02,0.02,0.02}; + + + 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') { + + + 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; + + + + + + dBodySetPosition (obj[i].body, + + + dRandReal()*2-1,dRandReal()*2-1,dRandReal()+1); + + + dMatrix3 R; + + + dRFromAxisAndAngle (R,dRandReal()*2.0-1.0,dRandReal()*2.0-1.0, + + + dRandReal()*2.0-1.0,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; + + + dMassSetCappedCylinder (&m,DENSITY,3,sides[0],sides[1]); + + + obj[i].geom[0] = dCreateCCylinder (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); + + + } + + +} + + + + + + + + +// draw a geom + + + + + +void drawGeom (dGeomID g, const dReal *pos, const dReal *R) + + +{ + + + 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 == dCCylinderClass) { + + + dReal radius,length; + + + dGeomCCylinderGetParams (g,&radius,&length); + + + dsDrawCappedCylinder (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); + + + } + + +} + + + + + + + + +// simulation loop + + + + + +static void simLoop (int pause) + + +{ + + + dsSetColor (0,0,2); + + + dSpaceCollide (space,0,&nearCallback); + + + if (!pause) dWorldStep (world,0.05); + + + + + + // remove all contact joints + + + dJointGroupEmpty (contactgroup); + + + + + + dsSetColor (1,1,0); + + + dsSetTexture (DS_WOOD); + + + for (int i=0; iLength = Length; +} + +dReal dGeomRayGetLength(dxGeom* g){ + return ((dxRay*)dGeomGetClassData(g))->Length; +} + +void dGeomRaySet(dxGeom* g, dVector3 Origin, dVector3 Direction){ + dGeomSetPosition(g, Origin[0], Origin[1], Origin[2]); + + dVector3 Up, Right; + dPlaneSpace(Direction, Up, Right); + + Origin[3] = Up[3] = Right[3] = REAL(0.0); + + dMatrix3 Rotation; + Rotation[0 * 4 + 0] = Right[0]; + Rotation[1 * 4 + 0] = Right[1]; + Rotation[2 * 4 + 0] = Right[2]; + Rotation[3 * 4 + 0] = Right[3]; + + Rotation[0 * 4 + 1] = Up[0]; + Rotation[1 * 4 + 1] = Up[1]; + Rotation[2 * 4 + 1] = Up[2]; + Rotation[3 * 4 + 1] = Up[3]; + + Rotation[0 * 4 + 2] = Direction[0]; + Rotation[1 * 4 + 2] = Direction[1]; + Rotation[2 * 4 + 2] = Direction[2]; + Rotation[3 * 4 + 2] = Direction[3]; + + dGeomSetRotation(g, Rotation); +} + +void dGeomRayGet(dxGeom* g, dVector3 Origin, dVector3 Direction){ + const dReal* Position = dGeomGetPosition(g); + Origin[0] = Position[0]; + Origin[1] = Position[1]; + Origin[2] = Position[2]; + Origin[3] = Position[3]; + + const dReal* Rotation = dGeomGetRotation(g); + Direction[0] = Rotation[0 * 4 + 2]; + Direction[1] = Rotation[1 * 4 + 2]; + Direction[2] = Rotation[2 * 4 + 2]; + Direction[3] = Rotation[3 * 4 + 2]; +} \ No newline at end of file diff --git a/libraries/ode-0.9/contrib/dRay/dRay_Box.cpp b/libraries/ode-0.9/contrib/dRay/dRay_Box.cpp new file mode 100644 index 0000000000..d2a0d9c580 --- /dev/null +++ b/libraries/ode-0.9/contrib/dRay/dRay_Box.cpp @@ -0,0 +1,134 @@ +// Ripped from Magic Software + +#include "Include\dRay.h" +#include "dxRay.h" + +bool Clip(dReal Denom, dReal Numer, dReal& T0, dReal& T1){ + // Return value is 'true' if line segment intersects the current test + // plane. Otherwise 'false' is returned in which case the line segment + // is entirely clipped. + + if (Denom > REAL(0.0)){ + if (Numer > Denom * T1){ + return false; + } + + if (Numer > Denom * T0){ + T0 = Numer / Denom; + } + return true; + } + else if (Denom < REAL(0.0)){ + if (Numer > Denom * T0){ + return false; + } + + if (Numer > Denom * T1){ + T1 = Numer / Denom; + } + return true; + } + else return Numer <= REAL(0.0); +} + +bool FindIntersection(const dVector3 Origin, const dVector3 Direction, const dVector3 Extents, dReal& T0, dReal& T1){ + dReal SaveT0 = T0; + dReal SaveT1 = T1; + + bool NotEntirelyClipped = + Clip(+Direction[0], -Origin[0] - Extents[0], T0, T1) && + Clip(-Direction[0], +Origin[0] - Extents[0], T0, T1) && + Clip(+Direction[1], -Origin[1] - Extents[1], T0, T1) && + Clip(-Direction[1], +Origin[1] - Extents[1], T0, T1) && + Clip(+Direction[2], -Origin[2] - Extents[2], T0, T1) && + Clip(-Direction[2], +Origin[2] - Extents[2], T0, T1); + + return NotEntirelyClipped && (T0 != SaveT0 || T1 != SaveT1); +} + +int dCollideBR(dxGeom* RayGeom, dxGeom* BoxGeom, int Flags, dContactGeom* Contacts, int Stride){ + const dVector3& Position = *(const dVector3*)dGeomGetPosition(BoxGeom); + const dMatrix3& Rotation = *(const dMatrix3*)dGeomGetRotation(BoxGeom); + dVector3 Extents; + dGeomBoxGetLengths(BoxGeom, Extents); + Extents[0] /= 2; + Extents[1] /= 2; + Extents[2] /= 2; + Extents[3] /= 2; + + dVector3 Origin, Direction; + dGeomRayGet(RayGeom, Origin, Direction); + dReal Length = dGeomRayGetLength(RayGeom); + + dVector3 Diff; + Diff[0] = Origin[0] - Position[0]; + Diff[1] = Origin[1] - Position[1]; + Diff[2] = Origin[2] - Position[2]; + Diff[3] = Origin[3] - Position[3]; + + Direction[0] *= Length; + Direction[1] *= Length; + Direction[2] *= Length; + Direction[3] *= Length; + + dVector3 Rot[3]; + Decompose(Rotation, Rot); + + dVector3 TransOrigin; + TransOrigin[0] = dDOT(Diff, Rot[0]); + TransOrigin[1] = dDOT(Diff, Rot[1]); + TransOrigin[2] = dDOT(Diff, Rot[2]); + TransOrigin[3] = REAL(0.0); + + dVector3 TransDirection; + TransDirection[0] = dDOT(Direction, Rot[0]); + TransDirection[1] = dDOT(Direction, Rot[1]); + TransDirection[2] = dDOT(Direction, Rot[2]); + TransDirection[3] = REAL(0.0); + + dReal T[2]; + T[0] = 0.0f; + T[1] = dInfinity; + + bool Intersect = FindIntersection(TransOrigin, TransDirection, Extents, T[0], T[1]); + + if (Intersect){ + if (T[0] > REAL(0.0)){ + dContactGeom* Contact0 = CONTACT(Flags, Contacts, 0, Stride); + Contact0->pos[0] = Origin[0] + T[0] * Direction[0]; + Contact0->pos[1] = Origin[1] + T[0] * Direction[1]; + Contact0->pos[2] = Origin[2] + T[0] * Direction[2]; + Contact0->pos[3] = Origin[3] + T[0] * Direction[3]; + //Contact0->normal = 0; + Contact0->depth = 0.0f; + Contact0->g1 = RayGeom; + Contact0->g2 = BoxGeom; + + dContactGeom* Contact1 = CONTACT(Flags, Contacts, 1, Stride); + Contact1->pos[0] = Origin[0] + T[1] * Direction[0]; + Contact1->pos[1] = Origin[1] + T[1] * Direction[1]; + Contact1->pos[2] = Origin[2] + T[1] * Direction[2]; + Contact1->pos[3] = Origin[3] + T[1] * Direction[3]; + //Contact1->normal = 0; + Contact1->depth = 0.0f; + Contact1->g1 = RayGeom; + Contact1->g2 = BoxGeom; + + return 2; + } + else{ + dContactGeom* Contact = CONTACT(Flags, Contacts, 0, Stride); + Contact->pos[0] = Origin[0] + T[1] * Direction[0]; + Contact->pos[1] = Origin[1] + T[1] * Direction[1]; + Contact->pos[2] = Origin[2] + T[1] * Direction[2]; + Contact->pos[3] = Origin[3] + T[1] * Direction[3]; + //Contact->normal = 0; + Contact->depth = 0.0f; + Contact->g1 = RayGeom; + Contact->g2 = BoxGeom; + + return 1; + } + } + else return 0; +} \ No newline at end of file diff --git a/libraries/ode-0.9/contrib/dRay/dRay_CCylinder.cpp b/libraries/ode-0.9/contrib/dRay/dRay_CCylinder.cpp new file mode 100644 index 0000000000..b9ea0c0dd3 --- /dev/null +++ b/libraries/ode-0.9/contrib/dRay/dRay_CCylinder.cpp @@ -0,0 +1,199 @@ +// Ripped from Magic Software + +#include "Include\dRay.h" +#include "dxRay.h" + +int Find(const dVector3 Origin, dVector3 Direction, dReal Length, const dVector3 CCPos, const dMatrix3 CCRot, dReal CCRadius, dReal CCLength, dReal T[2]){ + dVector3 U, V, W; + Decompose(CCRot, U, V, W); + + dVector3 CCOrigin; + CCOrigin[0] = CCPos[0] - (W[0] * CCLength / 2); + CCOrigin[1] = CCPos[1] - (W[1] * CCLength / 2); + CCOrigin[2] = CCPos[2] - (W[2] * CCLength / 2); + CCOrigin[3] = CCPos[3] - (W[3] * CCLength / 2); + + dVector3 D; + D[0] = dDOT(U, Direction); + D[1] = dDOT(V, Direction); + D[2] = dDOT(W, Direction); + + dReal DMag = Length; + dReal InvDMag = REAL(1.0) / DMag; + + dVector3 Diff; + Diff[0] = Origin[0] - CCOrigin[0]; + Diff[1] = Origin[1] - CCOrigin[1]; + Diff[2] = Origin[2] - CCOrigin[2]; + Diff[3] = Origin[3] - CCOrigin[3]; + + dVector3 P; + P[0] = dDOT(U, Diff); + P[1] = dDOT(V, Diff); + P[2] = dDOT(W, Diff); + + dReal CCRadiusSq = CCRadius * CCRadius; + + dReal Epsilon = 1e-12f; + + if (dFabs(D[2]) >= REAL(1.0) - Epsilon){ // line is parallel to capsule axis + dReal Discr = CCRadiusSq - P[0] * P[0] - P[1] * P[1]; + + if (Discr >= REAL(0.0)){ + dReal Root = dSqrt(Discr); + T[0] = (-P[2] + Root) * InvDMag; + T[1] = (CCLength - P[2] + Root) * InvDMag; + return 2; + } + else return 0; + } + + // test intersection with infinite cylinder + dReal A = D[0] * D[0] + D[1] * D[1]; + dReal B = P[0] * D[0] + P[1] * D[1]; + dReal C = P[0] * P[0] + P[1] * P[1] - CCRadiusSq; + dReal Discr = B * B - A * C; + if (Discr < REAL(0.0)){ // line does not intersect infinite cylinder + return 0; + } + + int Count = 0; + + if (Discr > REAL(0.0)){ // line intersects infinite cylinder in two places + dReal Root = dSqrt(Discr); + dReal Inv = REAL(1.0) / A; + + dReal TTemp = (-B - Root) * Inv; + + dReal Tmp = P[2] + TTemp * D[2]; + if (REAL(0.0) <= Tmp && Tmp <= CCLength){ + T[Count++] = TTemp * InvDMag; + } + + + TTemp = (-B + Root) * Inv; + Tmp = P[2] + TTemp * D[2]; + if (REAL(0.0) <= Tmp && Tmp <= CCLength){ + T[Count++] = TTemp * InvDMag; + } + + if (Count == 2){ // line intersects capsule wall in two places + return 2; + } + } + else{ // line is tangent to infinite cylinder + dReal TTemp = -B / A; + dReal Tmp = P[2] + TTemp * D[2]; + if (REAL(0.0) <= Tmp && Tmp <= CCLength){ + T[0] = TTemp * InvDMag; + return 1; + } + } + + // test intersection with bottom hemisphere + // fA = 1 + B += P[2] * D[2]; + C += P[2] * P[2]; + Discr = B * B - C; + if (Discr > REAL(0.0)){ + dReal Root = dSqrt(Discr); + dReal TTemp = -B - Root; + dReal Tmp = P[2] + TTemp * D[2]; + if (Tmp <= REAL(0.0)){ + T[Count++] = TTemp * InvDMag; + if (Count == 2){ + return 2; + } + } + + TTemp = -B + Root; + Tmp = P[2] + TTemp * D[2]; + if (Tmp <= REAL(0.0)){ + T[Count++] = TTemp * InvDMag; + if (Count == 2){ + return 2; + } + } + } + else if (Discr == REAL(0.0)){ + dReal TTemp = -B; + dReal Tmp = P[2] + TTemp * D[2]; + if (Tmp <= REAL(0.0)){ + T[Count++] = TTemp * InvDMag; + if (Count == 2){ + return 2; + } + } + } + + // test intersection with top hemisphere + // fA = 1 + B -= D[2] * CCLength; + C += CCLength * (CCLength - REAL(2.0) * P[2]); + + Discr = B * B - C; + if (Discr > REAL(0.0)){ + dReal Root = dSqrt(Discr); + dReal TTemp = -B - Root; + dReal Tmp = P[2] + TTemp * D[2]; + if (Tmp >= CCLength){ + + T[Count++] = TTemp * InvDMag; + if (Count == 2){ + return 2; + } + } + + TTemp = -B + Root; + Tmp = P[2] + TTemp * D[2]; + if (Tmp >= CCLength){ + T[Count++] = TTemp * InvDMag; + if (Count == 2){ + return 2; + } + } + } + else if (Discr == REAL(0.0)){ + dReal TTemp = -B; + dReal Tmp = P[2] + TTemp * D[2]; + if (Tmp >= CCLength){ + T[Count++] = TTemp * InvDMag; + if (Count == 2){ + return 2; + } + } + } + return Count; +} + +int dCollideCCR(dxGeom* RayGeom, dxGeom* CCGeom, int Flags, dContactGeom* Contacts, int Stride){ + const dVector3& CCPos = *(const dVector3*)dGeomGetPosition(CCGeom); + const dMatrix3& CCRot = *(const dMatrix3*)dGeomGetRotation(CCGeom); + + dReal CCRadius, CCLength; + dGeomCCylinderGetParams(CCGeom, &CCRadius, &CCLength); + + dVector3 Origin, Direction; + dGeomRayGet(RayGeom, Origin, Direction); + dReal Length = dGeomRayGetLength(RayGeom); + + dReal T[2]; + int Count = Find(Origin, Direction, Length, CCPos, CCRot, CCRadius, CCLength, T); + int ContactCount = 0; + for (int i = 0; i < Count; i++){ + if (T[i] >= 0.0){ + dContactGeom* Contact = CONTACT(Flags, Contacts, ContactCount, Stride); + Contact->pos[0] = Origin[0] + T[i] * Direction[0] * Length; + Contact->pos[1] = Origin[1] + T[i] * Direction[1] * Length; + Contact->pos[2] = Origin[2] + T[i] * Direction[2] * Length; + Contact->pos[3] = Origin[3] + T[i] * Direction[3] * Length; + //Contact->normal = 0; + Contact->depth = 0.0f; + Contact->g1 = RayGeom; + Contact->g2 = CCGeom; + + ContactCount++; + } + } + return ContactCount; +} \ No newline at end of file diff --git a/libraries/ode-0.9/contrib/dRay/dRay_Plane.cpp b/libraries/ode-0.9/contrib/dRay/dRay_Plane.cpp new file mode 100644 index 0000000000..cf03c5b3c7 --- /dev/null +++ b/libraries/ode-0.9/contrib/dRay/dRay_Plane.cpp @@ -0,0 +1,35 @@ +// Ripped from Paul Bourke + +#include "Include\dRay.h" +#include "dxRay.h" + +int dCollidePR(dxGeom* RayGeom, dxGeom* PlaneGeom, int Flags, dContactGeom* Contact, int Stride){ + dVector3 Plane; + dGeomPlaneGetParams(PlaneGeom, Plane); + + dVector3 Origin, Direction; + dGeomRayGet(RayGeom, Origin, Direction); + + dReal Length = dGeomRayGetLength(RayGeom); + + dReal Denom = Plane[0] * Direction[0] + Plane[1] * Direction[1] + Plane[2] * Direction[2]; + if (dFabs(Denom) < 0.00001f){ + return 0; // Ray never hits + } + + float T = -(Plane[3] + Plane[0] * Origin[0] + Plane[1] * Origin[1] + Plane[2] * Origin[2]) / Denom; + + if (T < 0 || T > Length){ + return 0; // Ray hits but not within boundaries + } + + Contact->pos[0] = Origin[0] + T * Direction[0]; + Contact->pos[1] = Origin[1] + T * Direction[1]; + Contact->pos[2] = Origin[2] + T * Direction[2]; + Contact->pos[3] = REAL(0.0); + //Contact->normal = 0; + Contact->depth = 0.0f; + Contact->g1 = RayGeom; + Contact->g2 = PlaneGeom; + return 1; +} \ No newline at end of file diff --git a/libraries/ode-0.9/contrib/dRay/dRay_Sphere.cpp b/libraries/ode-0.9/contrib/dRay/dRay_Sphere.cpp new file mode 100644 index 0000000000..8e1ac39329 --- /dev/null +++ b/libraries/ode-0.9/contrib/dRay/dRay_Sphere.cpp @@ -0,0 +1,95 @@ +// Ripped from Magic Software + +#include "Include\dRay.h" +#include "dxRay.h" + +int dCollideSR(dxGeom* RayGeom, dxGeom* SphereGeom, int Flags, dContactGeom* Contacts, int Stride){ + const dVector3& Position = *(const dVector3*)dGeomGetPosition(SphereGeom); + dReal Radius = dGeomSphereGetRadius(SphereGeom); + + dVector3 Origin, Direction; + dGeomRayGet(RayGeom, Origin, Direction); + dReal Length = dGeomRayGetLength(RayGeom); + + dVector3 Diff; + Diff[0] = Origin[0] - Position[0]; + Diff[1] = Origin[1] - Position[1]; + Diff[2] = Origin[2] - Position[2]; + Diff[3] = Origin[3] - Position[3]; + + Direction[0] *= Length; + Direction[1] *= Length; + Direction[2] *= Length; + Direction[3] *= Length; + + dReal A = Length * Length; + dReal B = dDOT(Diff, Direction); + dReal C = dDOT(Diff, Diff) - (Radius * Radius); + + dReal Discr = B * B - A * C; + if (Discr < REAL(0.0)){ + return 0; + } + else if (Discr > REAL(0.0)){ + dReal T[2]; + dReal Root = dSqrt(Discr); + dReal InvA = REAL(1.0) / A; + T[0] = (-B - Root) * InvA; + T[1] = (-B + Root) * InvA; + + if (T[0] >= REAL(0.0)){ + dContactGeom* Contact0 = CONTACT(Flags, Contacts, 0, Stride); + Contact0->pos[0] = Origin[0] + T[0] * Direction[0]; + Contact0->pos[1] = Origin[1] + T[0] * Direction[1]; + Contact0->pos[2] = Origin[2] + T[0] * Direction[2]; + Contact0->pos[3] = Origin[3] + T[0] * Direction[3]; + //Contact0->normal = 0; + Contact0->depth = 0.0f; + Contact0->g1 = RayGeom; + Contact0->g2 = SphereGeom; + + dContactGeom* Contact1 = CONTACT(Flags, Contacts, 1, Stride); + Contact1->pos[0] = Origin[0] + T[1] * Direction[0]; + Contact1->pos[1] = Origin[1] + T[1] * Direction[1]; + Contact1->pos[2] = Origin[2] + T[1] * Direction[2]; + Contact1->pos[3] = Origin[3] + T[1] * Direction[3]; + //Contact1->normal = 0; + Contact1->depth = 0.0f; + Contact1->g1 = RayGeom; + Contact1->g2 = SphereGeom; + + return 2; + } + else if (T[1] >= REAL(0.0)){ + dContactGeom* Contact = CONTACT(Flags, Contacts, 1, Stride); + Contact->pos[0] = Origin[0] + T[1] * Direction[0]; + Contact->pos[1] = Origin[1] + T[1] * Direction[1]; + Contact->pos[2] = Origin[2] + T[1] * Direction[2]; + Contact->pos[3] = Origin[3] + T[1] * Direction[3]; + //Contact->normal = 0; + Contact->depth = 0.0f; + Contact->g1 = RayGeom; + Contact->g2 = SphereGeom; + + return 1; + } + else return 0; + } + else{ + dReal T; + T = -B / A; + if (T >= REAL(0.0)){ + dContactGeom* Contact = CONTACT(Flags, Contacts, 0, Stride); + Contact->pos[0] = Origin[0] + T * Direction[0]; + Contact->pos[1] = Origin[1] + T * Direction[1]; + Contact->pos[2] = Origin[2] + T * Direction[2]; + Contact->pos[3] = Origin[3] + T * Direction[3]; + //Contact->normal = 0; + Contact->depth = 0.0f; + Contact->g1 = RayGeom; + Contact->g2 = SphereGeom; + return 1; + } + else return 0; + } +} \ No newline at end of file diff --git a/libraries/ode-0.9/contrib/dRay/dxRay.h b/libraries/ode-0.9/contrib/dRay/dxRay.h new file mode 100644 index 0000000000..0fd1d2d55c --- /dev/null +++ b/libraries/ode-0.9/contrib/dRay/dxRay.h @@ -0,0 +1,32 @@ +struct dxRay{ + dReal Length; +}; + +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] = Matrix[3 * 4 + 0]; + Up[0] = Matrix[0 * 4 + 1]; + Up[1] = Matrix[1 * 4 + 1]; + Up[2] = Matrix[2 * 4 + 1]; + Up[3] = Matrix[3 * 4 + 1]; + Direction[0] = Matrix[0 * 4 + 2]; + Direction[1] = Matrix[1 * 4 + 2]; + Direction[2] = Matrix[2 * 4 + 2]; + Direction[3] = Matrix[3 * 4 + 2]; +} + +inline void Decompose(const dMatrix3 Matrix, dVector3 Vectors[3]){ + Decompose(Matrix, Vectors[0], Vectors[1], Vectors[2]); +} + +inline dContactGeom* CONTACT(int Flags, dContactGeom* Contacts, int Index, int Stride){ + dIASSERT(Index >= 0 && Index < (Flags & 0x0ffff)); + return ((dContactGeom*)(((char*)Contacts) + (Index * Stride))); +} + +int dCollidePR(dxGeom* RayGeom, dxGeom* PlaneGeom, int Flags, dContactGeom* Contacts, int Stride); +int dCollideSR(dxGeom* RayGeom, dxGeom* SphereGeom, int Flags, dContactGeom* Contacts, int Stride); +int dCollideBR(dxGeom* RayGeom, dxGeom* BoxGeom, int Flags, dContactGeom* Contacts, int Stride); +int dCollideCCR(dxGeom* RayGeom, dxGeom* CCylinderGeom, int Flags, dContactGeom* Contacts, int Stride); \ No newline at end of file diff --git a/libraries/ode-0.9/depcomp b/libraries/ode-0.9/depcomp new file mode 100755 index 0000000000..ca5ea4e1ef --- /dev/null +++ b/libraries/ode-0.9/depcomp @@ -0,0 +1,584 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2006-10-15.18 + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006 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. + stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` + tmpdepfile="$stripped.u" + if test "$libtool" = yes; then + "$@" -Wc,-M + else + "$@" -M + fi + stat=$? + + if test -f "$tmpdepfile"; then : + else + stripped=`echo "$stripped" | sed 's,^.*/,,'` + tmpdepfile="$stripped.u" + fi + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + + if test -f "$tmpdepfile"; then + outname="$stripped.o" + # 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,^$outname:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^$outname: \(.*\)$,\1:," < "$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: diff --git a/libraries/ode-0.9/docs/annotated.html b/libraries/ode-0.9/docs/annotated.html new file mode 100644 index 0000000000..3b3c2f66b6 --- /dev/null +++ b/libraries/ode-0.9/docs/annotated.html @@ -0,0 +1,30 @@ + + +Open Dynamics Engine: Data Structures + + + + + + +

    Open Dynamics Engine Data Structures

    Here are the data structures with brief descriptions: + + +
    dContactGeomDescribe the contact point between two geoms
    dsFunctionsSet of functions to be used as callbacks by the simulation loop
    +
    Generated on Fri Oct 12 08:36:52 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/collision_8h-source.html b/libraries/ode-0.9/docs/collision_8h-source.html new file mode 100644 index 0000000000..b6ff3b7a3a --- /dev/null +++ b/libraries/ode-0.9/docs/collision_8h-source.html @@ -0,0 +1,417 @@ + + +Open Dynamics Engine: collision.h Source File + + + + + +

    collision.h

    00001 /*************************************************************************
    +00002  *                                                                       *
    +00003  * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith.       *
    +00004  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
    +00005  *                                                                       *
    +00006  * This library is free software; you can redistribute it and/or         *
    +00007  * modify it under the terms of EITHER:                                  *
    +00008  *   (1) The GNU Lesser General Public License as published by the Free  *
    +00009  *       Software Foundation; either version 2.1 of the License, or (at  *
    +00010  *       your option) any later version. The text of the GNU Lesser      *
    +00011  *       General Public License is included with this library in the     *
    +00012  *       file LICENSE.TXT.                                               *
    +00013  *   (2) The BSD-style license that is included with this library in     *
    +00014  *       the file LICENSE-BSD.TXT.                                       *
    +00015  *                                                                       *
    +00016  * This library is distributed in the hope that it will be useful,       *
    +00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
    +00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
    +00019  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
    +00020  *                                                                       *
    +00021  *************************************************************************/
    +00022 
    +00023 #ifndef _ODE_COLLISION_H_
    +00024 #define _ODE_COLLISION_H_
    +00025 
    +00026 #include <ode/common.h>
    +00027 #include <ode/collision_space.h>
    +00028 #include <ode/contact.h>
    +00029 
    +00030 #ifdef __cplusplus
    +00031 extern "C" {
    +00032 #endif
    +00033 
    +00049 /* ************************************************************************ */
    +00050 /* general functions */
    +00051 
    +00065 ODE_API void dGeomDestroy (dGeomID geom);
    +00066 
    +00067 
    +00075 ODE_API void dGeomSetData (dGeomID geom, void* data);
    +00076 
    +00077 
    +00084 ODE_API void *dGeomGetData (dGeomID geom);
    +00085 
    +00086 
    +00105 ODE_API void dGeomSetBody (dGeomID geom, dBodyID body);
    +00106 
    +00107 
    +00114 ODE_API dBodyID dGeomGetBody (dGeomID geom);
    +00115 
    +00116 
    +00131 ODE_API void dGeomSetPosition (dGeomID geom, dReal x, dReal y, dReal z);
    +00132 
    +00133 
    +00146 ODE_API void dGeomSetRotation (dGeomID geom, const dMatrix3 R);
    +00147 
    +00148 
    +00162 ODE_API void dGeomSetQuaternion (dGeomID geom, const dQuaternion Q);
    +00163 
    +00164 
    +00181 ODE_API const dReal * dGeomGetPosition (dGeomID geom);
    +00182 
    +00183 
    +00191 ODE_API void dGeomCopyPosition (dGeomID geom, dVector3 pos);
    +00192 
    +00193 
    +00210 ODE_API const dReal * dGeomGetRotation (dGeomID geom);
    +00211 
    +00212 
    +00226 ODE_API void dGeomCopyRotation(dGeomID geom, dMatrix3 R);
    +00227 
    +00228 
    +00242 ODE_API void dGeomGetQuaternion (dGeomID geom, dQuaternion result);
    +00243 
    +00244 
    +00261 ODE_API void dGeomGetAABB (dGeomID geom, dReal aabb[6]);
    +00262 
    +00263 
    +00270 ODE_API int dGeomIsSpace (dGeomID geom);
    +00271 
    +00272 
    +00280 ODE_API dSpaceID dGeomGetSpace (dGeomID);
    +00281 
    +00282 
    +00307 ODE_API int dGeomGetClass (dGeomID geom);
    +00308 
    +00309 
    +00322 ODE_API void dGeomSetCategoryBits (dGeomID geom, unsigned long bits);
    +00323 
    +00324 
    +00337 ODE_API void dGeomSetCollideBits (dGeomID geom, unsigned long bits);
    +00338 
    +00339 
    +00348 ODE_API unsigned long dGeomGetCategoryBits (dGeomID);
    +00349 
    +00350 
    +00359 ODE_API unsigned long dGeomGetCollideBits (dGeomID);
    +00360 
    +00361 
    +00374 ODE_API void dGeomEnable (dGeomID geom);
    +00375 
    +00376 
    +00389 ODE_API void dGeomDisable (dGeomID geom);
    +00390 
    +00391 
    +00405 ODE_API int dGeomIsEnabled (dGeomID geom);
    +00406 
    +00407 /* ************************************************************************ */
    +00408 /* geom offset from body */
    +00409 
    +00425 ODE_API void dGeomSetOffsetPosition (dGeomID geom, dReal x, dReal y, dReal z);
    +00426 
    +00427 
    +00441 ODE_API void dGeomSetOffsetRotation (dGeomID geom, const dMatrix3 R);
    +00442 
    +00443 
    +00457 ODE_API void dGeomSetOffsetQuaternion (dGeomID geom, const dQuaternion Q);
    +00458 
    +00459 
    +00476 ODE_API void dGeomSetOffsetWorldPosition (dGeomID geom, dReal x, dReal y, dReal z);
    +00477 
    +00478 
    +00493 ODE_API void dGeomSetOffsetWorldRotation (dGeomID geom, const dMatrix3 R);
    +00494 
    +00495 
    +00510 ODE_API void dGeomSetOffsetWorldQuaternion (dGeomID geom, const dQuaternion);
    +00511 
    +00512 
    +00526 ODE_API void dGeomClearOffset(dGeomID geom);
    +00527 
    +00528 
    +00544 ODE_API int dGeomIsOffset(dGeomID geom);
    +00545 
    +00546 
    +00560 ODE_API const dReal * dGeomGetOffsetPosition (dGeomID geom);
    +00561 
    +00562 
    +00573 ODE_API void dGeomCopyOffsetPosition (dGeomID geom, dVector3 pos);
    +00574 
    +00575 
    +00590 ODE_API const dReal * dGeomGetOffsetRotation (dGeomID geom);
    +00591 
    +00592 
    +00604 ODE_API void dGeomCopyOffsetRotation (dGeomID geom, dMatrix3 R);
    +00605 
    +00606 
    +00617 ODE_API void dGeomGetOffsetQuaternion (dGeomID geom, dQuaternion result);
    +00618 
    +00619 
    +00620 /* ************************************************************************ */
    +00621 /* collision detection */
    +00622 
    +00623 /*
    +00624  * Just generate any contacts (disables any contact refining).
    +00625  */
    +00626 #define CONTACTS_UNIMPORTANT        0x80000000
    +00627 
    +00675 ODE_API int dCollide (dGeomID o1, dGeomID o2, int flags, dContactGeom *contact,
    +00676          int skip);
    +00677 
    +00705 ODE_API void dSpaceCollide (dSpaceID space, void *data, dNearCallback *callback);
    +00706 
    +00707 
    +00742 ODE_API void dSpaceCollide2 (dGeomID space1, dGeomID space2, void *data, dNearCallback *callback);
    +00743 
    +00744 
    +00745 /* ************************************************************************ */
    +00746 /* standard classes */
    +00747 
    +00748 /* the maximum number of user classes that are supported */
    +00749 enum {
    +00750   dMaxUserClasses = 4
    +00751 };
    +00752 
    +00753 /* class numbers - each geometry object needs a unique number */
    +00754 enum {
    +00755   dSphereClass = 0,
    +00756   dBoxClass,
    +00757   dCapsuleClass,
    +00758   dCylinderClass,
    +00759   dPlaneClass,
    +00760   dRayClass,
    +00761   dConvexClass,
    +00762   dGeomTransformClass,
    +00763   dTriMeshClass,
    +00764   dHeightfieldClass,
    +00765 
    +00766   dFirstSpaceClass,
    +00767   dSimpleSpaceClass = dFirstSpaceClass,
    +00768   dHashSpaceClass,
    +00769   dQuadTreeSpaceClass,
    +00770   dLastSpaceClass = dQuadTreeSpaceClass,
    +00771 
    +00772   dFirstUserClass,
    +00773   dLastUserClass = dFirstUserClass + dMaxUserClasses - 1,
    +00774   dGeomNumClasses
    +00775 };
    +00776 
    +00777 
    +00797 ODE_API dGeomID dCreateSphere (dSpaceID space, dReal radius);
    +00798 
    +00799 
    +00809 ODE_API void dGeomSphereSetRadius (dGeomID sphere, dReal radius);
    +00810 
    +00811 
    +00820 ODE_API dReal dGeomSphereGetRadius (dGeomID sphere);
    +00821 
    +00822 
    +00837 ODE_API dReal dGeomSpherePointDepth (dGeomID sphere, dReal x, dReal y, dReal z);
    +00838 
    +00839 
    +00840 //--> Convex Functions
    +00841 ODE_API dGeomID dCreateConvex (dSpaceID space,
    +00842                 dReal *_planes,
    +00843                 unsigned int _planecount,
    +00844                 dReal *_points,
    +00845                 unsigned int _pointcount,unsigned int *_polygons);
    +00846 
    +00847 ODE_API void dGeomSetConvex (dGeomID g,
    +00848               dReal *_planes,
    +00849               unsigned int _count,
    +00850               dReal *_points,
    +00851               unsigned int _pointcount,unsigned int *_polygons);
    +00852 //<-- Convex Functions
    +00853 
    +00875 ODE_API dGeomID dCreateBox (dSpaceID space, dReal lx, dReal ly, dReal lz);
    +00876 
    +00877 
    +00889 ODE_API void dGeomBoxSetLengths (dGeomID box, dReal lx, dReal ly, dReal lz);
    +00890 
    +00891 
    +00901 ODE_API void dGeomBoxGetLengths (dGeomID box, dVector3 result);
    +00902 
    +00903 
    +00916 ODE_API dReal dGeomBoxPointDepth (dGeomID box, dReal x, dReal y, dReal z);
    +00917 
    +00918 
    +00919 ODE_API dGeomID dCreatePlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d);
    +00920 ODE_API void dGeomPlaneSetParams (dGeomID plane, dReal a, dReal b, dReal c, dReal d);
    +00921 ODE_API void dGeomPlaneGetParams (dGeomID plane, dVector4 result);
    +00922 ODE_API dReal dGeomPlanePointDepth (dGeomID plane, dReal x, dReal y, dReal z);
    +00923 
    +00924 ODE_API dGeomID dCreateCapsule (dSpaceID space, dReal radius, dReal length);
    +00925 ODE_API void dGeomCapsuleSetParams (dGeomID ccylinder, dReal radius, dReal length);
    +00926 ODE_API void dGeomCapsuleGetParams (dGeomID ccylinder, dReal *radius, dReal *length);
    +00927 ODE_API dReal dGeomCapsulePointDepth (dGeomID ccylinder, dReal x, dReal y, dReal z);
    +00928 
    +00929 // For now we want to have a backwards compatible C-API, note: C++ API is not.
    +00930 #define dCreateCCylinder dCreateCapsule
    +00931 #define dGeomCCylinderSetParams dGeomCapsuleSetParams
    +00932 #define dGeomCCylinderGetParams dGeomCapsuleGetParams
    +00933 #define dGeomCCylinderPointDepth dGeomCapsulePointDepth
    +00934 #define dCCylinderClass dCapsuleClass
    +00935 
    +00936 ODE_API dGeomID dCreateCylinder (dSpaceID space, dReal radius, dReal length);
    +00937 ODE_API void dGeomCylinderSetParams (dGeomID cylinder, dReal radius, dReal length);
    +00938 ODE_API void dGeomCylinderGetParams (dGeomID cylinder, dReal *radius, dReal *length);
    +00939 
    +00940 ODE_API dGeomID dCreateRay (dSpaceID space, dReal length);
    +00941 ODE_API void dGeomRaySetLength (dGeomID ray, dReal length);
    +00942 ODE_API dReal dGeomRayGetLength (dGeomID ray);
    +00943 ODE_API void dGeomRaySet (dGeomID ray, dReal px, dReal py, dReal pz,
    +00944         dReal dx, dReal dy, dReal dz);
    +00945 ODE_API void dGeomRayGet (dGeomID ray, dVector3 start, dVector3 dir);
    +00946 
    +00947 /*
    +00948  * Set/get ray flags that influence ray collision detection.
    +00949  * These flags are currently only noticed by the trimesh collider, because
    +00950  * they can make a major differences there.
    +00951  */
    +00952 ODE_API void dGeomRaySetParams (dGeomID g, int FirstContact, int BackfaceCull);
    +00953 ODE_API void dGeomRayGetParams (dGeomID g, int *FirstContact, int *BackfaceCull);
    +00954 ODE_API void dGeomRaySetClosestHit (dGeomID g, int closestHit);
    +00955 ODE_API int dGeomRayGetClosestHit (dGeomID g);
    +00956 
    +00957 #include "collision_trimesh.h"
    +00958 
    +00959 ODE_API dGeomID dCreateGeomTransform (dSpaceID space);
    +00960 ODE_API void dGeomTransformSetGeom (dGeomID g, dGeomID obj);
    +00961 ODE_API dGeomID dGeomTransformGetGeom (dGeomID g);
    +00962 ODE_API void dGeomTransformSetCleanup (dGeomID g, int mode);
    +00963 ODE_API int dGeomTransformGetCleanup (dGeomID g);
    +00964 ODE_API void dGeomTransformSetInfo (dGeomID g, int mode);
    +00965 ODE_API int dGeomTransformGetInfo (dGeomID g);
    +00966 
    +00967 
    +00968 /* ************************************************************************ */
    +00969 /* heightfield functions */
    +00970 
    +00971 
    +00972 // Data storage for heightfield data.
    +00973 struct dxHeightfieldData;
    +00974 typedef struct dxHeightfieldData* dHeightfieldDataID;
    +00975 
    +00976 
    +00994 typedef dReal dHeightfieldGetHeight( void* p_user_data, int x, int z );
    +00995 
    +00996 
    +00997 
    +01017 ODE_API dGeomID dCreateHeightfield( dSpaceID space,
    +01018                dHeightfieldDataID data, int bPlaceable );
    +01019 
    +01020 
    +01033 ODE_API dHeightfieldDataID dGeomHeightfieldDataCreate();
    +01034 
    +01035 
    +01044 ODE_API void dGeomHeightfieldDataDestroy( dHeightfieldDataID d );
    +01045 
    +01046 
    +01047 
    +01088 ODE_API void dGeomHeightfieldDataBuildCallback( dHeightfieldDataID d,
    +01089             void* pUserData, dHeightfieldGetHeight* pCallback,
    +01090             dReal width, dReal depth, int widthSamples, int depthSamples,
    +01091             dReal scale, dReal offset, dReal thickness, int bWrap );
    +01092 
    +01136 ODE_API void dGeomHeightfieldDataBuildByte( dHeightfieldDataID d,
    +01137             const unsigned char* pHeightData, int bCopyHeightData,
    +01138             dReal width, dReal depth, int widthSamples, int depthSamples,
    +01139             dReal scale, dReal offset, dReal thickness,  int bWrap );
    +01140 
    +01184 ODE_API void dGeomHeightfieldDataBuildShort( dHeightfieldDataID d,
    +01185             const short* pHeightData, int bCopyHeightData,
    +01186             dReal width, dReal depth, int widthSamples, int depthSamples,
    +01187             dReal scale, dReal offset, dReal thickness, int bWrap );
    +01188 
    +01234 ODE_API void dGeomHeightfieldDataBuildSingle( dHeightfieldDataID d,
    +01235             const float* pHeightData, int bCopyHeightData,
    +01236             dReal width, dReal depth, int widthSamples, int depthSamples,
    +01237             dReal scale, dReal offset, dReal thickness, int bWrap );
    +01238 
    +01284 ODE_API void dGeomHeightfieldDataBuildDouble( dHeightfieldDataID d,
    +01285             const double* pHeightData, int bCopyHeightData,
    +01286             dReal width, dReal depth, int widthSamples, int depthSamples,
    +01287             dReal scale, dReal offset, dReal thickness, int bWrap );
    +01288 
    +01306 ODE_API void dGeomHeightfieldDataSetBounds( dHeightfieldDataID d,
    +01307             dReal minHeight, dReal maxHeight );
    +01308 
    +01309 
    +01320 ODE_API void dGeomHeightfieldSetHeightfieldData( dGeomID g, dHeightfieldDataID d );
    +01321 
    +01322 
    +01332 ODE_API dHeightfieldDataID dGeomHeightfieldGetHeightfieldData( dGeomID g );
    +01333 
    +01334 
    +01335 
    +01336 /* ************************************************************************ */
    +01337 /* utility functions */
    +01338 
    +01339 ODE_API void dClosestLineSegmentPoints (const dVector3 a1, const dVector3 a2,
    +01340             const dVector3 b1, const dVector3 b2,
    +01341             dVector3 cp1, dVector3 cp2);
    +01342 
    +01343 ODE_API int dBoxTouchesBox (const dVector3 _p1, const dMatrix3 R1,
    +01344           const dVector3 side1, const dVector3 _p2,
    +01345           const dMatrix3 R2, const dVector3 side2);
    +01346 
    +01347 // The meaning of flags parameter is the same as in dCollide()
    +01348 ODE_API int dBoxBox (const dVector3 p1, const dMatrix3 R1,
    +01349         const dVector3 side1, const dVector3 p2,
    +01350         const dMatrix3 R2, const dVector3 side2,
    +01351         dVector3 normal, dReal *depth, int *return_code,
    +01352         int flags, dContactGeom *contact, int skip);
    +01353 
    +01354 ODE_API void dInfiniteAABB (dGeomID geom, dReal aabb[6]);
    +01355 ODE_API void dInitODE(void);
    +01356 ODE_API void dCloseODE(void);
    +01357 
    +01358 /* ************************************************************************ */
    +01359 /* custom classes */
    +01360 
    +01361 typedef void dGetAABBFn (dGeomID, dReal aabb[6]);
    +01362 typedef int dColliderFn (dGeomID o1, dGeomID o2,
    +01363           int flags, dContactGeom *contact, int skip);
    +01364 typedef dColliderFn * dGetColliderFnFn (int num);
    +01365 typedef void dGeomDtorFn (dGeomID o);
    +01366 typedef int dAABBTestFn (dGeomID o1, dGeomID o2, dReal aabb[6]);
    +01367 
    +01368 typedef struct dGeomClass {
    +01369   int bytes;
    +01370   dGetColliderFnFn *collider;
    +01371   dGetAABBFn *aabb;
    +01372   dAABBTestFn *aabb_test;
    +01373   dGeomDtorFn *dtor;
    +01374 } dGeomClass;
    +01375 
    +01376 ODE_API int dCreateGeomClass (const dGeomClass *classptr);
    +01377 ODE_API void * dGeomGetClassData (dGeomID);
    +01378 ODE_API dGeomID dCreateGeom (int classnum);
    +01379 
    +01380 /* ************************************************************************ */
    +01381 
    +01382 #ifdef __cplusplus
    +01383 }
    +01384 #endif
    +01385 
    +01386 #endif
    +

    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/collision__space_8h-source.html b/libraries/ode-0.9/docs/collision__space_8h-source.html new file mode 100644 index 0000000000..dbece3d226 --- /dev/null +++ b/libraries/ode-0.9/docs/collision__space_8h-source.html @@ -0,0 +1,81 @@ + + +Open Dynamics Engine: collision_space.h Source File + + + + + +

    collision_space.h

    00001 /*************************************************************************
    +00002  *                                                                       *
    +00003  * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith.       *
    +00004  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
    +00005  *                                                                       *
    +00006  * This library is free software; you can redistribute it and/or         *
    +00007  * modify it under the terms of EITHER:                                  *
    +00008  *   (1) The GNU Lesser General Public License as published by the Free  *
    +00009  *       Software Foundation; either version 2.1 of the License, or (at  *
    +00010  *       your option) any later version. The text of the GNU Lesser      *
    +00011  *       General Public License is included with this library in the     *
    +00012  *       file LICENSE.TXT.                                               *
    +00013  *   (2) The BSD-style license that is included with this library in     *
    +00014  *       the file LICENSE-BSD.TXT.                                       *
    +00015  *                                                                       *
    +00016  * This library is distributed in the hope that it will be useful,       *
    +00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
    +00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
    +00019  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
    +00020  *                                                                       *
    +00021  *************************************************************************/
    +00022 
    +00023 #ifndef _ODE_COLLISION_SPACE_H_
    +00024 #define _ODE_COLLISION_SPACE_H_
    +00025 
    +00026 #include <ode/common.h>
    +00027 
    +00028 #ifdef __cplusplus
    +00029 extern "C" {
    +00030 #endif
    +00031 
    +00032 struct dContactGeom;
    +00033 
    +00049 typedef void dNearCallback (void *data, dGeomID o1, dGeomID o2);
    +00050 
    +00051 
    +00052 ODE_API dSpaceID dSimpleSpaceCreate (dSpaceID space);
    +00053 ODE_API dSpaceID dHashSpaceCreate (dSpaceID space);
    +00054 ODE_API dSpaceID dQuadTreeSpaceCreate (dSpaceID space, dVector3 Center, dVector3 Extents, int Depth);
    +00055 
    +00056 ODE_API void dSpaceDestroy (dSpaceID);
    +00057 
    +00058 ODE_API void dHashSpaceSetLevels (dSpaceID space, int minlevel, int maxlevel);
    +00059 ODE_API void dHashSpaceGetLevels (dSpaceID space, int *minlevel, int *maxlevel);
    +00060 
    +00061 ODE_API void dSpaceSetCleanup (dSpaceID space, int mode);
    +00062 ODE_API int dSpaceGetCleanup (dSpaceID space);
    +00063 
    +00064 ODE_API void dSpaceAdd (dSpaceID, dGeomID);
    +00065 ODE_API void dSpaceRemove (dSpaceID, dGeomID);
    +00066 ODE_API int dSpaceQuery (dSpaceID, dGeomID);
    +00067 ODE_API void dSpaceClean (dSpaceID);
    +00068 ODE_API int dSpaceGetNumGeoms (dSpaceID);
    +00069 ODE_API dGeomID dSpaceGetGeom (dSpaceID, int i);
    +00070 
    +00071 
    +00072 #ifdef __cplusplus
    +00073 }
    +00074 #endif
    +00075 
    +00076 #endif
    +

    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/collision__trimesh_8h-source.html b/libraries/ode-0.9/docs/collision__trimesh_8h-source.html new file mode 100644 index 0000000000..488925c823 --- /dev/null +++ b/libraries/ode-0.9/docs/collision__trimesh_8h-source.html @@ -0,0 +1,220 @@ + + +Open Dynamics Engine: collision_trimesh.h Source File + + + + + +

    collision_trimesh.h

    00001 /*************************************************************************
    +00002  *                                                                       *
    +00003  * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith.       *
    +00004  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
    +00005  *                                                                       *
    +00006  * This library is free software; you can redistribute it and/or         *
    +00007  * modify it under the terms of EITHER:                                  *
    +00008  *   (1) The GNU Lesser General Public License as published by the Free  *
    +00009  *       Software Foundation; either version 2.1 of the License, or (at  *
    +00010  *       your option) any later version. The text of the GNU Lesser      *
    +00011  *       General Public License is included with this library in the     *
    +00012  *       file LICENSE.TXT.                                               *
    +00013  *   (2) The BSD-style license that is included with this library in     *
    +00014  *       the file LICENSE-BSD.TXT.                                       *
    +00015  *                                                                       *
    +00016  * This library is distributed in the hope that it will be useful,       *
    +00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
    +00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
    +00019  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
    +00020  *                                                                       *
    +00021  *************************************************************************/
    +00022 
    +00023 /*
    +00024  * TriMesh code by Erwin de Vries.
    +00025  *
    +00026  * Trimesh data.
    +00027  * This is where the actual vertexdata (pointers), and BV tree is stored.
    +00028  * Vertices should be single precision!
    +00029  * This should be more sophisticated, so that the user can easyly implement
    +00030  * another collision library, but this is a lot of work, and also costs some
    +00031  * performance because some data has to be copied.
    +00032  */
    +00033 
    +00034 #ifndef _ODE_COLLISION_TRIMESH_H_
    +00035 #define _ODE_COLLISION_TRIMESH_H_
    +00036 
    +00037 #ifdef __cplusplus
    +00038 extern "C" {
    +00039 #endif
    +00040 
    +00041 /*
    +00042  * Data storage for triangle meshes.
    +00043  */
    +00044 struct dxTriMeshData;
    +00045 typedef struct dxTriMeshData* dTriMeshDataID;
    +00046 
    +00047 /*
    +00048  * These dont make much sense now, but they will later when we add more
    +00049  * features.
    +00050  */
    +00051 ODE_API dTriMeshDataID dGeomTriMeshDataCreate(void);
    +00052 ODE_API void dGeomTriMeshDataDestroy(dTriMeshDataID g);
    +00053 
    +00054 
    +00055 
    +00056 enum { TRIMESH_FACE_NORMALS };
    +00057 ODE_API void dGeomTriMeshDataSet(dTriMeshDataID g, int data_id, void* in_data);
    +00058 ODE_API void* dGeomTriMeshDataGet(dTriMeshDataID g, int data_id);
    +00059 
    +00060 
    +00061 
    +00067 ODE_API void dGeomTriMeshSetLastTransform( dGeomID g, dMatrix4 last_trans );
    +00068 ODE_API dReal* dGeomTriMeshGetLastTransform( dGeomID g );
    +00069 
    +00070 /*
    +00071  * Build TriMesh data with single precision used in vertex data .
    +00072  */
    +00073 ODE_API void dGeomTriMeshDataBuildSingle(dTriMeshDataID g,
    +00074                                  const void* Vertices, int VertexStride, int VertexCount, 
    +00075                                  const void* Indices, int IndexCount, int TriStride);
    +00076 /* same again with a normals array (used as trimesh-trimesh optimization) */
    +00077 ODE_API void dGeomTriMeshDataBuildSingle1(dTriMeshDataID g,
    +00078                                   const void* Vertices, int VertexStride, int VertexCount, 
    +00079                                   const void* Indices, int IndexCount, int TriStride,
    +00080                                   const void* Normals);
    +00081 /*
    +00082 * Build TriMesh data with double pricision used in vertex data .
    +00083 */
    +00084 ODE_API void dGeomTriMeshDataBuildDouble(dTriMeshDataID g, 
    +00085                                  const void* Vertices,  int VertexStride, int VertexCount, 
    +00086                                  const void* Indices, int IndexCount, int TriStride);
    +00087 /* same again with a normals array (used as trimesh-trimesh optimization) */
    +00088 ODE_API void dGeomTriMeshDataBuildDouble1(dTriMeshDataID g, 
    +00089                                   const void* Vertices,  int VertexStride, int VertexCount, 
    +00090                                   const void* Indices, int IndexCount, int TriStride,
    +00091                                   const void* Normals);
    +00092 
    +00093 /*
    +00094  * Simple build. Single/double precision based on dSINGLE/dDOUBLE!
    +00095  */
    +00096 ODE_API void dGeomTriMeshDataBuildSimple(dTriMeshDataID g,
    +00097                                  const dReal* Vertices, int VertexCount,
    +00098                                  const int* Indices, int IndexCount);
    +00099 /* same again with a normals array (used as trimesh-trimesh optimization) */
    +00100 ODE_API void dGeomTriMeshDataBuildSimple1(dTriMeshDataID g,
    +00101                                   const dReal* Vertices, int VertexCount,
    +00102                                   const int* Indices, int IndexCount,
    +00103                                   const int* Normals);
    +00104 
    +00105 /* Preprocess the trimesh data to remove mark unnecessary edges and vertices */
    +00106 ODE_API void dGeomTriMeshDataPreprocess(dTriMeshDataID g);
    +00107 /* Get and set the internal preprocessed trimesh data buffer, for loading and saving */
    +00108 ODE_API void dGeomTriMeshDataGetBuffer(dTriMeshDataID g, unsigned char** buf, int* bufLen);
    +00109 ODE_API void dGeomTriMeshDataSetBuffer(dTriMeshDataID g, unsigned char* buf);
    +00110 
    +00111 
    +00112 /*
    +00113  * Per triangle callback. Allows the user to say if he wants a collision with
    +00114  * a particular triangle.
    +00115  */
    +00116 typedef int dTriCallback(dGeomID TriMesh, dGeomID RefObject, int TriangleIndex);
    +00117 ODE_API void dGeomTriMeshSetCallback(dGeomID g, dTriCallback* Callback);
    +00118 ODE_API dTriCallback* dGeomTriMeshGetCallback(dGeomID g);
    +00119 
    +00120 /*
    +00121  * Per object callback. Allows the user to get the list of triangles in 1
    +00122  * shot. Maybe we should remove this one.
    +00123  */
    +00124 typedef void dTriArrayCallback(dGeomID TriMesh, dGeomID RefObject, const int* TriIndices, int TriCount);
    +00125 ODE_API void dGeomTriMeshSetArrayCallback(dGeomID g, dTriArrayCallback* ArrayCallback);
    +00126 ODE_API dTriArrayCallback* dGeomTriMeshGetArrayCallback(dGeomID g);
    +00127 
    +00128 /*
    +00129  * Ray callback.
    +00130  * Allows the user to say if a ray collides with a triangle on barycentric
    +00131  * coords. The user can for example sample a texture with alpha transparency
    +00132  * to determine if a collision should occur.
    +00133  */
    +00134 typedef int dTriRayCallback(dGeomID TriMesh, dGeomID Ray, int TriangleIndex, dReal u, dReal v);
    +00135 ODE_API void dGeomTriMeshSetRayCallback(dGeomID g, dTriRayCallback* Callback);
    +00136 ODE_API dTriRayCallback* dGeomTriMeshGetRayCallback(dGeomID g);
    +00137 
    +00138 /*
    +00139  * Trimesh class
    +00140  * Construction. Callbacks are optional.
    +00141  */
    +00142 ODE_API dGeomID dCreateTriMesh(dSpaceID space, dTriMeshDataID Data, dTriCallback* Callback, dTriArrayCallback* ArrayCallback, dTriRayCallback* RayCallback);
    +00143 
    +00144 ODE_API void dGeomTriMeshSetData(dGeomID g, dTriMeshDataID Data);
    +00145 ODE_API dTriMeshDataID dGeomTriMeshGetData(dGeomID g);
    +00146 
    +00147 
    +00148 // enable/disable/check temporal coherence
    +00149 ODE_API void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable);
    +00150 ODE_API int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass);
    +00151 
    +00152 /*
    +00153  * Clears the internal temporal coherence caches. When a geom has its
    +00154  * collision checked with a trimesh once, data is stored inside the trimesh.
    +00155  * With large worlds with lots of seperate objects this list could get huge.
    +00156  * We should be able to do this automagically.
    +00157  */
    +00158 ODE_API void dGeomTriMeshClearTCCache(dGeomID g);
    +00159 
    +00160 
    +00161 /*
    +00162  * returns the TriMeshDataID
    +00163  */
    +00164 ODE_API dTriMeshDataID dGeomTriMeshGetTriMeshDataID(dGeomID g);
    +00165 
    +00166 /*
    +00167  * Gets a triangle.
    +00168  */
    +00169 ODE_API void dGeomTriMeshGetTriangle(dGeomID g, int Index, dVector3* v0, dVector3* v1, dVector3* v2);
    +00170 
    +00171 /*
    +00172  * Gets the point on the requested triangle and the given barycentric
    +00173  * coordinates.
    +00174  */
    +00175 ODE_API void dGeomTriMeshGetPoint(dGeomID g, int Index, dReal u, dReal v, dVector3 Out);
    +00176 
    +00177 /*
    +00178 
    +00179 This is how the strided data works:
    +00180 
    +00181 struct StridedVertex{
    +00182    dVector3 Vertex;
    +00183    // Userdata
    +00184 };
    +00185 int VertexStride = sizeof(StridedVertex);
    +00186 
    +00187 struct StridedTri{
    +00188    int Indices[3];
    +00189    // Userdata
    +00190 };
    +00191 int TriStride = sizeof(StridedTri);
    +00192 
    +00193 */
    +00194 
    +00195 
    +00196 ODE_API int dGeomTriMeshGetTriangleCount (dGeomID g);
    +00197 
    +00198 ODE_API void dGeomTriMeshDataUpdate(dTriMeshDataID g);
    +00199 
    +00200 #ifdef __cplusplus
    +00201 }
    +00202 #endif
    +00203 
    +00204 #endif   /* _ODE_COLLISION_TRIMESH_H_ */
    +00205 
    +

    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/common_8h-source.html b/libraries/ode-0.9/docs/common_8h-source.html new file mode 100644 index 0000000000..8b29b64d93 --- /dev/null +++ b/libraries/ode-0.9/docs/common_8h-source.html @@ -0,0 +1,408 @@ + + +Open Dynamics Engine: common.h Source File + + + + + +

    common.h

    00001 /*************************************************************************
    +00002  *                                                                       *
    +00003  * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
    +00004  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
    +00005  *                                                                       *
    +00006  * This library is free software; you can redistribute it and/or         *
    +00007  * modify it under the terms of EITHER:                                  *
    +00008  *   (1) The GNU Lesser General Public License as published by the Free  *
    +00009  *       Software Foundation; either version 2.1 of the License, or (at  *
    +00010  *       your option) any later version. The text of the GNU Lesser      *
    +00011  *       General Public License is included with this library in the     *
    +00012  *       file LICENSE.TXT.                                               *
    +00013  *   (2) The BSD-style license that is included with this library in     *
    +00014  *       the file LICENSE-BSD.TXT.                                       *
    +00015  *                                                                       *
    +00016  * This library is distributed in the hope that it will be useful,       *
    +00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
    +00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
    +00019  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
    +00020  *                                                                       *
    +00021  *************************************************************************/
    +00022 
    +00023 #ifndef _ODE_COMMON_H_
    +00024 #define _ODE_COMMON_H_
    +00025 #include <ode/config.h>
    +00026 #include <ode/error.h>
    +00027 #include <math.h>
    +00028 
    +00029 #ifdef __cplusplus
    +00030 extern "C" {
    +00031 #endif
    +00032 
    +00033 
    +00034 /* configuration stuff */
    +00035 
    +00036 /* the efficient alignment. most platforms align data structures to some
    +00037  * number of bytes, but this is not always the most efficient alignment.
    +00038  * for example, many x86 compilers align to 4 bytes, but on a pentium it
    +00039  * is important to align doubles to 8 byte boundaries (for speed), and
    +00040  * the 4 floats in a SIMD register to 16 byte boundaries. many other
    +00041  * platforms have similar behavior. setting a larger alignment can waste
    +00042  * a (very) small amount of memory. NOTE: this number must be a power of
    +00043  * two. this is set to 16 by default.
    +00044  */
    +00045 #define EFFICIENT_ALIGNMENT 16
    +00046 
    +00047 
    +00048 /* constants */
    +00049 
    +00050 /* pi and 1/sqrt(2) are defined here if necessary because they don't get
    +00051  * defined in <math.h> on some platforms (like MS-Windows)
    +00052  */
    +00053 
    +00054 #ifndef M_PI
    +00055 #define M_PI REAL(3.1415926535897932384626433832795029)
    +00056 #endif
    +00057 #ifndef M_SQRT1_2
    +00058 #define M_SQRT1_2 REAL(0.7071067811865475244008443621048490)
    +00059 #endif
    +00060 
    +00061 
    +00062 /* debugging:
    +00063  *   IASSERT  is an internal assertion, i.e. a consistency check. if it fails
    +00064  *            we want to know where.
    +00065  *   UASSERT  is a user assertion, i.e. if it fails a nice error message
    +00066  *            should be printed for the user.
    +00067  *   AASSERT  is an arguments assertion, i.e. if it fails "bad argument(s)"
    +00068  *            is printed.
    +00069  *   DEBUGMSG just prints out a message
    +00070  */
    +00071 
    +00072 #ifndef dNODEBUG
    +00073 #ifdef __GNUC__
    +00074 #define dIASSERT(a) if (!(a)) dDebug (d_ERR_IASSERT, \
    +00075   "assertion \"" #a "\" failed in %s() [%s]",__FUNCTION__,__FILE__);
    +00076 #define dUASSERT(a,msg) if (!(a)) dDebug (d_ERR_UASSERT, \
    +00077   msg " in %s()", __FUNCTION__);
    +00078 #define dDEBUGMSG(msg) dMessage (d_ERR_UASSERT,          \
    +00079 msg " in %s() File %s Line %d", __FUNCTION__, __FILE__,__LINE__);
    +00080 #else
    +00081 #define dIASSERT(a) if (!(a)) dDebug (d_ERR_IASSERT, \
    +00082   "assertion \"" #a "\" failed in %s:%d",__FILE__,__LINE__);
    +00083 #define dUASSERT(a,msg) if (!(a)) dDebug (d_ERR_UASSERT, \
    +00084   msg " (%s:%d)", __FILE__,__LINE__);
    +00085 #define dDEBUGMSG(msg) dMessage (d_ERR_UASSERT, \
    +00086   msg " (%s:%d)", __FILE__,__LINE__);
    +00087 #endif
    +00088 #else
    +00089 #define dIASSERT(a) ;
    +00090 #define dUASSERT(a,msg) ;
    +00091 #define dDEBUGMSG(msg) ;
    +00092 #endif
    +00093 #define dAASSERT(a) dUASSERT(a,"Bad argument(s)")
    +00094 
    +00095 // Macro used to suppress unused variable warning
    +00096 #define dVARIABLEUSED(a) ((void)a)
    +00097 
    +00098 /* floating point data type, vector, matrix and quaternion types */
    +00099 
    +00100 #if defined(dSINGLE)
    +00101 typedef float dReal;
    +00102 #ifdef dDOUBLE
    +00103 #error You can only #define dSINGLE or dDOUBLE, not both.
    +00104 #endif // dDOUBLE
    +00105 #elif defined(dDOUBLE)
    +00106 typedef double dReal;
    +00107 #else
    +00108 #error You must #define dSINGLE or dDOUBLE
    +00109 #endif
    +00110 
    +00111 // Detect if we've got both trimesh engines enabled.
    +00112 #if dTRIMESH_ENABLED
    +00113 #if dTRIMESH_OPCODE && dTRIMESH_GIMPACT
    +00114 #error You can only #define dTRIMESH_OPCODE or dTRIMESH_GIMPACT, not both.
    +00115 #endif
    +00116 #endif // dTRIMESH_ENABLED
    +00117 
    +00118 /* round an integer up to a multiple of 4, except that 0 and 1 are unmodified
    +00119  * (used to compute matrix leading dimensions)
    +00120  */
    +00121 #define dPAD(a) (((a) > 1) ? ((((a)-1)|3)+1) : (a))
    +00122 
    +00123 /* these types are mainly just used in headers */
    +00124 typedef dReal dVector3[4];
    +00125 typedef dReal dVector4[4];
    +00126 typedef dReal dMatrix3[4*3];
    +00127 typedef dReal dMatrix4[4*4];
    +00128 typedef dReal dMatrix6[8*6];
    +00129 typedef dReal dQuaternion[4];
    +00130 
    +00131 
    +00132 /* precision dependent scalar math functions */
    +00133 
    +00134 #if defined(dSINGLE)
    +00135 
    +00136 #define REAL(x) (x ## f)               /* form a constant */
    +00137 #define dRecip(x) ((1.0f/(x)))            /* reciprocal */
    +00138 #define dSqrt(x) (sqrtf(x))         /* square root */
    +00139 #define dRecipSqrt(x) ((1.0f/sqrtf(x)))      /* reciprocal square root */
    +00140 #define dSin(x) (sinf(x))           /* sine */
    +00141 #define dCos(x) (cosf(x))           /* cosine */
    +00142 #define dFabs(x) (fabsf(x))         /* absolute value */
    +00143 #define dAtan2(y,x) (atan2f(y,x))      /* arc tangent with 2 args */
    +00144 #define dFMod(a,b) (fmodf(a,b))     /* modulo */
    +00145 #define dFloor(x) floorf(x)         /* floor */
    +00146 
    +00147 #ifdef HAVE___ISNANF
    +00148 #define dIsNan(x) (__isnanf(x))
    +00149 #elif defined(HAVE__ISNANF)
    +00150 #define dIsNan(x) (_isnanf(x))
    +00151 #elif defined(HAVE_ISNANF)
    +00152 #define dIsNan(x) (isnanf(x))
    +00153 #else
    +00154   /*
    +00155      fall back to _isnan which is the VC way,
    +00156      this may seem redundant since we already checked
    +00157      for _isnan before, but if isnan is detected by
    +00158      configure but is not found during compilation
    +00159      we should always make sure we check for __isnanf,
    +00160      _isnanf and isnanf in that order before falling
    +00161      back to a default
    +00162   */
    +00163 #define dIsNan(x) (_isnan(x))
    +00164 #endif
    +00165 
    +00166 #define dCopySign(a,b) ((dReal)copysignf(a,b))
    +00167 
    +00168 #elif defined(dDOUBLE)
    +00169 
    +00170 #define REAL(x) (x)
    +00171 #define dRecip(x) (1.0/(x))
    +00172 #define dSqrt(x) sqrt(x)
    +00173 #define dRecipSqrt(x) (1.0/sqrt(x))
    +00174 #define dSin(x) sin(x)
    +00175 #define dCos(x) cos(x)
    +00176 #define dFabs(x) fabs(x)
    +00177 #define dAtan2(y,x) atan2((y),(x))
    +00178 #define dFMod(a,b) (fmod((a),(b)))
    +00179 #define dFloor(x) floor(x)
    +00180 
    +00181 #ifdef HAVE___ISNAN
    +00182 #define dIsNan(x) (__isnan(x))
    +00183 #elif defined(HAVE__ISNAN)
    +00184 #define dIsNan(x) (_isnan(x))
    +00185 #elif defined(HAVE_ISNAN)
    +00186 #define dIsNan(x) (isnan(x))
    +00187 #else
    +00188 #define dIsNan(x) (_isnan(x))
    +00189 #endif
    +00190 
    +00191 #define dCopySign(a,b) (copysign((a),(b)))
    +00192 
    +00193 #else
    +00194 #error You must #define dSINGLE or dDOUBLE
    +00195 #endif
    +00196 
    +00197 
    +00198 /* utility */
    +00199 
    +00200 
    +00201 /* round something up to be a multiple of the EFFICIENT_ALIGNMENT */
    +00202 
    +00203 #define dEFFICIENT_SIZE(x) ((((x)-1)|(EFFICIENT_ALIGNMENT-1))+1)
    +00204 
    +00205 
    +00206 /* alloca aligned to the EFFICIENT_ALIGNMENT. note that this can waste
    +00207  * up to 15 bytes per allocation, depending on what alloca() returns.
    +00208  */
    +00209 
    +00210 #define dALLOCA16(n) \
    +00211   ((char*)dEFFICIENT_SIZE(((size_t)(alloca((n)+(EFFICIENT_ALIGNMENT-1))))))
    +00212 
    +00213 
    +00214 // Use the error-checking memory allocation system.  Because this system uses heap
    +00215 //  (malloc) instead of stack (alloca), it is slower.  However, it allows you to
    +00216 //  simulate larger scenes, as well as handle out-of-memory errors in a somewhat
    +00217 //  graceful manner
    +00218 
    +00219 // #define dUSE_MALLOC_FOR_ALLOCA
    +00220 
    +00221 #ifdef dUSE_MALLOC_FOR_ALLOCA
    +00222 enum {
    +00223   d_MEMORY_OK = 0,      /* no memory errors */
    +00224   d_MEMORY_OUT_OF_MEMORY   /* malloc failed due to out of memory error */
    +00225 };
    +00226 
    +00227 #endif
    +00228 
    +00229 
    +00230 
    +00231 /* internal object types (all prefixed with `dx') */
    +00232 
    +00233 struct dxWorld;      /* dynamics world */
    +00234 struct dxSpace;      /* collision space */
    +00235 struct dxBody;    /* rigid body (dynamics object) */
    +00236 struct dxGeom;    /* geometry (collision object) */
    +00237 struct dxJoint;
    +00238 struct dxJointNode;
    +00239 struct dxJointGroup;
    +00240 
    +00241 typedef struct dxWorld *dWorldID;
    +00242 typedef struct dxSpace *dSpaceID;
    +00243 typedef struct dxBody *dBodyID;
    +00244 typedef struct dxGeom *dGeomID;
    +00245 typedef struct dxJoint *dJointID;
    +00246 typedef struct dxJointGroup *dJointGroupID;
    +00247 
    +00248 
    +00249 /* error numbers */
    +00250 
    +00251 enum {
    +00252   d_ERR_UNKNOWN = 0,    /* unknown error */
    +00253   d_ERR_IASSERT,     /* internal assertion failed */
    +00254   d_ERR_UASSERT,     /* user assertion failed */
    +00255   d_ERR_LCP       /* user assertion failed */
    +00256 };
    +00257 
    +00258 
    +00259 /* joint type numbers */
    +00260 
    +00261 enum {
    +00262   dJointTypeNone = 0,      /* or "unknown" */
    +00263   dJointTypeBall,
    +00264   dJointTypeHinge,
    +00265   dJointTypeSlider,
    +00266   dJointTypeContact,
    +00267   dJointTypeUniversal,
    +00268   dJointTypeHinge2,
    +00269   dJointTypeFixed,
    +00270   dJointTypeNull,
    +00271   dJointTypeAMotor,
    +00272   dJointTypeLMotor,
    +00273   dJointTypePlane2D,
    +00274   dJointTypePR
    +00275 };
    +00276 
    +00277 
    +00278 /* an alternative way of setting joint parameters, using joint parameter
    +00279  * structures and member constants. we don't actually do this yet.
    +00280  */
    +00281 
    +00282 /*
    +00283 typedef struct dLimot {
    +00284   int mode;
    +00285   dReal lostop, histop;
    +00286   dReal vel, fmax;
    +00287   dReal fudge_factor;
    +00288   dReal bounce, soft;
    +00289   dReal suspension_erp, suspension_cfm;
    +00290 } dLimot;
    +00291 
    +00292 enum {
    +00293   dLimotLoStop    = 0x0001,
    +00294   dLimotHiStop    = 0x0002,
    +00295   dLimotVel    = 0x0004,
    +00296   dLimotFMax      = 0x0008,
    +00297   dLimotFudgeFactor  = 0x0010,
    +00298   dLimotBounce    = 0x0020,
    +00299   dLimotSoft      = 0x0040
    +00300 };
    +00301 */
    +00302 
    +00303 
    +00304 /* standard joint parameter names. why are these here? - because we don't want
    +00305  * to include all the joint function definitions in joint.cpp. hmmmm.
    +00306  * MSVC complains if we call D_ALL_PARAM_NAMES_X with a blank second argument,
    +00307  * which is why we have the D_ALL_PARAM_NAMES macro as well. please copy and
    +00308  * paste between these two.
    +00309  */
    +00310 
    +00311 #define D_ALL_PARAM_NAMES(start) \
    +00312   /* parameters for limits and motors */ \
    +00313   dParamLoStop = start, \
    +00314   dParamHiStop, \
    +00315   dParamVel, \
    +00316   dParamFMax, \
    +00317   dParamFudgeFactor, \
    +00318   dParamBounce, \
    +00319   dParamCFM, \
    +00320   dParamStopERP, \
    +00321   dParamStopCFM, \
    +00322   /* parameters for suspension */ \
    +00323   dParamSuspensionERP, \
    +00324   dParamSuspensionCFM, \
    +00325   dParamERP, \
    +00326 
    +00327 #define D_ALL_PARAM_NAMES_X(start,x) \
    +00328   /* parameters for limits and motors */ \
    +00329   dParamLoStop ## x = start, \
    +00330   dParamHiStop ## x, \
    +00331   dParamVel ## x, \
    +00332   dParamFMax ## x, \
    +00333   dParamFudgeFactor ## x, \
    +00334   dParamBounce ## x, \
    +00335   dParamCFM ## x, \
    +00336   dParamStopERP ## x, \
    +00337   dParamStopCFM ## x, \
    +00338   /* parameters for suspension */ \
    +00339   dParamSuspensionERP ## x, \
    +00340   dParamSuspensionCFM ## x, \
    +00341   dParamERP ## x,
    +00342 
    +00343 enum {
    +00344   D_ALL_PARAM_NAMES(0)
    +00345   D_ALL_PARAM_NAMES_X(0x100,2)
    +00346   D_ALL_PARAM_NAMES_X(0x200,3)
    +00347 
    +00348   /* add a multiple of this constant to the basic parameter numbers to get
    +00349    * the parameters for the second, third etc axes.
    +00350    */
    +00351   dParamGroup=0x100
    +00352 };
    +00353 
    +00354 
    +00355 /* angular motor mode numbers */
    +00356 
    +00357 enum{
    +00358   dAMotorUser = 0,
    +00359   dAMotorEuler = 1
    +00360 };
    +00361 
    +00362 
    +00363 /* joint force feedback information */
    +00364 
    +00365 typedef struct dJointFeedback {
    +00366   dVector3 f1;    /* force applied to body 1 */
    +00367   dVector3 t1;    /* torque applied to body 1 */
    +00368   dVector3 f2;    /* force applied to body 2 */
    +00369   dVector3 t2;    /* torque applied to body 2 */
    +00370 } dJointFeedback;
    +00371 
    +00372 
    +00373 /* private functions that must be implemented by the collision library:
    +00374  * (1) indicate that a geom has moved, (2) get the next geom in a body list.
    +00375  * these functions are called whenever the position of geoms connected to a
    +00376  * body have changed, e.g. with dBodySetPosition(), dBodySetRotation(), or
    +00377  * when the ODE step function updates the body state.
    +00378  */
    +00379 
    +00380 void dGeomMoved (dGeomID);
    +00381 dGeomID dGeomGetBodyNext (dGeomID);
    +00382 
    +00383 
    +00384 #ifdef __cplusplus
    +00385 }
    +00386 #endif
    +00387 
    +00388 #endif
    +

    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/compatibility_8h-source.html b/libraries/ode-0.9/docs/compatibility_8h-source.html new file mode 100644 index 0000000000..859554b7fd --- /dev/null +++ b/libraries/ode-0.9/docs/compatibility_8h-source.html @@ -0,0 +1,60 @@ + + +Open Dynamics Engine: compatibility.h Source File + + + + + +

    compatibility.h

    00001 /*************************************************************************
    +00002  *                                                                       *
    +00003  * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
    +00004  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
    +00005  *                                                                       *
    +00006  * This library is free software; you can redistribute it and/or         *
    +00007  * modify it under the terms of EITHER:                                  *
    +00008  *   (1) The GNU Lesser General Public License as published by the Free  *
    +00009  *       Software Foundation; either version 2.1 of the License, or (at  *
    +00010  *       your option) any later version. The text of the GNU Lesser      *
    +00011  *       General Public License is included with this library in the     *
    +00012  *       file LICENSE.TXT.                                               *
    +00013  *   (2) The BSD-style license that is included with this library in     *
    +00014  *       the file LICENSE-BSD.TXT.                                       *
    +00015  *                                                                       *
    +00016  * This library is distributed in the hope that it will be useful,       *
    +00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
    +00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
    +00019  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
    +00020  *                                                                       *
    +00021  *************************************************************************/
    +00022 
    +00023 #ifndef _ODE_COMPATIBILITY_H_
    +00024 #define _ODE_COMPATIBILITY_H_
    +00025 
    +00026 /*
    +00027  * ODE's backward compatibility system ensures that as ODE's API
    +00028  * evolves, user code will not break.
    +00029  */
    +00030 
    +00031 /*
    +00032  * These new rotation function names are more consistent with the
    +00033  * rest of the API.
    +00034  */
    +00035 #define dQtoR(q,R) dRfromQ((R),(q))
    +00036 #define dRtoQ(R,q) dQfromR((q),(R))
    +00037 #define dWtoDQ(w,q,dq) dDQfromW((dq),(w),(q))
    +00038 
    +00039 
    +00040 #endif
    +

    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/config_8h-source.html b/libraries/ode-0.9/docs/config_8h-source.html new file mode 100644 index 0000000000..28440634cb --- /dev/null +++ b/libraries/ode-0.9/docs/config_8h-source.html @@ -0,0 +1,196 @@ + + +Open Dynamics Engine: config.h Source File + + + + + +

    config.h

    00001 /* This file was autogenerated by Premake */
    +00002 #ifndef _ODE_CONFIG_H_
    +00003 #define _ODE_CONFIG_H_
    +00004 
    +00005 
    +00006 /******************************************************************
    +00007  * CONFIGURATON SETTINGS - you can change these, and then rebuild
    +00008  *   ODE to modify the behavior of the library.
    +00009  *
    +00010  *   dSINGLE/dDOUBLE   - force ODE to use single-precision (float)
    +00011  *                       or double-precision (double) for numbers.
    +00012  *                       Only one should be defined.
    +00013  *
    +00014  *   dTRIMESH_ENABLED  - enable/disable trimesh support
    +00015  *   dTRIMESH_OPCODE   - use the OPCODE trimesh engine
    +00016  *   dTRIMESH_GIMPACT  - use the GIMPACT trimesh engine
    +00017  *                       Only one trimesh engine should be enabled.
    +00018  *
    +00019  *   dUSE_MALLOC_FOR_ALLOCA (experimental)-
    +00020  *                       Use malloc() instead of alloca(). Slower,
    +00021  *                       but allows for larger systems and more
    +00022  *                       graceful out-of-memory handling.
    +00023  *
    +00024  *   dTRIMESH_OPCODE_USE_NEW_TRIMESH_TRIMESH_COLLIDER (experimental)-
    +00025  *                       Use an alternative trimesh-trimesh collider
    +00026  *                       which should yield better results.
    +00027  *
    +00028  ******************************************************************/
    +00029 
    +00030 #define dSINGLE
    +00031 /* #define dDOUBLE */
    +00032 
    +00033 #define dTRIMESH_ENABLED 1
    +00034 #define dTRIMESH_OPCODE 1
    +00035 
    +00036 #define dTRIMESH_OPCODE_USE_NEW_TRIMESH_TRIMESH_COLLIDER 0
    +00037 
    +00038 /* #define dUSE_MALLOC_FOR_ALLOCA */
    +00039 
    +00040 
    +00041 /******************************************************************
    +00042  * SYSTEM SETTINGS - you shouldn't need to change these. If you
    +00043  *   run into an issue with these settings, please report it to
    +00044  *   the ODE bug tracker at:
    +00045  *      http://sf.net/tracker/?group_id=24884&atid=382799
    +00046  ******************************************************************/
    +00047 
    +00048 /* Try to identify the platform */
    +00049 #if defined(_XENON)
    +00050   #define ODE_PLATFORM_XBOX360
    +00051 #elif defined(SN_TARGET_PSP_HW)
    +00052   #define ODE_PLATFORM_PSP
    +00053 #elif defined(SN_TARGET_PS3)
    +00054   #define ODE_PLATFORM_PS3
    +00055 #elif defined(_MSC_VER) || defined(__CYGWIN32__) || defined(__MINGW32__)
    +00056   #define ODE_PLATFORM_WINDOWS
    +00057 #elif defined(__linux__)
    +00058   #define ODE_PLATFORM_LINUX
    +00059 #elif defined(__APPLE__) && defined(__MACH__)
    +00060   #define ODE_PLATFORM_OSX
    +00061 #else
    +00062   #error "Need some help identifying the platform!"
    +00063 #endif
    +00064 
    +00065 /* Additional platform defines used in the code */
    +00066 #if defined(ODE_PLATFORM_WINDOWS) && !defined(WIN32)
    +00067   #define WIN32
    +00068 #endif
    +00069 
    +00070 #if defined(__CYGWIN32__) || defined(__MINGW32__)
    +00071   #define CYGWIN
    +00072 #endif
    +00073 
    +00074 #if defined(ODE_PLATFORM_OSX)
    +00075   #define macintosh
    +00076 #endif
    +00077 
    +00078 
    +00079 /* Define a DLL export symbol for those platforms that need it */
    +00080 #if defined(ODE_PLATFORM_WINDOWS)
    +00081   #if defined(ODE_DLL)
    +00082     #define ODE_API __declspec(dllexport)
    +00083   #elif !defined(ODE_LIB)
    +00084     #define ODE_DLL_API __declspec(dllimport)
    +00085   #endif
    +00086 #endif
    +00087 
    +00088 #if !defined(ODE_API)
    +00089   #define ODE_API
    +00090 #endif
    +00091 
    +00092 
    +00093 /* Pull in the standard headers */
    +00094 #include <stdio.h>
    +00095 #include <stdlib.h>
    +00096 #include <stdarg.h>
    +00097 #include <math.h>
    +00098 #include <string.h>
    +00099 #include <float.h>
    +00100 
    +00101 #if !defined(ODE_PLATFORM_PS3)
    +00102   #include <malloc.h>
    +00103 #endif
    +00104 
    +00105 #if !defined(ODE_PLATFORM_WINDOWS)
    +00106   #include <alloca.h>
    +00107 #endif
    +00108 
    +00109 
    +00110 /* Visual C does not define these functions */
    +00111 #if defined(_MSC_VER)
    +00112   #define copysignf _copysign
    +00113   #define copysign _copysign
    +00114 #endif
    +00115 
    +00116 
    +00117 /* Define a value for infinity */
    +00118 #if defined(HUGE_VALF)
    +00119    #define ODE_INFINITY4 HUGE_VALF
    +00120    #define ODE_INFINITY8 HUGE_VAL
    +00121 #elif defined(FLT_MAX)
    +00122    #define ODE_INFINITY4 FLT_MAX
    +00123    #define ODE_INFINITY8 DBL_MAX
    +00124 #else
    +00125    static union { unsigned char __c[4]; float  __f; }  __ode_huge_valf = {{0,0,0x80,0x7f}};
    +00126    static union { unsigned char __c[8]; double __d; }  __ode_huge_val  = {{0,0,0,0,0,0,0xf0,0x7f}};
    +00127    #define ODE_INFINITY4 (__ode_huge_valf.__f)
    +00128    #define ODE_INFINITY8 (__ode_huge_val.__d)
    +00129 #endif
    +00130 
    +00131 #ifdef dSINGLE
    +00132    #define dInfinity ODE_INFINITY4
    +00133    #define dEpsilon  FLT_EPSILON
    +00134 #else
    +00135    #define dInfinity ODE_INFINITY8
    +00136    #define dEpsilon  DBL_EPSILON
    +00137 #endif
    +00138 
    +00139 
    +00140 /* Well-defined common data types...need to define for 64 bit systems */
    +00141 #if defined(_M_IA64) || defined(__ia64__) || defined(_M_AMD64) || defined(__x86_64__)
    +00142   #define X86_64_SYSTEM   1
    +00143   typedef int             int32;
    +00144   typedef unsigned int    uint32;
    +00145   typedef short           int16;
    +00146   typedef unsigned short  uint16;
    +00147   typedef char            int8;
    +00148   typedef unsigned char   uint8;
    +00149 #else
    +00150   typedef int             int32;
    +00151   typedef unsigned int    uint32;
    +00152   typedef short           int16;
    +00153   typedef unsigned short  uint16;
    +00154   typedef char            int8;
    +00155   typedef unsigned char   uint8;
    +00156 #endif
    +00157 
    +00158 /* An integer type that can be safely cast to a pointer. This definition
    +00159  * should be safe even on 64-bit systems */
    +00160 typedef size_t intP;
    +00161 
    +00162 
    +00163 /* The efficient alignment. most platforms align data structures to some
    +00164  * number of bytes, but this is not always the most efficient alignment.
    +00165  * for example, many x86 compilers align to 4 bytes, but on a pentium it is
    +00166  * important to align doubles to 8 byte boundaries (for speed), and the 4
    +00167  * floats in a SIMD register to 16 byte boundaries. many other platforms have
    +00168  * similar behavior. setting a larger alignment can waste a (very) small
    +00169  * amount of memory. NOTE: this number must be a power of two. */
    +00170 #define EFFICIENT_ALIGNMENT 16
    +00171 
    +00172 
    +00173 /* Define this if your system supports anonymous memory maps (linux does) */
    +00174 #define MMAP_ANONYMOUS
    +00175 
    +00176 #endif
    +

    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/contact_8h-source.html b/libraries/ode-0.9/docs/contact_8h-source.html new file mode 100644 index 0000000000..0339e51b8a --- /dev/null +++ b/libraries/ode-0.9/docs/contact_8h-source.html @@ -0,0 +1,109 @@ + + +Open Dynamics Engine: contact.h Source File + + + + + +

    contact.h

    00001 /*************************************************************************
    +00002  *                                                                       *
    +00003  * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
    +00004  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
    +00005  *                                                                       *
    +00006  * This library is free software; you can redistribute it and/or         *
    +00007  * modify it under the terms of EITHER:                                  *
    +00008  *   (1) The GNU Lesser General Public License as published by the Free  *
    +00009  *       Software Foundation; either version 2.1 of the License, or (at  *
    +00010  *       your option) any later version. The text of the GNU Lesser      *
    +00011  *       General Public License is included with this library in the     *
    +00012  *       file LICENSE.TXT.                                               *
    +00013  *   (2) The BSD-style license that is included with this library in     *
    +00014  *       the file LICENSE-BSD.TXT.                                       *
    +00015  *                                                                       *
    +00016  * This library is distributed in the hope that it will be useful,       *
    +00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
    +00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
    +00019  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
    +00020  *                                                                       *
    +00021  *************************************************************************/
    +00022 
    +00023 #ifndef _ODE_CONTACT_H_
    +00024 #define _ODE_CONTACT_H_
    +00025 
    +00026 #include <ode/common.h>
    +00027 
    +00028 #ifdef __cplusplus
    +00029 extern "C" {
    +00030 #endif
    +00031 
    +00032 
    +00033 enum {
    +00034   dContactMu2     = 0x001,
    +00035   dContactFDir1      = 0x002,
    +00036   dContactBounce  = 0x004,
    +00037   dContactSoftERP = 0x008,
    +00038   dContactSoftCFM = 0x010,
    +00039   dContactMotion1 = 0x020,
    +00040   dContactMotion2 = 0x040,
    +00041   dContactSlip1      = 0x080,
    +00042   dContactSlip2      = 0x100,
    +00043 
    +00044   dContactApprox0 = 0x0000,
    +00045   dContactApprox1_1  = 0x1000,
    +00046   dContactApprox1_2  = 0x2000,
    +00047   dContactApprox1 = 0x3000
    +00048 };
    +00049 
    +00050 
    +00051 typedef struct dSurfaceParameters {
    +00052   /* must always be defined */
    +00053   int mode;
    +00054   dReal mu;
    +00055 
    +00056   /* only defined if the corresponding flag is set in mode */
    +00057   dReal mu2;
    +00058   dReal bounce;
    +00059   dReal bounce_vel;
    +00060   dReal soft_erp;
    +00061   dReal soft_cfm;
    +00062   dReal motion1,motion2;
    +00063   dReal slip1,slip2;
    +00064 } dSurfaceParameters;
    +00065 
    +00066 
    +00081 typedef struct dContactGeom {
    +00082   dVector3 pos;          
    +00083   dVector3 normal;       
    +00084   dReal depth;           
    +00085   dGeomID g1,g2;         
    +00086   int side1,side2;       
    +00087 } dContactGeom;
    +00088 
    +00089 
    +00090 /* contact info used by contact joint */
    +00091 
    +00092 typedef struct dContact {
    +00093   dSurfaceParameters surface;
    +00094   dContactGeom geom;
    +00095   dVector3 fdir1;
    +00096 } dContact;
    +00097 
    +00098 
    +00099 #ifdef __cplusplus
    +00100 }
    +00101 #endif
    +00102 
    +00103 #endif
    +

    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/doxygen.css b/libraries/ode-0.9/docs/doxygen.css new file mode 100644 index 0000000000..c7db1a8a04 --- /dev/null +++ b/libraries/ode-0.9/docs/doxygen.css @@ -0,0 +1,358 @@ +BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { + font-family: Geneva, Arial, Helvetica, sans-serif; +} +BODY,TD { + font-size: 90%; +} +H1 { + text-align: center; + font-size: 160%; +} +H2 { + font-size: 120%; +} +H3 { + font-size: 100%; +} +CAPTION { font-weight: bold } +DIV.qindex { + width: 100%; + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; +} +DIV.nav { + width: 100%; + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; +} +DIV.navtab { + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} +TD.navtab { + font-size: 70%; +} +A.qindex { + text-decoration: none; + font-weight: bold; + color: #1A419D; +} +A.qindex:visited { + text-decoration: none; + font-weight: bold; + color: #1A419D +} +A.qindex:hover { + text-decoration: none; + background-color: #ddddff; +} +A.qindexHL { + text-decoration: none; + font-weight: bold; + background-color: #6666cc; + color: #ffffff; + border: 1px double #9295C2; +} +A.qindexHL:hover { + text-decoration: none; + background-color: #6666cc; + color: #ffffff; +} +A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff } +A.el { text-decoration: none; font-weight: bold } +A.elRef { font-weight: bold } +A.code:link { text-decoration: none; font-weight: normal; color: #0000FF} +A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF} +A.codeRef:link { font-weight: normal; color: #0000FF} +A.codeRef:visited { font-weight: normal; color: #0000FF} +A:hover { text-decoration: none; background-color: #f2f2ff } +DL.el { margin-left: -1cm } +.fragment { + font-family: monospace, fixed; + font-size: 95%; +} +PRE.fragment { + border: 1px solid #CCCCCC; + background-color: #f5f5f5; + margin-top: 4px; + margin-bottom: 4px; + margin-left: 2px; + margin-right: 8px; + padding-left: 6px; + padding-right: 6px; + padding-top: 4px; + padding-bottom: 4px; +} +DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } + +DIV.groupHeader { + margin-left: 16px; + margin-top: 12px; + margin-bottom: 6px; + font-weight: bold; +} +DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% } +BODY { + background: white; + color: black; + margin-right: 20px; + margin-left: 20px; +} +TD.indexkey { + background-color: #e8eef2; + font-weight: bold; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; +} +TD.indexvalue { + background-color: #e8eef2; + font-style: italic; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; +} +TR.memlist { + background-color: #f0f0f0; +} +P.formulaDsp { text-align: center; } +IMG.formulaDsp { } +IMG.formulaInl { vertical-align: middle; } +SPAN.keyword { color: #008000 } +SPAN.keywordtype { color: #604020 } +SPAN.keywordflow { color: #e08000 } +SPAN.comment { color: #800000 } +SPAN.preprocessor { color: #806020 } +SPAN.stringliteral { color: #002080 } +SPAN.charliteral { color: #008080 } +.mdescLeft { + padding: 0px 8px 4px 8px; + font-size: 80%; + font-style: italic; + background-color: #FAFAFA; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.mdescRight { + padding: 0px 8px 4px 8px; + font-size: 80%; + font-style: italic; + background-color: #FAFAFA; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.memItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memItemRight { + padding: 1px 8px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: none; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplItemRight { + padding: 1px 8px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: none; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplParams { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + color: #606060; + background-color: #FAFAFA; + font-size: 80%; +} +.search { color: #003399; + font-weight: bold; +} +FORM.search { + margin-bottom: 0px; + margin-top: 0px; +} +INPUT.search { font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +TD.tiny { font-size: 75%; +} +a { + color: #1A41A8; +} +a:visited { + color: #2A3798; +} +.dirtab { padding: 4px; + border-collapse: collapse; + border: 1px solid #84b0c7; +} +TH.dirtab { background: #e8eef2; + font-weight: bold; +} +HR { height: 1px; + border: none; + border-top: 1px solid black; +} + +/* Style for detailed member documentation */ +.memtemplate { + font-size: 80%; + color: #606060; + font-weight: normal; +} +.memnav { + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} +.memitem { + padding: 4px; + background-color: #eef3f5; + border-width: 1px; + border-style: solid; + border-color: #dedeee; + -moz-border-radius: 8px 8px 8px 8px; +} +.memname { + white-space: nowrap; + font-weight: bold; +} +.memdoc{ + padding-left: 10px; +} +.memproto { + background-color: #d5e1e8; + width: 100%; + border-width: 1px; + border-style: solid; + border-color: #84b0c7; + font-weight: bold; + -moz-border-radius: 8px 8px 8px 8px; +} +.paramkey { + text-align: right; +} +.paramtype { + white-space: nowrap; +} +.paramname { + color: #602020; + font-style: italic; + white-space: nowrap; +} +/* End Styling for detailed member documentation */ + +/* for the tree view */ +.ftvtree { + font-family: sans-serif; + margin:0.5em; +} +.directory { font-size: 9pt; font-weight: bold; } +.directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } +.directory > h3 { margin-top: 0; } +.directory p { margin: 0px; white-space: nowrap; } +.directory div { display: none; margin: 0px; } +.directory img { vertical-align: -30%; } diff --git a/libraries/ode-0.9/docs/doxygen.png b/libraries/ode-0.9/docs/doxygen.png new file mode 100644 index 0000000000..f0a274bbaf Binary files /dev/null and b/libraries/ode-0.9/docs/doxygen.png differ diff --git a/libraries/ode-0.9/docs/drawstuff_8h-source.html b/libraries/ode-0.9/docs/drawstuff_8h-source.html new file mode 100644 index 0000000000..e08e6c279f --- /dev/null +++ b/libraries/ode-0.9/docs/drawstuff_8h-source.html @@ -0,0 +1,166 @@ + + +Open Dynamics Engine: drawstuff.h Source File + + + + + +

    drawstuff.h

    00001 /*************************************************************************
    +00002  *                                                                       *
    +00003  * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith.       *
    +00004  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
    +00005  *                                                                       *
    +00006  * This library is free software; you can redistribute it and/or         *
    +00007  * modify it under the terms of EITHER:                                  *
    +00008  *   (1) The GNU Lesser General Public License as published by the Free  *
    +00009  *       Software Foundation; either version 2.1 of the License, or (at  *
    +00010  *       your option) any later version. The text of the GNU Lesser      *
    +00011  *       General Public License is included with this library in the     *
    +00012  *       file LICENSE.TXT.                                               *
    +00013  *   (2) The BSD-style license that is included with this library in     *
    +00014  *       the file LICENSE-BSD.TXT.                                       *
    +00015  *                                                                       *
    +00016  * This library is distributed in the hope that it will be useful,       *
    +00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
    +00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
    +00019  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
    +00020  *                                                                       *
    +00021  *************************************************************************/
    +00022 
    +00041 #ifndef __DRAWSTUFF_H__
    +00042 #define __DRAWSTUFF_H__
    +00043 
    +00044 /* Define a DLL export symbol for those platforms that need it */
    +00045 #if defined(ODE_PLATFORM_WINDOWS)
    +00046   #if defined(DS_DLL)
    +00047     #define DS_API __declspec(dllexport)
    +00048   #elif !defined(DS_LIB)
    +00049     #define DS_DLL_API __declspec(dllimport)
    +00050   #endif
    +00051 #endif
    +00052     
    +00053 #if !defined(DS_API)
    +00054   #define DS_API
    +00055 #endif
    +00056 
    +00057 #ifdef __cplusplus
    +00058 extern "C" {
    +00059 #endif
    +00060 
    +00061 
    +00062 #include <drawstuff/version.h>
    +00063 
    +00064 
    +00065 /* texture numbers */
    +00066 #define DS_NONE   0  /* uses the current color instead of a texture */
    +00067 #define DS_WOOD   1
    +00068 
    +00069 
    +00075 typedef struct dsFunctions {
    +00076   int version;       /* put DS_VERSION here */
    +00077   /* version 1 data */
    +00078   void (*start)();      /* called before sim loop starts */
    +00079   void (*step) (int pause);   /* called before every frame */
    +00080   void (*command) (int cmd);  /* called if a command key is pressed */
    +00081   void (*stop)();    /* called after sim loop exits */
    +00082   /* version 2 data */
    +00083   char *path_to_textures;  /* if nonzero, path to texture files */
    +00084 } dsFunctions;
    +00085 
    +00086 
    +00095 DS_API void dsSimulationLoop (int argc, char **argv,
    +00096              int window_width, int window_height,
    +00097              struct dsFunctions *fn);
    +00098 
    +00105 DS_API void dsError (char *msg, ...);
    +00106 
    +00113 DS_API void dsDebug (char *msg, ...);
    +00114 
    +00120 DS_API void dsPrint (char *msg, ...);
    +00121 
    +00130 DS_API void dsSetViewpoint (float xyz[3], float hpr[3]);
    +00131 
    +00132 
    +00139 DS_API void dsGetViewpoint (float xyz[3], float hpr[3]);
    +00140 
    +00149 DS_API void dsStop();
    +00150 
    +00156 DS_API double dsElapsedTime();
    +00157 
    +00168 DS_API void dsSetTexture (int texture_number);
    +00169 
    +00177 DS_API void dsSetColor (float red, float green, float blue);
    +00178 
    +00185 DS_API void dsSetColorAlpha (float red, float green, float blue, float alpha);
    +00186 
    +00197 DS_API void dsDrawBox (const float pos[3], const float R[12], const float sides[3]);
    +00198 
    +00206 DS_API void dsDrawSphere (const float pos[3], const float R[12], float radius);
    +00207 
    +00218 DS_API void dsDrawTriangle (const float pos[3], const float R[12],
    +00219            const float *v0, const float *v1, const float *v2, int solid);
    +00220 
    +00225 DS_API void dsDrawCylinder (const float pos[3], const float R[12],
    +00226            float length, float radius);
    +00227 
    +00232 DS_API void dsDrawCapsule (const float pos[3], const float R[12],
    +00233           float length, float radius);
    +00234 
    +00239 DS_API void dsDrawLine (const float pos1[3], const float pos2[3]);
    +00240 
    +00245 DS_API void dsDrawConvex(const float pos[3], const float R[12],
    +00246         float *_planes,
    +00247         unsigned int _planecount,
    +00248         float *_points,
    +00249         unsigned int _pointcount,
    +00250         unsigned int *_polygons);
    +00251 
    +00252  /* these drawing functions are identical to the ones above, except they take
    +00253  * double arrays for `pos' and `R'.
    +00254  */
    +00255 DS_API void dsDrawBoxD (const double pos[3], const double R[12],
    +00256        const double sides[3]);
    +00257 DS_API void dsDrawSphereD (const double pos[3], const double R[12],
    +00258           const float radius);
    +00259 DS_API void dsDrawTriangleD (const double pos[3], const double R[12],
    +00260             const double *v0, const double *v1, const double *v2, int solid);
    +00261 DS_API void dsDrawCylinderD (const double pos[3], const double R[12],
    +00262             float length, float radius);
    +00263 DS_API void dsDrawCapsuleD (const double pos[3], const double R[12],
    +00264            float length, float radius);
    +00265 DS_API void dsDrawLineD (const double pos1[3], const double pos2[3]);
    +00266 DS_API void dsDrawConvexD(const double pos[3], const double R[12],
    +00267         double *_planes,
    +00268         unsigned int _planecount,
    +00269         double *_points,
    +00270         unsigned int _pointcount,
    +00271         unsigned int *_polygons);
    +00272 
    +00280 DS_API void dsSetSphereQuality (int n);      /* default = 1 */
    +00281 DS_API void dsSetCapsuleQuality (int n);     /* default = 3 */
    +00282 
    +00283 // Backwards compatible API
    +00284 #define dsDrawCappedCylinder dsDrawCapsule
    +00285 #define dsDrawCappedCylinderD dsDrawCapsuleD
    +00286 #define dsSetCappedCylinderQuality dsSetCapsuleQuality
    +00287 
    +00288 /* closing bracket for extern "C" */
    +00289 #ifdef __cplusplus
    +00290 }
    +00291 #endif
    +00292 
    +00293 #endif
    +00294 
    +

    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/error_8h-source.html b/libraries/ode-0.9/docs/error_8h-source.html new file mode 100644 index 0000000000..bb8e44a23c --- /dev/null +++ b/libraries/ode-0.9/docs/error_8h-source.html @@ -0,0 +1,83 @@ + + +Open Dynamics Engine: error.h Source File + + + + + +

    error.h

    00001 /*************************************************************************
    +00002  *                                                                       *
    +00003  * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
    +00004  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
    +00005  *                                                                       *
    +00006  * This library is free software; you can redistribute it and/or         *
    +00007  * modify it under the terms of EITHER:                                  *
    +00008  *   (1) The GNU Lesser General Public License as published by the Free  *
    +00009  *       Software Foundation; either version 2.1 of the License, or (at  *
    +00010  *       your option) any later version. The text of the GNU Lesser      *
    +00011  *       General Public License is included with this library in the     *
    +00012  *       file LICENSE.TXT.                                               *
    +00013  *   (2) The BSD-style license that is included with this library in     *
    +00014  *       the file LICENSE-BSD.TXT.                                       *
    +00015  *                                                                       *
    +00016  * This library is distributed in the hope that it will be useful,       *
    +00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
    +00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
    +00019  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
    +00020  *                                                                       *
    +00021  *************************************************************************/
    +00022 
    +00023 /* this comes from the `reuse' library. copy any changes back to the source */
    +00024 
    +00025 #ifndef _ODE_ERROR_H_
    +00026 #define _ODE_ERROR_H_
    +00027 
    +00028 #include <ode/config.h>
    +00029 
    +00030 #ifdef __cplusplus
    +00031 extern "C" {
    +00032 #endif
    +00033 
    +00034 /* all user defined error functions have this type. error and debug functions
    +00035  * should not return.
    +00036  */
    +00037 typedef void dMessageFunction (int errnum, const char *msg, va_list ap);
    +00038 
    +00039 /* set a new error, debug or warning handler. if fn is 0, the default handlers
    +00040  * are used.
    +00041  */
    +00042 ODE_API void dSetErrorHandler (dMessageFunction *fn);
    +00043 ODE_API void dSetDebugHandler (dMessageFunction *fn);
    +00044 ODE_API void dSetMessageHandler (dMessageFunction *fn);
    +00045 
    +00046 /* return the current error, debug or warning handler. if the return value is
    +00047  * 0, the default handlers are in place.
    +00048  */
    +00049 ODE_API dMessageFunction *dGetErrorHandler(void);
    +00050 ODE_API dMessageFunction *dGetDebugHandler(void);
    +00051 ODE_API dMessageFunction *dGetMessageHandler(void);
    +00052 
    +00053 /* generate a fatal error, debug trap or a message. */
    +00054 ODE_API void dError (int num, const char *msg, ...);
    +00055 ODE_API void dDebug (int num, const char *msg, ...);
    +00056 ODE_API void dMessage (int num, const char *msg, ...);
    +00057 
    +00058 
    +00059 #ifdef __cplusplus
    +00060 }
    +00061 #endif
    +00062 
    +00063 #endif
    +

    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/export-dif_8h-source.html b/libraries/ode-0.9/docs/export-dif_8h-source.html new file mode 100644 index 0000000000..9a5084eb1d --- /dev/null +++ b/libraries/ode-0.9/docs/export-dif_8h-source.html @@ -0,0 +1,52 @@ + + +Open Dynamics Engine: export-dif.h Source File + + + + + +

    export-dif.h

    00001 /*************************************************************************
    +00002  *                                                                       *
    +00003  * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
    +00004  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
    +00005  *                                                                       *
    +00006  * This library is free software; you can redistribute it and/or         *
    +00007  * modify it under the terms of EITHER:                                  *
    +00008  *   (1) The GNU Lesser General Public License as published by the Free  *
    +00009  *       Software Foundation; either version 2.1 of the License, or (at  *
    +00010  *       your option) any later version. The text of the GNU Lesser      *
    +00011  *       General Public License is included with this library in the     *
    +00012  *       file LICENSE.TXT.                                               *
    +00013  *   (2) The BSD-style license that is included with this library in     *
    +00014  *       the file LICENSE-BSD.TXT.                                       *
    +00015  *                                                                       *
    +00016  * This library is distributed in the hope that it will be useful,       *
    +00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
    +00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
    +00019  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
    +00020  *                                                                       *
    +00021  *************************************************************************/
    +00022 
    +00023 #ifndef _ODE_EXPORT_DIF_
    +00024 #define _ODE_EXPORT_DIF_
    +00025 
    +00026 #include <ode/common.h>
    +00027 
    +00028 
    +00029 ODE_API void dWorldExportDIF (dWorldID w, FILE *file, const char *world_name);
    +00030 
    +00031 
    +00032 #endif
    +

    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/files.html b/libraries/ode-0.9/docs/files.html new file mode 100644 index 0000000000..29d3e776a5 --- /dev/null +++ b/libraries/ode-0.9/docs/files.html @@ -0,0 +1,44 @@ + + +Open Dynamics Engine: File Index + + + + + +

    Open Dynamics Engine File List

    Here is a list of all documented files with brief descriptions: + + + + + + + + + + + + + + + + + + + + + + +
    collision.h [code]
    collision_space.h [code]
    collision_trimesh.h [code]
    common.h [code]
    compatibility.h [code]
    config.h [code]
    contact.h [code]
    drawstuff.h [code]
    error.h [code]
    export-dif.h [code]
    mass.h [code]
    matrix.h [code]
    memory.h [code]
    misc.h [code]
    objects.h [code]
    ode.h [code]
    odecpp.h [code]
    odecpp_collision.h [code]
    odemath.h [code]
    rotation.h [code]
    timer.h [code]
    version.h [code]
    +
    Generated on Fri Oct 12 08:36:52 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/functions.html b/libraries/ode-0.9/docs/functions.html new file mode 100644 index 0000000000..0d321d4e86 --- /dev/null +++ b/libraries/ode-0.9/docs/functions.html @@ -0,0 +1,46 @@ + + +Open Dynamics Engine: Data Fields + + + + + + +
    + +
    +Here is a list of all documented struct and union fields with links to the struct/union documentation for each field: +

    +

    +
    Generated on Fri Oct 12 08:36:52 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/functions_vars.html b/libraries/ode-0.9/docs/functions_vars.html new file mode 100644 index 0000000000..2b5702bba3 --- /dev/null +++ b/libraries/ode-0.9/docs/functions_vars.html @@ -0,0 +1,46 @@ + + +Open Dynamics Engine: Data Fields - Variables + + + + + + +
    + +
    +  +

    +

    +
    Generated on Fri Oct 12 08:36:52 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/group__bodies.html b/libraries/ode-0.9/docs/group__bodies.html new file mode 100644 index 0000000000..951ff2bd92 --- /dev/null +++ b/libraries/ode-0.9/docs/group__bodies.html @@ -0,0 +1,1827 @@ + + +Open Dynamics Engine: Rigid Bodies + + + + + +

    Rigid Bodies

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    Functions

    ODE_API dReal dBodyGetAutoDisableLinearThreshold (dBodyID)
     Get auto disable linear average threshold.
    ODE_API void dBodySetAutoDisableLinearThreshold (dBodyID, dReal linear_average_threshold)
     Set auto disable linear average threshold.
    ODE_API dReal dBodyGetAutoDisableAngularThreshold (dBodyID)
     Get auto disable angular average threshold.
    ODE_API void dBodySetAutoDisableAngularThreshold (dBodyID, dReal angular_average_threshold)
     Set auto disable angular average threshold.
    ODE_API int dBodyGetAutoDisableAverageSamplesCount (dBodyID)
     Get auto disable average size (samples count).
    ODE_API void dBodySetAutoDisableAverageSamplesCount (dBodyID, unsigned int average_samples_count)
     Set auto disable average buffer size (average steps).
    ODE_API int dBodyGetAutoDisableSteps (dBodyID)
     Get auto steps a body must be thought of as idle to disable.
    ODE_API void dBodySetAutoDisableSteps (dBodyID, int steps)
     Set auto disable steps.
    ODE_API dReal dBodyGetAutoDisableTime (dBodyID)
     Get auto disable time.
    ODE_API void dBodySetAutoDisableTime (dBodyID, dReal time)
     Set auto disable time.
    ODE_API int dBodyGetAutoDisableFlag (dBodyID)
     Get auto disable flag.
    ODE_API void dBodySetAutoDisableFlag (dBodyID, int do_auto_disable)
     Set auto disable flag.
    ODE_API void dBodySetAutoDisableDefaults (dBodyID)
     Set auto disable defaults.
    ODE_API dWorldID dBodyGetWorld (dBodyID)
     Retrives the world attached to te given body.
    ODE_API dBodyID dBodyCreate (dWorldID)
     Create a body in given world.
    ODE_API void dBodyDestroy (dBodyID)
     Destroy a body.
    ODE_API void dBodySetData (dBodyID, void *data)
     Set the body's user-data pointer.
    ODE_API void * dBodyGetData (dBodyID)
     Get the body's user-data pointer.
    ODE_API void dBodySetPosition (dBodyID, dReal x, dReal y, dReal z)
     Set position of a body.
    ODE_API void dBodySetRotation (dBodyID, const dMatrix3 R)
     Set the orientation of a body.
    ODE_API void dBodySetQuaternion (dBodyID, const dQuaternion q)
     Set the orientation of a body.
    +ODE_API void dBodySetLinearVel (dBodyID, dReal x, dReal y, dReal z)
     Set the linear velocity of a body.
    +ODE_API void dBodySetAngularVel (dBodyID, dReal x, dReal y, dReal z)
     Set the angular velocity of a body.
    ODE_API const dReal * dBodyGetPosition (dBodyID)
     Get the position of a body.
    ODE_API void dBodyCopyPosition (dBodyID body, dVector3 pos)
     Copy the position of a body into a vector.
    ODE_API const dReal * dBodyGetRotation (dBodyID)
     Get the rotation of a body.
    ODE_API void dBodyCopyRotation (dBodyID, dMatrix3 R)
     Copy the rotation of a body.
    ODE_API const dReal * dBodyGetQuaternion (dBodyID)
     Get the rotation of a body.
    ODE_API void dBodyCopyQuaternion (dBodyID body, dQuaternion quat)
     Copy the orientation of a body into a quaternion.
    +ODE_API const dReal * dBodyGetLinearVel (dBodyID)
     Get the linear velocity of a body.
    +ODE_API const dReal * dBodyGetAngularVel (dBodyID)
     Get the angular velocity of a body.
    +ODE_API void dBodySetMass (dBodyID, const dMass *mass)
     Set the mass of a body.
    +ODE_API void dBodyGetMass (dBodyID, dMass *mass)
     Get the mass of a body.
    +ODE_API void dBodyAddForce (dBodyID, dReal fx, dReal fy, dReal fz)
     Add force at centre of mass of body in absolute coordinates.
    +ODE_API void dBodyAddTorque (dBodyID, dReal fx, dReal fy, dReal fz)
     Add torque at centre of mass of body in absolute coordinates.
    +ODE_API void dBodyAddRelForce (dBodyID, dReal fx, dReal fy, dReal fz)
     Add force at centre of mass of body in coordinates relative to body.
    +ODE_API void dBodyAddRelTorque (dBodyID, dReal fx, dReal fy, dReal fz)
     Add torque at centre of mass of body in coordinates relative to body.
    +ODE_API void dBodyAddForceAtPos (dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz)
     Add force at specified point in body in global coordinates.
    +ODE_API void dBodyAddForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz)
     Add force at specified point in body in local coordinates.
    +ODE_API void dBodyAddRelForceAtPos (dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz)
     Add force at specified point in body in global coordinates.
    +ODE_API void dBodyAddRelForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz)
     Add force at specified point in body in local coordinates.
    ODE_API const dReal * dBodyGetForce (dBodyID)
     Return the current accumulated force vector.
    ODE_API const dReal * dBodyGetTorque (dBodyID)
     Return the current accumulated torque vector.
    ODE_API void dBodySetForce (dBodyID b, dReal x, dReal y, dReal z)
     Set the body force accumulation vector.
    ODE_API void dBodySetTorque (dBodyID b, dReal x, dReal y, dReal z)
     Set the body torque accumulation vector.
    ODE_API void dBodyGetRelPointPos (dBodyID, dReal px, dReal py, dReal pz, dVector3 result)
     Get world position of a relative point on body.
    ODE_API void dBodyGetRelPointVel (dBodyID, dReal px, dReal py, dReal pz, dVector3 result)
     Get velocity vector in global coords of a relative point on body.
    ODE_API void dBodyGetPointVel (dBodyID, dReal px, dReal py, dReal pz, dVector3 result)
     Get velocity vector in global coords of a globally specified point on a body.
    ODE_API void dBodyGetPosRelPoint (dBodyID, dReal px, dReal py, dReal pz, dVector3 result)
     takes a point in global coordinates and returns the point's position in body-relative coordinates.
    ODE_API void dBodyVectorToWorld (dBodyID, dReal px, dReal py, dReal pz, dVector3 result)
     Convert from local to world coordinates.
    ODE_API void dBodyVectorFromWorld (dBodyID, dReal px, dReal py, dReal pz, dVector3 result)
     Convert from world to local coordinates.
    ODE_API void dBodySetFiniteRotationMode (dBodyID, int mode)
     controls the way a body's orientation is updated at each timestep.
    ODE_API void dBodySetFiniteRotationAxis (dBodyID, dReal x, dReal y, dReal z)
     sets the finite rotation axis for a body.
    ODE_API int dBodyGetFiniteRotationMode (dBodyID)
     Get the way a body's orientation is updated each timestep.
    ODE_API void dBodyGetFiniteRotationAxis (dBodyID, dVector3 result)
     Get the finite rotation axis.
    ODE_API int dBodyGetNumJoints (dBodyID b)
     Get the number of joints that are attached to this body.
    ODE_API dJointID dBodyGetJoint (dBodyID, int index)
     Return a joint attached to this body, given by index.
    ODE_API void dBodyEnable (dBodyID)
     Manually enable a body.
    ODE_API void dBodyDisable (dBodyID)
     Manually disable a body.
    ODE_API int dBodyIsEnabled (dBodyID)
     Check wether a body is enabled.
    ODE_API void dBodySetGravityMode (dBodyID b, int mode)
     Set whether the body is influenced by the world's gravity or not.
    ODE_API int dBodyGetGravityMode (dBodyID b)
     Get whether the body is influenced by the world's gravity or not.
    +

    Detailed Description

    +A rigid body has various properties from the point of view of the simulation. Some properties change over time:

    +

      +
    • 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.
    • +
    • Linear velocity of the point of reference, a vector (vx,vy,vz).
    • +
    • Orientation of a body, represented by a quaternion (qs,qx,qy,qz) or a 3x3 rotation matrix.
    • +
    • Angular velocity vector (wx,wy,wz) which describes how the orientation changes over time.
    • +
    +Other body properties are usually constant over time:

    +

      +
    • Mass of the body.
    • +
    • 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.
    • +
    • 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.


    Function Documentation

    + +
    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dBodyCopyPosition (dBodyID  body,
    dVector3  pos 
    )
    +
    +
    + +

    +Copy the position of a body into a vector. +

    +

    Parameters:
    + + + +
    body the body to query
    pos a copy of the body position
    +
    +
    See also:
    dBodyGetPosition
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dBodyCopyQuaternion (dBodyID  body,
    dQuaternion  quat 
    )
    +
    +
    + +

    +Copy the orientation of a body into a quaternion. +

    +

    Parameters:
    + + + +
    body the body to query
    quat a copy of the orientation quaternion
    +
    +
    See also:
    dBodyGetQuaternion
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dBodyCopyRotation (dBodyID ,
    dMatrix3  R 
    )
    +
    +
    + +

    +Copy the rotation of a body. +

    +

    Parameters:
    + + + +
    body the body to query
    R a copy of the rotation matrix
    +
    +
    See also:
    dBodyGetRotation
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API dBodyID dBodyCreate (dWorldID   ) 
    +
    +
    + +

    +Create a body in given world. +

    +

    Remarks:
    Default mass parameters are at position (0,0,0).
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API void dBodyDestroy (dBodyID   ) 
    +
    +
    + +

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

    + +

    +
    + + + + + + + + + +
    ODE_API void dBodyDisable (dBodyID   ) 
    +
    +
    + +

    +Manually disable a body. +

    +

    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 dBodyEnable (dBodyID   ) 
    +
    +
    + +

    +Manually enable a body. +

    +

    Parameters:
    + + +
    dBodyID identification of body.
    +
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API dReal dBodyGetAutoDisableAngularThreshold (dBodyID   ) 
    +
    +
    + +

    +Get auto disable angular average threshold. +

    +

    Returns:
    the threshold
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API int dBodyGetAutoDisableAverageSamplesCount (dBodyID   ) 
    +
    +
    + +

    +Get auto disable average size (samples count). +

    +

    Returns:
    the nr of steps/size.
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API int dBodyGetAutoDisableFlag (dBodyID   ) 
    +
    +
    + +

    +Get auto disable flag. +

    +

    Returns:
    0 or 1
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API dReal dBodyGetAutoDisableLinearThreshold (dBodyID   ) 
    +
    +
    + +

    +Get auto disable linear average threshold. +

    +

    Returns:
    the threshold
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API int dBodyGetAutoDisableSteps (dBodyID   ) 
    +
    +
    + +

    +Get auto steps a body must be thought of as idle to disable. +

    +

    Returns:
    the nr of steps
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API dReal dBodyGetAutoDisableTime (dBodyID   ) 
    +
    +
    + +

    +Get auto disable time. +

    +

    Returns:
    nr of seconds
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API void* dBodyGetData (dBodyID   ) 
    +
    +
    + +

    +Get the body's user-data pointer. +

    +

    Returns:
    a pointer to the user's data.
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dBodyGetFiniteRotationAxis (dBodyID ,
    dVector3  result 
    )
    +
    +
    + +

    +Get the finite rotation axis. +

    +

    Parameters:
    + + +
    result will contain the axis.
    +
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API int dBodyGetFiniteRotationMode (dBodyID   ) 
    +
    +
    + +

    +Get the way a body's orientation is updated each timestep. +

    +

    Returns:
    the mode 0 (infitesimal) or 1 (finite).
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API const dReal* dBodyGetForce (dBodyID   ) 
    +
    +
    + +

    +Return the current accumulated force vector. +

    +

    Returns:
    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.
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API int dBodyGetGravityMode (dBodyID  b  ) 
    +
    +
    + +

    +Get whether the body is influenced by the world's gravity or not. +

    +

    Returns:
    nonzero means gravity affects this body.
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API dJointID dBodyGetJoint (dBodyID ,
    int  index 
    )
    +
    +
    + +

    +Return a joint attached to this body, given by index. +

    +

    Parameters:
    + + +
    index valid range is 0 to n-1 where n is the value returned by dBodyGetNumJoints().
    +
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API int dBodyGetNumJoints (dBodyID  b  ) 
    +
    +
    + +

    +Get the number of joints that are attached to this body. +

    +

    Returns:
    nr of joints
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dBodyGetPointVel (dBodyID ,
    dReal  px,
    dReal  py,
    dReal  pz,
    dVector3  result 
    )
    +
    +
    + +

    +Get velocity vector in global coords of a globally specified point on a body. +

    +

    Parameters:
    + + +
    result will contain the result.
    +
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API const dReal* dBodyGetPosition (dBodyID   ) 
    +
    +
    + +

    +Get the position of a body. +

    +

    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.
    +
    See also:
    dBodyCopyPosition
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dBodyGetPosRelPoint (dBodyID ,
    dReal  px,
    dReal  py,
    dReal  pz,
    dVector3  result 
    )
    +
    +
    + +

    +takes a point in global coordinates and returns the point's position in body-relative coordinates. +

    +

    Remarks:
    This is the inverse of dBodyGetRelPointPos()
    +
    Parameters:
    + + +
    result will contain the result.
    +
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API const dReal* dBodyGetQuaternion (dBodyID   ) 
    +
    +
    + +

    +Get the rotation of a body. +

    +

    Returns:
    pointer to 4 scalars that represent the quaternion.
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dBodyGetRelPointPos (dBodyID ,
    dReal  px,
    dReal  py,
    dReal  pz,
    dVector3  result 
    )
    +
    +
    + +

    +Get world position of a relative point on body. +

    +

    Parameters:
    + + +
    result will contain the result.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dBodyGetRelPointVel (dBodyID ,
    dReal  px,
    dReal  py,
    dReal  pz,
    dVector3  result 
    )
    +
    +
    + +

    +Get velocity vector in global coords of a relative point on body. +

    +

    Parameters:
    + + +
    result will contain the result.
    +
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API const dReal* dBodyGetRotation (dBodyID   ) 
    +
    +
    + +

    +Get the rotation of a body. +

    +

    Returns:
    pointer to a 4x3 rotation matrix.
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API const dReal* dBodyGetTorque (dBodyID   ) 
    +
    +
    + +

    +Return the current accumulated torque vector. +

    +

    Returns:
    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.
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API dWorldID dBodyGetWorld (dBodyID   ) 
    +
    +
    + +

    +Retrives the world attached to te given body. +

    +

    Remarks:
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API int dBodyIsEnabled (dBodyID   ) 
    +
    +
    + +

    +Check wether a body is enabled. +

    +

    Returns:
    1 if a body is currently enabled or 0 if it is disabled.
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dBodySetAutoDisableAngularThreshold (dBodyID ,
    dReal  angular_average_threshold 
    )
    +
    +
    + +

    +Set auto disable angular average threshold. +

    +

    Returns:
    the threshold
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dBodySetAutoDisableAverageSamplesCount (dBodyID ,
    unsigned int  average_samples_count 
    )
    +
    +
    + +

    +Set auto disable average buffer size (average steps). +

    +

    Parameters:
    + + +
    average_samples_count the nr of samples to review.
    +
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API void dBodySetAutoDisableDefaults (dBodyID   ) 
    +
    +
    + +

    +Set auto disable defaults. +

    +

    Remarks:
    Set the values for the body to those set as default for the world.
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dBodySetAutoDisableFlag (dBodyID ,
    int  do_auto_disable 
    )
    +
    +
    + +

    +Set auto disable flag. +

    +

    Parameters:
    + + +
    do_auto_disable 0 or 1
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dBodySetAutoDisableLinearThreshold (dBodyID ,
    dReal  linear_average_threshold 
    )
    +
    +
    + +

    +Set auto disable linear average threshold. +

    +

    Returns:
    the threshold
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dBodySetAutoDisableSteps (dBodyID ,
    int  steps 
    )
    +
    +
    + +

    +Set auto disable steps. +

    +

    Parameters:
    + + +
    steps the nr of steps.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dBodySetAutoDisableTime (dBodyID ,
    dReal  time 
    )
    +
    +
    + +

    +Set auto disable time. +

    +

    Parameters:
    + + +
    time nr of seconds.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dBodySetData (dBodyID ,
    void *  data 
    )
    +
    +
    + +

    +Set the body's user-data pointer. +

    +

    Parameters:
    + + +
    data arbitraty pointer
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dBodySetFiniteRotationAxis (dBodyID ,
    dReal  x,
    dReal  y,
    dReal  z 
    )
    +
    +
    + +

    +sets the finite rotation axis for a body. +

    +

    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.

    +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 dBodySetFiniteRotationMode (dBodyID ,
    int  mode 
    )
    +
    +
    + +

    +controls the way a body's orientation is updated at each timestep. +

    +

    Parameters:
    + + +
    mode can be 0 or 1:
      +
    • 0: An ``infinitesimal'' orientation update is used. This is fast to compute, but it can occasionally cause inaccuracies for bodies that are rotating at high speed, especially when those bodies are joined to other bodies. This is the default for every new body that is created.
    • +
    • 1: A ``finite'' orientation update is used. This is more costly to compute, but will be more accurate for high speed rotations.
    • +
    +
    +
    +
    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 dBodySetForce (dBodyID  b,
    dReal  x,
    dReal  y,
    dReal  z 
    )
    +
    +
    + +

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

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dBodySetGravityMode (dBodyID  b,
    int  mode 
    )
    +
    +
    + +

    +Set whether the body is influenced by the world's gravity or not. +

    +

    Parameters:
    + + +
    mode when nonzero gravity affects this body.
    +
    +
    Remarks:
    Newly created bodies are always influenced by the world's gravity.
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dBodySetPosition (dBodyID ,
    dReal  x,
    dReal  y,
    dReal  z 
    )
    +
    +
    + +

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

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dBodySetQuaternion (dBodyID ,
    const dQuaternion  q 
    )
    +
    +
    + +

    +Set the orientation 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.
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dBodySetRotation (dBodyID ,
    const dMatrix3  R 
    )
    +
    +
    + +

    +Set the orientation 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.
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dBodySetTorque (dBodyID  b,
    dReal  x,
    dReal  y,
    dReal  z 
    )
    +
    +
    + +

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

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dBodyVectorFromWorld (dBodyID ,
    dReal  px,
    dReal  py,
    dReal  pz,
    dVector3  result 
    )
    +
    +
    + +

    +Convert from world to local coordinates. +

    +

    Parameters:
    + + +
    result will contain the result.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dBodyVectorToWorld (dBodyID ,
    dReal  px,
    dReal  py,
    dReal  pz,
    dVector3  result 
    )
    +
    +
    + +

    +Convert from local to world coordinates. +

    +

    Parameters:
    + + +
    result will contain the result.
    +
    + +
    +

    +


    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/group__collide.html b/libraries/ode-0.9/docs/group__collide.html new file mode 100644 index 0000000000..c56e7596a1 --- /dev/null +++ b/libraries/ode-0.9/docs/group__collide.html @@ -0,0 +1,2452 @@ + + +Open Dynamics Engine: Collision Detection + + + + + +

    Collision Detection

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    Modules

     Sphere Class
     Box Class

    Data Structures

    struct  dContactGeom
     Describe the contact point between two geoms. More...

    Typedefs

    typedef dReal dHeightfieldGetHeight (void *p_user_data, int x, int z)
     Callback prototype.
    typedef void dNearCallback (void *data, dGeomID o1, dGeomID o2)
     User callback for geom-geom collision testing.

    Functions

    ODE_API void dGeomDestroy (dGeomID geom)
     Destroy a geom, removing it from any space.
    ODE_API void dGeomSetData (dGeomID geom, void *data)
     Set the user-defined data pointer stored in the geom.
    ODE_API void * dGeomGetData (dGeomID geom)
     Get the user-defined data pointer stored in the geom.
    ODE_API void dGeomSetBody (dGeomID geom, dBodyID body)
     Set the body associated with a placeable geom.
    ODE_API dBodyID dGeomGetBody (dGeomID geom)
     Get the body associated with a placeable geom.
    ODE_API void dGeomSetPosition (dGeomID geom, dReal x, dReal y, dReal z)
     Set the position vector of a placeable geom.
    ODE_API void dGeomSetRotation (dGeomID geom, const dMatrix3 R)
     Set the rotation matrix of a placeable geom.
    ODE_API void dGeomSetQuaternion (dGeomID geom, const dQuaternion Q)
     Set the rotation of a placeable geom.
    ODE_API const dReal * dGeomGetPosition (dGeomID geom)
     Get the position vector of a placeable geom.
    ODE_API void dGeomCopyPosition (dGeomID geom, dVector3 pos)
     Copy the position of a geom into a vector.
    ODE_API const dReal * dGeomGetRotation (dGeomID geom)
     Get the rotation matrix of a placeable geom.
    ODE_API void dGeomCopyRotation (dGeomID geom, dMatrix3 R)
     Get the rotation matrix of a placeable geom.
    ODE_API void dGeomGetQuaternion (dGeomID geom, dQuaternion result)
     Get the rotation quaternion of a placeable geom.
    ODE_API void dGeomGetAABB (dGeomID geom, dReal aabb[6])
     Return the axis-aligned bounding box.
    ODE_API int dGeomIsSpace (dGeomID geom)
     Determing if a geom is a space.
    ODE_API dSpaceID dGeomGetSpace (dGeomID)
     Query for the space containing a particular geom.
    ODE_API int dGeomGetClass (dGeomID geom)
     Given a geom, this returns its class.
    ODE_API void dGeomSetCategoryBits (dGeomID geom, unsigned long bits)
     Set the "category" bitfield for the given geom.
    ODE_API void dGeomSetCollideBits (dGeomID geom, unsigned long bits)
     Set the "collide" bitfield for the given geom.
    ODE_API unsigned long dGeomGetCategoryBits (dGeomID)
     Get the "category" bitfield for the given geom.
    ODE_API unsigned long dGeomGetCollideBits (dGeomID)
     Get the "collide" bitfield for the given geom.
    ODE_API void dGeomEnable (dGeomID geom)
     Enable a geom.
    ODE_API void dGeomDisable (dGeomID geom)
     Disable a geom.
    ODE_API int dGeomIsEnabled (dGeomID geom)
     Check to see if a geom is enabled.
    ODE_API void dGeomSetOffsetPosition (dGeomID geom, dReal x, dReal y, dReal z)
     Set the local offset position of a geom from its body.
    ODE_API void dGeomSetOffsetRotation (dGeomID geom, const dMatrix3 R)
     Set the local offset rotation matrix of a geom from its body.
    ODE_API void dGeomSetOffsetQuaternion (dGeomID geom, const dQuaternion Q)
     Set the local offset rotation of a geom from its body.
    ODE_API void dGeomSetOffsetWorldPosition (dGeomID geom, dReal x, dReal y, dReal z)
     Set the offset position of a geom from its body.
    ODE_API void dGeomSetOffsetWorldRotation (dGeomID geom, const dMatrix3 R)
     Set the offset rotation of a geom from its body.
    ODE_API void dGeomSetOffsetWorldQuaternion (dGeomID geom, const dQuaternion)
     Set the offset rotation of a geom from its body.
    ODE_API void dGeomClearOffset (dGeomID geom)
     Clear any offset from the geom.
    ODE_API int dGeomIsOffset (dGeomID geom)
     Check to see whether the geom has an offset.
    ODE_API const dReal * dGeomGetOffsetPosition (dGeomID geom)
     Get the offset position vector of a geom.
    ODE_API void dGeomCopyOffsetPosition (dGeomID geom, dVector3 pos)
     Copy the offset position vector of a geom.
    ODE_API const dReal * dGeomGetOffsetRotation (dGeomID geom)
     Get the offset rotation matrix of a geom.
    ODE_API void dGeomCopyOffsetRotation (dGeomID geom, dMatrix3 R)
     Copy the offset rotation matrix of a geom.
    ODE_API void dGeomGetOffsetQuaternion (dGeomID geom, dQuaternion result)
     Get the offset rotation quaternion of a geom.
    ODE_API int dCollide (dGeomID o1, dGeomID o2, int flags, dContactGeom *contact, int skip)
     Given two geoms o1 and o2 that potentially intersect, generate contact information for them.
    ODE_API void dSpaceCollide (dSpaceID space, void *data, dNearCallback *callback)
     Determines which pairs of geoms in a space may potentially intersect, and calls the callback function for each candidate pair.
    ODE_API void dSpaceCollide2 (dGeomID space1, dGeomID space2, void *data, dNearCallback *callback)
     Determines which geoms from one space may potentially intersect with geoms from another space, and calls the callback function for each candidate pair.
    ODE_API dGeomID dCreateHeightfield (dSpaceID space, dHeightfieldDataID data, int bPlaceable)
     Creates a heightfield geom.
    ODE_API
    +dHeightfieldDataID 
    dGeomHeightfieldDataCreate ()
     Creates a new empty dHeightfieldDataID.
    ODE_API void dGeomHeightfieldDataDestroy (dHeightfieldDataID d)
     Destroys a dHeightfieldDataID.
    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)
     Configures a dHeightfieldDataID to use a callback to retrieve height data.
    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)
     Configures a dHeightfieldDataID to use height data in byte format.
    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)
     Configures a dHeightfieldDataID to use height data in short format.
    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)
     Configures a dHeightfieldDataID to use height data in single precision floating point format.
    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)
     Configures a dHeightfieldDataID to use height data in double precision floating point format.
    ODE_API void dGeomHeightfieldDataSetBounds (dHeightfieldDataID d, dReal minHeight, dReal maxHeight)
     Manually set the minimum and maximum height bounds.
    ODE_API void dGeomHeightfieldSetHeightfieldData (dGeomID g, dHeightfieldDataID d)
     Assigns a dHeightfieldDataID to a heightfield geom.
    ODE_API
    +dHeightfieldDataID 
    dGeomHeightfieldGetHeightfieldData (dGeomID g)
     Gets the dHeightfieldDataID bound to a heightfield geom.
    +

    Detailed Description

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


    Typedef Documentation

    + +
    +
    + + + + +
    typedef dReal dHeightfieldGetHeight(void *p_user_data, int x, int z)
    +
    +
    + +

    +Callback prototype. +

    +Used by the callback heightfield data type to sample a height for a given cell position.

    +

    Parameters:
    + + + + +
    p_user_data User data specified when creating the dHeightfieldDataID
    x The index of a sample in the local x axis. It is a value in the range zero to ( nWidthSamples - 1 ).
    x The index of a sample in the local z axis. It is a value in the range zero to ( nDepthSamples - 1 ).
    +
    +
    Returns:
    The sample height which is then scaled and offset using the values specified when the heightfield data was created.
    + +
    +

    + +

    +
    + + + + +
    typedef void dNearCallback(void *data, dGeomID o1, dGeomID o2)
    +
    +
    + +

    +User callback for geom-geom collision testing. +

    +

    Parameters:
    + + + + +
    data The user data object, as passed to dSpaceCollide.
    o1 The first geom being tested.
    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.
    + +
    +

    +


    Function Documentation

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API int dCollide (dGeomID  o1,
    dGeomID  o2,
    int  flags,
    dContactGeom contact,
    int  skip 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + + + + +
    o1 The first geom to test.
    o2 The second geom to test.
    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.
    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.

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

    +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).

    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API dGeomID dCreateHeightfield (dSpaceID  space,
    dHeightfieldDataID  data,
    int  bPlaceable 
    )
    +
    +
    + +

    +Creates a heightfield geom. +

    +Uses the information in the given dHeightfieldDataID to construct a geom representing a heightfield in a collision space.

    +

    Parameters:
    + + + + +
    space The space to add the geom to.
    data The dHeightfieldDataID created by dGeomHeightfieldDataCreate and setup by dGeomHeightfieldDataBuildCallback, dGeomHeightfieldDataBuildByte, dGeomHeightfieldDataBuildShort or dGeomHeightfieldDataBuildFloat.
    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.
    +
    +
    Returns:
    A geom id to reference this geom in other calls.
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API void dGeomClearOffset (dGeomID  geom  ) 
    +
    +
    + +

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

    +

    Parameters:
    + + +
    geom the geom to have its offset destroyed.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomCopyOffsetPosition (dGeomID  geom,
    dVector3  pos 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + + +
    geom the geom to query.
    pos returns the offset position
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomCopyOffsetRotation (dGeomID  geom,
    dMatrix3  R 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + + +
    geom the geom to query.
    R returns the rotation matrix.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomCopyPosition (dGeomID  geom,
    dVector3  pos 
    )
    +
    +
    + +

    +Copy the position of a geom into a vector. +

    +

    Parameters:
    + + + +
    geom the geom to query
    pos a copy of the geom position
    +
    +
    See also:
    dGeomGetPosition
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomCopyRotation (dGeomID  geom,
    dMatrix3  R 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + + +
    geom the geom to query.
    R a copy of the geom rotation
    +
    +
    See also:
    dGeomGetRotation
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API void dGeomDestroy (dGeomID  geom  ) 
    +
    +
    + +

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

    +

    Parameters:
    + + +
    geom the geom to be destroyed.
    +
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API void dGeomDisable (dGeomID  geom  ) 
    +
    +
    + +

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

    +

    Parameters:
    + + +
    geom the geom to disable
    +
    +
    See also:
    dGeomDisable

    +dGeomIsEnabled

    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API void dGeomEnable (dGeomID  geom  ) 
    +
    +
    + +

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

    +

    Parameters:
    + + +
    geom the geom to enable
    +
    +
    See also:
    dGeomDisable

    +dGeomIsEnabled

    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomGetAABB (dGeomID  geom,
    dReal  aabb[6] 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + + +
    geom the geom to query
    aabb the returned bounding box
    +
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API dBodyID dGeomGetBody (dGeomID  geom  ) 
    +
    +
    + +

    +Get the body associated with a placeable geom. +

    +

    Parameters:
    + + +
    geom the geom to query.
    +
    +
    See also:
    dGeomSetBody
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API unsigned long dGeomGetCategoryBits (dGeomID   ) 
    +
    +
    + +

    +Get the "category" bitfield for the given geom. +

    +

    Parameters:
    + + + +
    geom the geom to set
    bits the new bitfield value
    +
    +
    See also:
    dGeomSetCategoryBits
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API int dGeomGetClass (dGeomID  geom  ) 
    +
    +
    + +

    +Given a geom, this returns its class. +

    +The ODE classes are:

      +
    • dSphereClass
    • +
    • dBoxClass
    • +
    • dCylinderClass
    • +
    • dPlaneClass
    • +
    • dRayClass
    • +
    • dConvexClass
    • +
    • dGeomTransformClass
    • +
    • dTriMeshClass
    • +
    • dSimpleSpaceClass
    • +
    • dHashSpaceClass
    • +
    • dQuadTreeSpaceClass
    • +
    • dFirstUserClass
    • +
    • dLastUserClass
    • +
    +User-defined class will return their own number.

    +

    Parameters:
    + + +
    geom the geom to query
    +
    +
    Returns:
    The geom class ID.
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API unsigned long dGeomGetCollideBits (dGeomID   ) 
    +
    +
    + +

    +Get the "collide" bitfield for the given geom. +

    +

    Parameters:
    + + + +
    geom the geom to set
    bits the new bitfield value
    +
    +
    See also:
    dGeomSetCollideBits
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API void* dGeomGetData (dGeomID  geom  ) 
    +
    +
    + +

    +Get the user-defined data pointer stored in the geom. +

    +

    Parameters:
    + + +
    geom the geom containing the data
    +
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API const dReal* dGeomGetOffsetPosition (dGeomID  geom  ) 
    +
    +
    + +

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

    +

    Parameters:
    + + +
    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.
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomGetOffsetQuaternion (dGeomID  geom,
    dQuaternion  result 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + + +
    geom the geom to query.
    result a copy of the rotation quaternion.
    +
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API const dReal* dGeomGetOffsetRotation (dGeomID  geom  ) 
    +
    +
    + +

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

    +

    Parameters:
    + + +
    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.
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API const dReal* dGeomGetPosition (dGeomID  geom  ) 
    +
    +
    + +

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

    +

    Parameters:
    + + +
    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.
    +
    See also:
    dBodyGetPosition
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomGetQuaternion (dGeomID  geom,
    dQuaternion  result 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + + +
    geom the geom to query.
    result a copy of the rotation quaternion.
    +
    +
    See also:
    dBodyGetQuaternion
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API const dReal* dGeomGetRotation (dGeomID  geom  ) 
    +
    +
    + +

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

    +

    Parameters:
    + + +
    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.
    +
    See also:
    dBodyGetRotation
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API dSpaceID dGeomGetSpace (dGeomID   ) 
    +
    +
    + +

    +Query for the space containing a particular geom. +

    +

    Parameters:
    + + +
    geom the geom to query
    +
    +
    Returns:
    The space that contains the geom, or NULL if the geom is not contained by a space.
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    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 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + + + + + + + + + + + +
    d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate
    pHeightData A pointer to the height data.
    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.
    width Specifies the total 'width' of the heightfield along the geom's local x axis.
    depth Specifies the total 'depth' of the heightfield along the geom's local z axis.
    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.
    depthSamples Specifies the number of vertices to sample along the depth of the heightfield.
    scale A uniform scale applied to all raw height data.
    offset An offset applied to the scaled height data.
    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.
    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.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    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 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + + + + + + + + + +
    d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate
    width Specifies the total 'width' of the heightfield along the geom's local x axis.
    depth Specifies the total 'depth' of the heightfield along the geom's local z axis.
    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.
    depthSamples Specifies the number of vertices to sample along the depth of the heightfield.
    scale A uniform scale applied to all raw height data.
    offset An offset applied to the scaled height data.
    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.
    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.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    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 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + + + + + + + + + + + +
    d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate
    pHeightData A pointer to the height data.
    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.
    width Specifies the total 'width' of the heightfield along the geom's local x axis.
    depth Specifies the total 'depth' of the heightfield along the geom's local z axis.
    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.
    depthSamples Specifies the number of vertices to sample along the depth of the heightfield.
    scale A uniform scale applied to all raw height data.
    offset An offset applied to the scaled height data.
    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.
    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.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    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 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + + + + + + + + + + + +
    d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate
    pHeightData A pointer to the height data.
    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.
    width Specifies the total 'width' of the heightfield along the geom's local x axis.
    depth Specifies the total 'depth' of the heightfield along the geom's local z axis.
    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.
    depthSamples Specifies the number of vertices to sample along the depth of the heightfield.
    scale A uniform scale applied to all raw height data.
    offset An offset applied to the scaled height data.
    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.
    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.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    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 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + + + + + + + + + + + +
    d A new dHeightfieldDataID created by dGeomHeightfieldDataCreate
    pHeightData A pointer to the height data.
    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.
    width Specifies the total 'width' of the heightfield along the geom's local x axis.
    depth Specifies the total 'depth' of the heightfield along the geom's local z axis.
    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.
    depthSamples Specifies the number of vertices to sample along the depth of the heightfield.
    scale A uniform scale applied to all raw height data.
    offset An offset applied to the scaled height data.
    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.
    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.
    +
    + +
    +

    + +

    +
    + + + + + + + + +
    ODE_API dHeightfieldDataID dGeomHeightfieldDataCreate (  ) 
    +
    +
    + +

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

    +

    Returns:
    A dHeightfieldDataID for use with dGeomHeightfieldDataBuildCallback, dGeomHeightfieldDataBuildByte, dGeomHeightfieldDataBuildShort or dGeomHeightfieldDataBuildFloat.
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API void dGeomHeightfieldDataDestroy (dHeightfieldDataID  d  ) 
    +
    +
    + +

    +Destroys a dHeightfieldDataID. +

    +Deallocates a given dHeightfieldDataID and all managed resources.

    +

    Parameters:
    + + +
    d A dHeightfieldDataID created by dGeomHeightfieldDataCreate
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomHeightfieldDataSetBounds (dHeightfieldDataID  d,
    dReal  minHeight,
    dReal  maxHeight 
    )
    +
    +
    + +

    +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.
    +
    Parameters:
    + + + + +
    d A dHeightfieldDataID created by dGeomHeightfieldDataCreate
    min_height The new minimum height value. Scale, offset and thickness is then applied.
    max_height The new maximum height value. Scale and offset is then applied.
    +
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API dHeightfieldDataID dGeomHeightfieldGetHeightfieldData (dGeomID  g  ) 
    +
    +
    + +

    +Gets the dHeightfieldDataID bound to a heightfield geom. +

    +Returns the dHeightfieldDataID associated with a heightfield geom.

    +

    Parameters:
    + + +
    g A geom created by dCreateHeightfield
    +
    +
    Returns:
    The dHeightfieldDataID which may be NULL if none was assigned.
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomHeightfieldSetHeightfieldData (dGeomID  g,
    dHeightfieldDataID  d 
    )
    +
    +
    + +

    +Assigns a dHeightfieldDataID to a heightfield geom. +

    +Associates the given dHeightfieldDataID with a heightfield geom. This is done without affecting the GEOM_PLACEABLE flag.

    +

    Parameters:
    + + + +
    g A geom created by dCreateHeightfield
    d A dHeightfieldDataID created by dGeomHeightfieldDataCreate
    +
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API int dGeomIsEnabled (dGeomID  geom  ) 
    +
    +
    + +

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

    +

    Parameters:
    + + +
    geom the geom to query
    +
    +
    Returns:
    Non-zero if the geom is enabled, zero otherwise.
    +
    See also:
    dGeomDisable

    +dGeomIsEnabled

    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API int dGeomIsOffset (dGeomID  geom  ) 
    +
    +
    + +

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

    +

    Parameters:
    + + +
    geom the geom to query.
    +
    +
    Returns:
    Non-zero if the geom has an offset, zero otherwise.
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API int dGeomIsSpace (dGeomID  geom  ) 
    +
    +
    + +

    +Determing if a geom is a space. +

    +

    Parameters:
    + + +
    geom the geom to query
    +
    +
    Returns:
    Non-zero if the geom is a space, zero otherwise.
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomSetBody (dGeomID  geom,
    dBodyID  body 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + + +
    geom the geom to connect
    body the body to attach to the geom
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomSetCategoryBits (dGeomID  geom,
    unsigned long  bits 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + + +
    geom the geom to set
    bits the new bitfield value
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomSetCollideBits (dGeomID  geom,
    unsigned long  bits 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + + +
    geom the geom to set
    bits the new bitfield value
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomSetData (dGeomID  geom,
    void *  data 
    )
    +
    +
    + +

    +Set the user-defined data pointer stored in the geom. +

    +

    Parameters:
    + + + +
    geom the geom to hold the data
    data the data pointer to be stored
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomSetOffsetPosition (dGeomID  geom,
    dReal  x,
    dReal  y,
    dReal  z 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + + + + +
    geom the geom to set.
    x the new X coordinate.
    y the new Y coordinate.
    z the new Z coordinate.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomSetOffsetQuaternion (dGeomID  geom,
    const dQuaternion  Q 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + + +
    geom the geom to set.
    Q the new rotation.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomSetOffsetRotation (dGeomID  geom,
    const dMatrix3  R 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + + +
    geom the geom to set.
    R the new rotation matrix.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomSetOffsetWorldPosition (dGeomID  geom,
    dReal  x,
    dReal  y,
    dReal  z 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + + + + +
    geom the geom to set.
    x the new X coordinate.
    y the new Y coordinate.
    z the new Z coordinate.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomSetOffsetWorldQuaternion (dGeomID  geom,
    const   dQuaternion 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + + +
    geom the geom to set.
    Q the new rotation.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomSetOffsetWorldRotation (dGeomID  geom,
    const dMatrix3  R 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + + +
    geom the geom to set.
    R the new rotation matrix.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomSetPosition (dGeomID  geom,
    dReal  x,
    dReal  y,
    dReal  z 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + + + + +
    geom the geom to set.
    x the new X coordinate.
    y the new Y coordinate.
    z the new Z coordinate.
    +
    +
    See also:
    dBodySetPosition
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomSetQuaternion (dGeomID  geom,
    const dQuaternion  Q 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + + +
    geom the geom to set.
    Q the new rotation.
    +
    +
    See also:
    dBodySetQuaternion
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomSetRotation (dGeomID  geom,
    const dMatrix3  R 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + + +
    geom the geom to set.
    R the new rotation matrix.
    +
    +
    See also:
    dBodySetRotation
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dSpaceCollide (dSpaceID  space,
    void *  data,
    dNearCallback callback 
    )
    +
    +
    + +

    +Determines which pairs of geoms in a space may potentially intersect, and calls the callback function for each candidate pair. +

    +

    Parameters:
    + + + + +
    space The space to test.
    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.
    callback A callback function is of type 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.

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

    +
    See also:
    dSpaceCollide2
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dSpaceCollide2 (dGeomID  space1,
    dGeomID  space2,
    void *  data,
    dNearCallback callback 
    )
    +
    +
    + +

    +Determines which geoms from one space may potentially intersect with geoms from another space, and calls the callback function for each candidate pair. +

    +

    Parameters:
    + + + + + +
    space1 The first space to test.
    space2 The second space to test.
    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.
    callback A callback function is of type 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.

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

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

    +
    See also:
    dSpaceCollide
    + +
    +

    +


    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/group__collide__box.html b/libraries/ode-0.9/docs/group__collide__box.html new file mode 100644 index 0000000000..341c2c19a4 --- /dev/null +++ b/libraries/ode-0.9/docs/group__collide__box.html @@ -0,0 +1,182 @@ + + +Open Dynamics Engine: Box Class + + + + + +

    Box Class
    + +[Collision Detection] +

    + + + + + + + + + + + +

    Functions

    ODE_API dGeomID dCreateBox (dSpaceID space, dReal lx, dReal ly, dReal lz)
     Create a box geom with the provided side lengths.
    ODE_API void dGeomBoxSetLengths (dGeomID box, dReal lx, dReal ly, dReal lz)
     Set the side lengths of the given box.
    ODE_API void dGeomBoxGetLengths (dGeomID box, dVector3 result)
     Get the side lengths of a box.
    +

    Function Documentation

    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API dGeomID dCreateBox (dSpaceID  space,
    dReal  lx,
    dReal  ly,
    dReal  lz 
    )
    +
    +
    + +

    +Create a box geom with the provided side lengths. +

    +

    Parameters:
    + + + + + +
    space a space to contain the new geom. May be null.
    lx the length of the box along the X axis
    ly the length of the box along the Y axis
    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.
    +
    See also:
    dGeomDestroy

    +dGeomBoxSetLengths

    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomBoxGetLengths (dGeomID  box,
    dVector3  result 
    )
    +
    +
    + +

    +Get the side lengths of a box. +

    +

    Parameters:
    + + + +
    box the box to query
    result the returned side lengths
    +
    +
    See also:
    dGeomBoxSetLengths
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomBoxSetLengths (dGeomID  box,
    dReal  lx,
    dReal  ly,
    dReal  lz 
    )
    +
    +
    + +

    +Set the side lengths of the given box. +

    +

    Parameters:
    + + + + + +
    box the box to set
    lx the length of the box along the X axis
    ly the length of the box along the Y axis
    lz the length of the box along the Z axis
    +
    +
    See also:
    dGeomBoxGetLengths
    + +
    +

    +


    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/group__collide__sphere.html b/libraries/ode-0.9/docs/group__collide__sphere.html new file mode 100644 index 0000000000..c0174cc5d7 --- /dev/null +++ b/libraries/ode-0.9/docs/group__collide__sphere.html @@ -0,0 +1,199 @@ + + +Open Dynamics Engine: Sphere Class + + + + + +

    Sphere Class
    + +[Collision Detection] +

    + + + + + + + + + + + + + + +

    Functions

    ODE_API dGeomID dCreateSphere (dSpaceID space, dReal radius)
     Create a sphere geom of the given radius, and return its ID.
    ODE_API void dGeomSphereSetRadius (dGeomID sphere, dReal radius)
     Set the radius of a sphere geom.
    ODE_API dReal dGeomSphereGetRadius (dGeomID sphere)
     Retrieves the radius of a sphere geom.
    ODE_API dReal dGeomSpherePointDepth (dGeomID sphere, dReal x, dReal y, dReal z)
     Calculate the depth of the a given point within a sphere.
    +

    Function Documentation

    + +
    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API dGeomID dCreateSphere (dSpaceID  space,
    dReal  radius 
    )
    +
    +
    + +

    +Create a sphere geom of the given radius, and return its ID. +

    +

    Parameters:
    + + + +
    space a space to contain the new geom. May be null.
    radius the radius of the sphere.
    +
    +
    Returns:
    A new sphere geom.
    +
    Remarks:
    The point of reference for a sphere is its center.
    +
    See also:
    dGeomDestroy

    +dGeomSphereSetRadius

    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API dReal dGeomSphereGetRadius (dGeomID  sphere  ) 
    +
    +
    + +

    +Retrieves the radius of a sphere geom. +

    +

    Parameters:
    + + +
    sphere the sphere to query.
    +
    +
    See also:
    dGeomSphereSetRadius
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API dReal dGeomSpherePointDepth (dGeomID  sphere,
    dReal  x,
    dReal  y,
    dReal  z 
    )
    +
    +
    + +

    +Calculate the depth of the a given point within a sphere. +

    +

    Parameters:
    + + + + + +
    sphere the sphere to query.
    x the X coordinate of the point.
    y the Y coordinate of the point.
    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.
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dGeomSphereSetRadius (dGeomID  sphere,
    dReal  radius 
    )
    +
    +
    + +

    +Set the radius of a sphere geom. +

    +

    Parameters:
    + + + +
    sphere the sphere to set.
    radius the new radius.
    +
    +
    See also:
    dGeomSphereGetRadius
    + +
    +

    +


    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/group__disable.html b/libraries/ode-0.9/docs/group__disable.html new file mode 100644 index 0000000000..ad8bb2c393 --- /dev/null +++ b/libraries/ode-0.9/docs/group__disable.html @@ -0,0 +1,563 @@ + + +Open Dynamics Engine: Automatic Enabling and Disabling + + + + + +

    Automatic Enabling and Disabling

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    Functions

    +ODE_API void dWorldSetAutoEnableDepthSF1 (dWorldID, int autoEnableDepth)
     Set the AutoEnableDepth parameter used by the StepFast1 algorithm.
    +ODE_API int dWorldGetAutoEnableDepthSF1 (dWorldID)
     Get the AutoEnableDepth parameter used by the StepFast1 algorithm.
    ODE_API dReal dWorldGetAutoDisableLinearThreshold (dWorldID)
     Get auto disable linear threshold for newly created bodies.
    ODE_API void dWorldSetAutoDisableLinearThreshold (dWorldID, dReal linear_threshold)
     Set auto disable linear threshold for newly created bodies.
    ODE_API dReal dWorldGetAutoDisableAngularThreshold (dWorldID)
     Get auto disable angular threshold for newly created bodies.
    ODE_API void dWorldSetAutoDisableAngularThreshold (dWorldID, dReal angular_threshold)
     Set auto disable angular threshold for newly created bodies.
    ODE_API dReal dWorldGetAutoDisableLinearAverageThreshold (dWorldID)
     Get auto disable linear average threshold for newly created bodies.
    ODE_API void dWorldSetAutoDisableLinearAverageThreshold (dWorldID, dReal linear_average_threshold)
     Set auto disable linear average threshold for newly created bodies.
    ODE_API dReal dWorldGetAutoDisableAngularAverageThreshold (dWorldID)
     Get auto disable angular average threshold for newly created bodies.
    ODE_API void dWorldSetAutoDisableAngularAverageThreshold (dWorldID, dReal angular_average_threshold)
     Set auto disable angular average threshold for newly created bodies.
    ODE_API int dWorldGetAutoDisableAverageSamplesCount (dWorldID)
     Get auto disable sample count for newly created bodies.
    ODE_API void dWorldSetAutoDisableAverageSamplesCount (dWorldID, unsigned int average_samples_count)
     Set auto disable average sample count for newly created bodies.
    ODE_API int dWorldGetAutoDisableSteps (dWorldID)
     Get auto disable steps for newly created bodies.
    ODE_API void dWorldSetAutoDisableSteps (dWorldID, int steps)
     Set auto disable steps for newly created bodies.
    ODE_API dReal dWorldGetAutoDisableTime (dWorldID)
     Get auto disable time for newly created bodies.
    ODE_API void dWorldSetAutoDisableTime (dWorldID, dReal time)
     Set auto disable time for newly created bodies.
    ODE_API int dWorldGetAutoDisableFlag (dWorldID)
     Get auto disable flag for newly created bodies.
    ODE_API void dWorldSetAutoDisableFlag (dWorldID, int do_auto_disable)
     Set auto disable flag for newly created bodies.
    +

    Detailed Description

    +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

      +
    • It has been idle for a given number of simulation steps.
    • +
    • 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.


    Function Documentation

    + +
    +
    + + + + + + + + + +
    ODE_API dReal dWorldGetAutoDisableAngularAverageThreshold (dWorldID   ) 
    +
    +
    + +

    +Get auto disable angular average threshold for newly created bodies. +

    +

    Returns:
    the threshold
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API dReal dWorldGetAutoDisableAngularThreshold (dWorldID   ) 
    +
    +
    + +

    +Get auto disable angular threshold for newly created bodies. +

    +

    Returns:
    the threshold
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API int dWorldGetAutoDisableAverageSamplesCount (dWorldID   ) 
    +
    +
    + +

    +Get auto disable sample count for newly created bodies. +

    +

    Returns:
    number of samples used
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API int dWorldGetAutoDisableFlag (dWorldID   ) 
    +
    +
    + +

    +Get auto disable flag for newly created bodies. +

    +

    Returns:
    0 or 1
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API dReal dWorldGetAutoDisableLinearAverageThreshold (dWorldID   ) 
    +
    +
    + +

    +Get auto disable linear average threshold for newly created bodies. +

    +

    Returns:
    the threshold
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API dReal dWorldGetAutoDisableLinearThreshold (dWorldID   ) 
    +
    +
    + +

    +Get auto disable linear threshold for newly created bodies. +

    +

    Returns:
    the threshold
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API int dWorldGetAutoDisableSteps (dWorldID   ) 
    +
    +
    + +

    +Get auto disable steps for newly created bodies. +

    +

    Returns:
    nr of steps
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API dReal dWorldGetAutoDisableTime (dWorldID   ) 
    +
    +
    + +

    +Get auto disable time for newly created bodies. +

    +

    Returns:
    nr of seconds
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dWorldSetAutoDisableAngularAverageThreshold (dWorldID ,
    dReal  angular_average_threshold 
    )
    +
    +
    + +

    +Set auto disable angular average threshold for newly created bodies. +

    +

    Parameters:
    + + +
    linear_average_threshold default is 0.01
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dWorldSetAutoDisableAngularThreshold (dWorldID ,
    dReal  angular_threshold 
    )
    +
    +
    + +

    +Set auto disable angular threshold for newly created bodies. +

    +

    Parameters:
    + + +
    linear_threshold default is 0.01
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dWorldSetAutoDisableAverageSamplesCount (dWorldID ,
    unsigned int  average_samples_count 
    )
    +
    +
    + +

    +Set auto disable average sample count for newly created bodies. +

    +

    Parameters:
    + + +
    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 dWorldSetAutoDisableFlag (dWorldID ,
    int  do_auto_disable 
    )
    +
    +
    + +

    +Set auto disable flag for newly created bodies. +

    +

    Parameters:
    + + +
    do_auto_disable default is false.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dWorldSetAutoDisableLinearAverageThreshold (dWorldID ,
    dReal  linear_average_threshold 
    )
    +
    +
    + +

    +Set auto disable linear average threshold for newly created bodies. +

    +

    Parameters:
    + + +
    linear_average_threshold default is 0.01
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dWorldSetAutoDisableLinearThreshold (dWorldID ,
    dReal  linear_threshold 
    )
    +
    +
    + +

    +Set auto disable linear threshold for newly created bodies. +

    +

    Parameters:
    + + +
    linear_threshold default is 0.01
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dWorldSetAutoDisableSteps (dWorldID ,
    int  steps 
    )
    +
    +
    + +

    +Set auto disable steps for newly created bodies. +

    +

    Parameters:
    + + +
    steps default is 10
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dWorldSetAutoDisableTime (dWorldID ,
    dReal  time 
    )
    +
    +
    + +

    +Set auto disable time for newly created bodies. +

    +

    Parameters:
    + + +
    time default is 0 seconds
    +
    + +
    +

    +


    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/group__drawstuff.html b/libraries/ode-0.9/docs/group__drawstuff.html new file mode 100644 index 0000000000..6cf86504eb --- /dev/null +++ b/libraries/ode-0.9/docs/group__drawstuff.html @@ -0,0 +1,668 @@ + + +Open Dynamics Engine: DrawStuff + + + + + +

    DrawStuff

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    Data Structures

    struct  dsFunctions
     Set of functions to be used as callbacks by the simulation loop. More...

    Functions

    DS_API void dsSimulationLoop (int argc, char **argv, int window_width, int window_height, struct dsFunctions *fn)
     Does the complete simulation.
    DS_API void dsError (char *msg,...)
     exit with error message.
    DS_API void dsDebug (char *msg,...)
     exit with error message and core dump.
    DS_API void dsPrint (char *msg,...)
     print log message
    DS_API void dsSetViewpoint (float xyz[3], float hpr[3])
     Sets the viewpoint.
    DS_API void dsGetViewpoint (float xyz[3], float hpr[3])
     Gets the viewpoint.
    DS_API void dsStop ()
     Stop the simulation loop.
    DS_API double dsElapsedTime ()
     Get the elapsed time (on wall-clock).
    DS_API void dsSetTexture (int texture_number)
     Toggle the rendering of textures.
    DS_API void dsSetColor (float red, float green, float blue)
     Set the color with which geometry is drawn.
    DS_API void dsSetColorAlpha (float red, float green, float blue, float alpha)
     Set the color and transparency with which geometry is drawn.
    DS_API void dsDrawBox (const float pos[3], const float R[12], const float sides[3])
     Draw a box.
    DS_API void dsDrawSphere (const float pos[3], const float R[12], float radius)
     Draw a sphere.
    DS_API void dsDrawTriangle (const float pos[3], const float R[12], const float *v0, const float *v1, const float *v2, int solid)
     Draw a triangle.
    +DS_API void dsDrawCylinder (const float pos[3], const float R[12], float length, float radius)
     Draw a z-aligned cylinder.
    +DS_API void dsDrawCapsule (const float pos[3], const float R[12], float length, float radius)
     Draw a z-aligned capsule.
    +DS_API void dsDrawLine (const float pos1[3], const float pos2[3])
     Draw a line.
    +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)
     Draw a convex shape.
    DS_API void dsSetSphereQuality (int n)
     Set the quality with which curved objects are rendered.
    +

    Detailed Description

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

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


    Function Documentation

    + +
    +
    + + + + + + + + + + + + + + + + + + +
    DS_API void dsDebug (char *  msg,
      ... 
    )
    +
    +
    + +

    +exit with error message and core dump. +

    +this functions tries to dump core or start the debugger.

    Parameters:
    + + +
    msg format strin, like printf, without the newline character.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    DS_API void dsDrawBox (const float  pos[3],
    const float  R[12],
    const float  sides[3] 
    )
    +
    +
    + +

    +Draw a box. +

    +

    Parameters:
    + + + + +
    pos is the x,y,z of the center of the object.
    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 ]
    sides[] is an array of x,y,z side lengths.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    DS_API void dsDrawSphere (const float  pos[3],
    const float  R[12],
    float  radius 
    )
    +
    +
    + +

    +Draw a sphere. +

    +

    Parameters:
    + + + + +
    pos Position of center.
    R orientation.
    radius 
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    DS_API void dsDrawTriangle (const float  pos[3],
    const float  R[12],
    const float *  v0,
    const float *  v1,
    const float *  v2,
    int  solid 
    )
    +
    +
    + +

    +Draw a triangle. +

    +

    Parameters:
    + + + + + + + +
    pos Position of center
    R orientation
    v0 first vertex
    v1 second
    v2 third vertex
    solid set to 0 for wireframe
    +
    + +
    +

    + +

    +
    + + + + + + + + +
    DS_API double dsElapsedTime (  ) 
    +
    +
    + +

    +Get the elapsed time (on wall-clock). +

    +It returns the nr of seconds since the last call to this function. +

    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    DS_API void dsError (char *  msg,
      ... 
    )
    +
    +
    + +

    +exit with error message. +

    +This function displays an error message then exit.

    Parameters:
    + + +
    msg format strin, like printf, without the newline character.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    DS_API void dsGetViewpoint (float  xyz[3],
    float  hpr[3] 
    )
    +
    +
    + +

    +Gets the viewpoint. +

    +

    Parameters:
    + + + +
    xyz position
    hpr heading,pitch,roll.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    DS_API void dsPrint (char *  msg,
      ... 
    )
    +
    +
    + +

    +print log message +

    +

    Parameters:
    + + +
    msg format string, like printf, without the
    +.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    DS_API void dsSetColor (float  red,
    float  green,
    float  blue 
    )
    +
    +
    + +

    +Set the color with which geometry is drawn. +

    +

    Parameters:
    + + + + +
    red Red component from 0 to 1
    green Green component from 0 to 1
    blue Blue component from 0 to 1
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    DS_API void dsSetColorAlpha (float  red,
    float  green,
    float  blue,
    float  alpha 
    )
    +
    +
    + +

    +Set the color and transparency with which geometry is drawn. +

    +

    Parameters:
    + + +
    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 dsSetSphereQuality (int  n  ) 
    +
    +
    + +

    +Set the quality with which curved objects are rendered. +

    +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 dsSetTexture (int  texture_number  ) 
    +
    +
    + +

    +Toggle the rendering of textures. +

    +It changes the way objects are drawn. these changes will apply to all further dsDrawXXX() functions.

    Parameters:
    + + +
    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 dsSetViewpoint (float  xyz[3],
    float  hpr[3] 
    )
    +
    +
    + +

    +Sets the viewpoint. +

    +

    Parameters:
    + + + +
    xyz camera position.
    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 dsSimulationLoop (int  argc,
    char **  argv,
    int  window_width,
    int  window_height,
    struct dsFunctions fn 
    )
    +
    +
    + +

    +Does the complete simulation. +

    +This function starts running the simulation, and only exits when the simulation is done. Function pointers should be provided for the callbacks.

    Parameters:
    + + + +
    argv supports flags like '-notex' '-noshadow' '-pause'
    fn Callback functions.
    +
    + +
    +

    + +

    +
    + + + + + + + + +
    DS_API void dsStop (  ) 
    +
    +
    + +

    +Stop the simulation loop. +

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

    +

    +


    Generated on Fri Oct 12 08:36:52 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/group__joints.html b/libraries/ode-0.9/docs/group__joints.html new file mode 100644 index 0000000000..efe718e967 --- /dev/null +++ b/libraries/ode-0.9/docs/group__joints.html @@ -0,0 +1,2127 @@ + + +Open Dynamics Engine: Joints + + + + + +

    Joints

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    Functions

    ODE_API dJointID dJointCreateBall (dWorldID, dJointGroupID)
     Create a new joint of the ball type.
    ODE_API dJointID dJointCreateHinge (dWorldID, dJointGroupID)
     Create a new joint of the hinge type.
    ODE_API dJointID dJointCreateSlider (dWorldID, dJointGroupID)
     Create a new joint of the slider type.
    ODE_API dJointID dJointCreateContact (dWorldID, dJointGroupID, const dContact *)
     Create a new joint of the contact type.
    ODE_API dJointID dJointCreateHinge2 (dWorldID, dJointGroupID)
     Create a new joint of the hinge2 type.
    ODE_API dJointID dJointCreateUniversal (dWorldID, dJointGroupID)
     Create a new joint of the universal type.
    ODE_API dJointID dJointCreatePR (dWorldID, dJointGroupID)
     Create a new joint of the PR (Prismatic and Rotoide) type.
    ODE_API dJointID dJointCreateFixed (dWorldID, dJointGroupID)
     Create a new joint of the fixed type.
    ODE_API dJointID dJointCreateAMotor (dWorldID, dJointGroupID)
     Create a new joint of the A-motor type.
    ODE_API dJointID dJointCreateLMotor (dWorldID, dJointGroupID)
     Create a new joint of the L-motor type.
    ODE_API dJointID dJointCreatePlane2D (dWorldID, dJointGroupID)
     Create a new joint of the plane-2d type.
    ODE_API void dJointDestroy (dJointID)
     Destroy a joint.
    ODE_API dJointGroupID dJointGroupCreate (int max_size)
     Create a joint group.
    ODE_API void dJointGroupDestroy (dJointGroupID)
     Destroy a joint group.
    ODE_API void dJointGroupEmpty (dJointGroupID)
     Empty a joint group.
    ODE_API void dJointAttach (dJointID, dBodyID body1, dBodyID body2)
     Attach the joint to some new bodies.
    +ODE_API void dJointSetData (dJointID, void *data)
     Set the user-data pointer.
    +ODE_API void * dJointGetData (dJointID)
     Get the user-data pointer.
    ODE_API int dJointGetType (dJointID)
     Get the type of the joint.
    ODE_API dBodyID dJointGetBody (dJointID, int index)
     Return the bodies that this joint connects.
    ODE_API void dJointSetFeedback (dJointID, dJointFeedback *)
     Sets the datastructure that is to receive the feedback.
    +ODE_API dJointFeedback * dJointGetFeedback (dJointID)
     Gets the datastructure that is to receive the feedback.
    ODE_API void dJointSetBallAnchor (dJointID, dReal x, dReal y, dReal z)
     Set the joint anchor point.
    +ODE_API void dJointSetBallAnchor2 (dJointID, dReal x, dReal y, dReal z)
     Set the joint anchor point.
    +ODE_API void dJointSetBallParam (dJointID, int parameter, dReal value)
     Param setting for Ball joints.
    +ODE_API void dJointSetHingeAnchor (dJointID, dReal x, dReal y, dReal z)
     Set hinge anchor parameter.
    +ODE_API void dJointSetHingeAxis (dJointID, dReal x, dReal y, dReal z)
     Set hinge axis.
    +ODE_API void dJointSetHingeParam (dJointID, int parameter, dReal value)
     set joint parameter
    ODE_API void dJointAddHingeTorque (dJointID joint, dReal torque)
     Applies the torque about the hinge axis.
    +ODE_API void dJointSetSliderAxis (dJointID, dReal x, dReal y, dReal z)
     set the joint axis
    +ODE_API void dJointSetSliderAxisDelta (dJointID, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az)
    +ODE_API void dJointSetSliderParam (dJointID, int parameter, dReal value)
     set joint parameter
    ODE_API void dJointAddSliderForce (dJointID joint, dReal force)
     Applies the given force in the slider's direction.
    +ODE_API void dJointSetHinge2Anchor (dJointID, dReal x, dReal y, dReal z)
     set anchor
    +ODE_API void dJointSetHinge2Axis1 (dJointID, dReal x, dReal y, dReal z)
     set axis
    +ODE_API void dJointSetHinge2Axis2 (dJointID, dReal x, dReal y, dReal z)
     set axis
    +ODE_API void dJointSetHinge2Param (dJointID, int parameter, dReal value)
     set joint parameter
    ODE_API void dJointAddHinge2Torques (dJointID joint, dReal torque1, dReal torque2)
     Applies torque1 about the hinge2's axis 1, torque2 about the hinge2's axis 2.
    +ODE_API void dJointSetUniversalAnchor (dJointID, dReal x, dReal y, dReal z)
     set anchor
    +ODE_API void dJointSetUniversalAxis1 (dJointID, dReal x, dReal y, dReal z)
     set axis
    +ODE_API void dJointSetUniversalAxis2 (dJointID, dReal x, dReal y, dReal z)
     set axis
    +ODE_API void dJointSetUniversalParam (dJointID, int parameter, dReal value)
     set joint parameter
    ODE_API void dJointAddUniversalTorques (dJointID joint, dReal torque1, dReal torque2)
     Applies torque1 about the universal's axis 1, torque2 about the universal's axis 2.
    +ODE_API void dJointSetPRAnchor (dJointID, dReal x, dReal y, dReal z)
     set anchor
    +ODE_API void dJointSetPRAxis1 (dJointID, dReal x, dReal y, dReal z)
     set the axis for the prismatic articulation
    +ODE_API void dJointSetPRAxis2 (dJointID, dReal x, dReal y, dReal z)
     set the axis for the rotoide articulation
    ODE_API void dJointSetPRParam (dJointID, int parameter, dReal value)
     set joint parameter
    ODE_API void dJointAddPRTorque (dJointID j, dReal torque)
     Applies the torque about the rotoide axis of the PR joint.
    +ODE_API void dJointSetFixed (dJointID)
     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.
    ODE_API void dJointSetAMotorNumAxes (dJointID, int num)
     set the nr of axes
    +ODE_API void dJointSetAMotorAxis (dJointID, int anum, int rel, dReal x, dReal y, dReal z)
     set axis
    ODE_API void dJointSetAMotorAngle (dJointID, int anum, dReal angle)
     Tell the AMotor what the current angle is along axis anum.
    +ODE_API void dJointSetAMotorParam (dJointID, int parameter, dReal value)
     set joint parameter
    +ODE_API void dJointSetAMotorMode (dJointID, int mode)
     set mode
    ODE_API void dJointAddAMotorTorques (dJointID, dReal torque1, dReal torque2, dReal torque3)
     Applies torque0 about the AMotor's axis 0, torque1 about the AMotor's axis 1, and torque2 about the AMotor's axis 2.
    ODE_API void dJointSetLMotorNumAxes (dJointID, int num)
     Set the number of axes that will be controlled by the LMotor.
    ODE_API void dJointSetLMotorAxis (dJointID, int anum, int rel, dReal x, dReal y, dReal z)
     Set the AMotor axes.
    +ODE_API void dJointSetLMotorParam (dJointID, int parameter, dReal value)
     set joint parameter
    +ODE_API void dJointSetPlane2DXParam (dJointID, int parameter, dReal value)
    +ODE_API void dJointSetPlane2DYParam (dJointID, int parameter, dReal value)
    +ODE_API void dJointSetPlane2DAngleParam (dJointID, int parameter, dReal value)
    +ODE_API dReal dJointGetBallParam (dJointID, int parameter)
     get joint parameter
    ODE_API void dJointGetHingeAnchor (dJointID, dVector3 result)
     Get the hinge anchor point, in world coordinates.
    ODE_API void dJointGetHingeAnchor2 (dJointID, dVector3 result)
     Get the joint anchor point, in world coordinates.
    +ODE_API void dJointGetHingeAxis (dJointID, dVector3 result)
     get axis
    +ODE_API dReal dJointGetHingeParam (dJointID, int parameter)
     get joint parameter
    ODE_API dReal dJointGetHingeAngle (dJointID)
     Get the hinge angle.
    +ODE_API dReal dJointGetHingeAngleRate (dJointID)
     Get the hinge angle time derivative.
    ODE_API dReal dJointGetSliderPosition (dJointID)
     Get the slider linear position (i.e. the slider's extension).
    +ODE_API dReal dJointGetSliderPositionRate (dJointID)
     Get the slider linear position's time derivative.
    +ODE_API void dJointGetSliderAxis (dJointID, dVector3 result)
     Get the slider axis.
    +ODE_API dReal dJointGetSliderParam (dJointID, int parameter)
     get joint parameter
    ODE_API void dJointGetHinge2Anchor (dJointID, dVector3 result)
     Get the joint anchor point, in world coordinates.
    +ODE_API void dJointGetHinge2Anchor2 (dJointID, dVector3 result)
     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.
    +ODE_API void dJointGetHinge2Axis1 (dJointID, dVector3 result)
     Get joint axis.
    +ODE_API void dJointGetHinge2Axis2 (dJointID, dVector3 result)
     Get joint axis.
    +ODE_API dReal dJointGetHinge2Param (dJointID, int parameter)
     get joint parameter
    +ODE_API dReal dJointGetHinge2Angle1 (dJointID)
     Get angle.
    +ODE_API dReal dJointGetHinge2Angle1Rate (dJointID)
     Get time derivative of angle.
    +ODE_API dReal dJointGetHinge2Angle2Rate (dJointID)
     Get time derivative of angle.
    ODE_API void dJointGetUniversalAnchor (dJointID, dVector3 result)
     Get the joint anchor point, in world coordinates.
    ODE_API void dJointGetUniversalAnchor2 (dJointID, dVector3 result)
     Get the joint anchor point, in world coordinates.
    +ODE_API void dJointGetUniversalAxis1 (dJointID, dVector3 result)
     Get axis.
    +ODE_API void dJointGetUniversalAxis2 (dJointID, dVector3 result)
     Get axis.
    +ODE_API dReal dJointGetUniversalParam (dJointID, int parameter)
     get joint parameter
    ODE_API void dJointGetUniversalAngles (dJointID, dReal *angle1, dReal *angle2)
     Get both angles at the same time.
    +ODE_API dReal dJointGetUniversalAngle1 (dJointID)
     Get angle.
    +ODE_API dReal dJointGetUniversalAngle2 (dJointID)
     Get angle.
    +ODE_API dReal dJointGetUniversalAngle1Rate (dJointID)
     Get time derivative of angle.
    +ODE_API dReal dJointGetUniversalAngle2Rate (dJointID)
     Get time derivative of angle.
    ODE_API void dJointGetPRAnchor (dJointID, dVector3 result)
     Get the joint anchor point, in world coordinates.
    ODE_API dReal dJointGetPRPosition (dJointID)
     Get the PR linear position (i.e. the prismatic's extension).
    +ODE_API dReal dJointGetPRPositionRate (dJointID)
     Get the PR linear position's time derivative.
    +ODE_API void dJointGetPRAxis1 (dJointID, dVector3 result)
     Get the prismatic axis.
    +ODE_API void dJointGetPRAxis2 (dJointID, dVector3 result)
     Get the Rotoide axis.
    +ODE_API dReal dJointGetPRParam (dJointID, int parameter)
     get joint parameter
    ODE_API int dJointGetAMotorNumAxes (dJointID)
     Get the number of angular axes that will be controlled by the AMotor.
    ODE_API void dJointGetAMotorAxis (dJointID, int anum, dVector3 result)
     Get the AMotor axes.
    ODE_API int dJointGetAMotorAxisRel (dJointID, int anum)
     Get axis.
    ODE_API dReal dJointGetAMotorAngle (dJointID, int anum)
     Get the current angle for axis.
    ODE_API dReal dJointGetAMotorAngleRate (dJointID, int anum)
     Get the current angle rate for axis anum.
    +ODE_API dReal dJointGetAMotorParam (dJointID, int parameter)
     get joint parameter
    ODE_API int dJointGetAMotorMode (dJointID)
     Get the angular motor mode.
    +ODE_API int dJointGetLMotorNumAxes (dJointID)
     Get nr of axes.
    +ODE_API void dJointGetLMotorAxis (dJointID, int anum, dVector3 result)
     Get axis.
    +ODE_API dReal dJointGetLMotorParam (dJointID, int parameter)
     get joint parameter
    +ODE_API dReal dJointGetFixedParam (dJointID, int parameter)
     get joint parameter
    +ODE_API dJointID dConnectingJoint (dBodyID, dBodyID)
    +ODE_API int dConnectingJointList (dBodyID, dBodyID, dJointID *)
    ODE_API int dAreConnected (dBodyID, dBodyID)
     Utility function.
    ODE_API int dAreConnectedExcluding (dBodyID body1, dBodyID body2, int joint_type)
     Utility function.
    +

    Detailed Description

    +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:

    +

      +
    • 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.
    • +
    • 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.
    • +
    • dParamVel Desired motor velocity (this will be an angular or linear velocity).
    • +
    • 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.
    • +
    • 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.
    • +
    • 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.
    • +
    • dParamCFM The constraint force mixing (CFM) value used when not at a stop.
    • +
    • dParamStopERP The error reduction parameter (ERP) used by the stops.
    • +
    • 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.
    • +
    • dParamSuspensionERP Suspension error reduction parameter (ERP). Currently this is only implemented on the hinge-2 joint.
    • +
    • 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.

    Function Documentation

    + +
    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API int dAreConnected (dBodyID ,
    dBodyID  
    )
    +
    +
    + +

    +Utility function. +

    +

    Returns:
    1 if the two bodies are connected together by a joint, otherwise return 0.
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API int dAreConnectedExcluding (dBodyID  body1,
    dBodyID  body2,
    int  joint_type 
    )
    +
    +
    + +

    +Utility function. +

    +

    Returns:
    1 if the two bodies are connected together by a joint that does not have type
      +
    • {joint_type}, otherwise return 0.
    • +
    +
    +
    Parameters:
    + + + + +
    body1 A body to check.
    body2 A body to check.
    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.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dJointAddAMotorTorques (dJointID ,
    dReal  torque1,
    dReal  torque2,
    dReal  torque3 
    )
    +
    +
    + +

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

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dJointAddHinge2Torques (dJointID  joint,
    dReal  torque1,
    dReal  torque2 
    )
    +
    +
    + +

    +Applies torque1 about the hinge2's axis 1, torque2 about the hinge2's axis 2. +

    +

    Remarks:
    This function is just a wrapper for dBodyAddTorque().
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dJointAddHingeTorque (dJointID  joint,
    dReal  torque 
    )
    +
    +
    + +

    +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()} +

    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dJointAddPRTorque (dJointID  j,
    dReal  torque 
    )
    +
    +
    + +

    +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()} +

    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dJointAddSliderForce (dJointID  joint,
    dReal  force 
    )
    +
    +
    + +

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

    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dJointAddUniversalTorques (dJointID  joint,
    dReal  torque1,
    dReal  torque2 
    )
    +
    +
    + +

    +Applies torque1 about the universal's axis 1, torque2 about the universal's axis 2. +

    +

    Remarks:
    This function is just a wrapper for dBodyAddTorque().
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dJointAttach (dJointID ,
    dBodyID  body1,
    dBodyID  body2 
    )
    +
    +
    + +

    +Attach the joint to some new bodies. +

    +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 dJointID dJointCreateAMotor (dWorldID ,
    dJointGroupID  
    )
    +
    +
    + +

    +Create a new joint of the A-motor type. +

    +

    Parameters:
    + + +
    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  
    )
    +
    +
    + +

    +Create a new joint of the ball type. +

    +

    Remarks:
    The joint is initially in "limbo" (i.e. it has no effect on the simulation) because it does not connect to any bodies.
    +
    Parameters:
    + + +
    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 *  
    )
    +
    +
    + +

    +Create a new joint of the contact type. +

    +

    Parameters:
    + + +
    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  
    )
    +
    +
    + +

    +Create a new joint of the fixed type. +

    +

    Parameters:
    + + +
    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  
    )
    +
    +
    + +

    +Create a new joint of the hinge type. +

    +

    Parameters:
    + + +
    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  
    )
    +
    +
    + +

    +Create a new joint of the hinge2 type. +

    +

    Parameters:
    + + +
    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  
    )
    +
    +
    + +

    +Create a new joint of the L-motor type. +

    +

    Parameters:
    + + +
    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  
    )
    +
    +
    + +

    +Create a new joint of the plane-2d type. +

    +

    Parameters:
    + + +
    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  
    )
    +
    +
    + +

    +Create a new joint of the PR (Prismatic and Rotoide) type. +

    +

    Parameters:
    + + +
    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  
    )
    +
    +
    + +

    +Create a new joint of the slider type. +

    +

    Parameters:
    + + +
    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  
    )
    +
    +
    + +

    +Create a new joint of the universal type. +

    +

    Parameters:
    + + +
    dJointGroupID set to 0 to allocate the joint normally. If it is nonzero the joint is allocated in the given joint group.
    +
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API void dJointDestroy (dJointID   ) 
    +
    +
    + +

    +Destroy a joint. +

    +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 dReal dJointGetAMotorAngle (dJointID ,
    int  anum 
    )
    +
    +
    + +

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

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API dReal dJointGetAMotorAngleRate (dJointID ,
    int  anum 
    )
    +
    +
    + +

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

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dJointGetAMotorAxis (dJointID ,
    int  anum,
    dVector3  result 
    )
    +
    +
    + +

    +Get the AMotor axes. +

    +

    Parameters:
    + + + +
    anum selects the axis to change (0,1 or 2).
    rel Each axis can have one of three ``relative orientation'' modes.
      +
    • 0: The axis is anchored to the global frame.
    • +
    • 1: The axis is anchored to the first body.
    • +
    • 2: The axis is anchored to the second body.
    • +
    +
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API int dJointGetAMotorAxisRel (dJointID ,
    int  anum 
    )
    +
    +
    + +

    +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:
      +
    • Only axes 0 and 2 need to be set. Axis 1 will be determined automatically at each time step.
    • +
    • Axes 0 and 2 must be perpendicular to each other.
    • +
    • Axis 0 must be anchored to the first body, axis 2 must be anchored to the second body.
    • +
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API int dJointGetAMotorMode (dJointID   ) 
    +
    +
    + +

    +Get the angular motor mode. +

    +

    Parameters:
    + + +
    mode must be one of the following constants:
      +
    • dAMotorUser The AMotor axes and joint angle settings are entirely controlled by the user. This is the default mode.
    • +
    • 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.
    • +
    +
    +
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API int dJointGetAMotorNumAxes (dJointID   ) 
    +
    +
    + +

    +Get the number of angular axes that will be controlled by the AMotor. +

    +

    Parameters:
    + + +
    num can range from 0 (which effectively deactivates the joint) to 3. This is automatically set to 3 in dAMotorEuler mode.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API dBodyID dJointGetBody (dJointID ,
    int  index 
    )
    +
    +
    + +

    +Return the bodies that this joint connects. +

    +

    Parameters:
    + + +
    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 void dJointGetHinge2Anchor (dJointID ,
    dVector3  result 
    )
    +
    +
    + +

    +Get the joint anchor point, in world coordinates. +

    +

    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 dJointGetHingeAnchor (dJointID ,
    dVector3  result 
    )
    +
    +
    + +

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

    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dJointGetHingeAnchor2 (dJointID ,
    dVector3  result 
    )
    +
    +
    + +

    +Get the joint anchor point, in world coordinates. +

    +

    Returns:
    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.
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API dReal dJointGetHingeAngle (dJointID   ) 
    +
    +
    + +

    +Get the hinge angle. +

    +The angle is measured between the two bodies, or between the body and the static environment. The angle will be between -pi..pi. When the hinge anchor or axis is set, the current position of the attached bodies is examined and that position will be the zero angle. +

    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dJointGetPRAnchor (dJointID ,
    dVector3  result 
    )
    +
    +
    + +

    +Get the joint anchor point, in world coordinates. +

    +

    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 dReal dJointGetPRPosition (dJointID   ) 
    +
    +
    + +

    +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)] +

    +

    + +

    +
    + + + + + + + + + +
    ODE_API dReal dJointGetSliderPosition (dJointID   ) 
    +
    +
    + +

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

    +

    + +

    +
    + + + + + + + + + +
    ODE_API int dJointGetType (dJointID   ) 
    +
    +
    + +

    +Get the type of the joint. +

    +

    Returns:
    the type, being one of these:
      +
    • JointTypeBall
    • +
    • JointTypeHinge
    • +
    • JointTypeSlider
    • +
    • JointTypeContact
    • +
    • JointTypeUniversal
    • +
    • JointTypeHinge2
    • +
    • JointTypeFixed
    • +
    • JointTypeAMotor
    • +
    • JointTypeLMotor
    • +
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dJointGetUniversalAnchor (dJointID ,
    dVector3  result 
    )
    +
    +
    + +

    +Get the joint anchor point, in world coordinates. +

    +

    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 dJointGetUniversalAnchor2 (dJointID ,
    dVector3  result 
    )
    +
    +
    + +

    +Get the joint anchor point, in world coordinates. +

    +

    Returns:
    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.
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dJointGetUniversalAngles (dJointID ,
    dReal *  angle1,
    dReal *  angle2 
    )
    +
    +
    + +

    +Get both angles at the same time. +

    +

    Parameters:
    + + + + +
    joint The universal joint for which we want to calculate the angles
    angle1 The angle between the body1 and the axis 1
    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 dJointGroupID dJointGroupCreate (int  max_size  ) 
    +
    +
    + +

    +Create a joint group. +

    +

    Parameters:
    + + +
    max_size deprecated. Set to 0.
    +
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API void dJointGroupDestroy (dJointGroupID   ) 
    +
    +
    + +

    +Destroy a joint group. +

    +All joints in the joint group will be destroyed. +

    +

    + +

    +
    + + + + + + + + + +
    ODE_API void dJointGroupEmpty (dJointGroupID   ) 
    +
    +
    + +

    +Empty a joint group. +

    +All joints in the joint group will be destroyed, but the joint group itself will not be destroyed. +

    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dJointSetAMotorAngle (dJointID ,
    int  anum,
    dReal  angle 
    )
    +
    +
    + +

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

    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dJointSetAMotorNumAxes (dJointID ,
    int  num 
    )
    +
    +
    + +

    +set the nr of axes +

    +

    Parameters:
    + + +
    num 0..3
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dJointSetBallAnchor (dJointID ,
    dReal  x,
    dReal  y,
    dReal  z 
    )
    +
    +
    + +

    +Set the joint anchor point. +

    +The joint will try to keep this point on each body together. The input is specified in world coordinates. +

    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dJointSetFeedback (dJointID ,
    dJointFeedback *  
    )
    +
    +
    + +

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

    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dJointSetLMotorAxis (dJointID ,
    int  anum,
    int  rel,
    dReal  x,
    dReal  y,
    dReal  z 
    )
    +
    +
    + +

    +Set the AMotor axes. +

    +

    Parameters:
    + + + +
    anum selects the axis to change (0,1 or 2).
    rel Each axis can have one of three ``relative orientation'' modes
      +
    • 0: The axis is anchored to the global frame.
    • +
    • 1: The axis is anchored to the first body.
    • +
    • 2: The axis is anchored to the second body.
    • +
    +
    +
    +
    Remarks:
    The axis vector is always specified in global coordinates regardless of the setting of rel.
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dJointSetLMotorNumAxes (dJointID ,
    int  num 
    )
    +
    +
    + +

    +Set the number of axes that will be controlled by the LMotor. +

    +

    Parameters:
    + + +
    num can range from 0 (which effectively deactivates the joint) to 3.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dJointSetPRParam (dJointID ,
    int  parameter,
    dReal  value 
    )
    +
    +
    + +

    +set joint parameter +

    +

    Note:
    parameterX where X equal 2 refer to parameter for the rotoide articulation
    + +
    +

    +


    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/group__world.html b/libraries/ode-0.9/docs/group__world.html new file mode 100644 index 0000000000..9b48f47015 --- /dev/null +++ b/libraries/ode-0.9/docs/group__world.html @@ -0,0 +1,697 @@ + + +Open Dynamics Engine: World + + + + + +

    World

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    Functions

    ODE_API dWorldID dWorldCreate (void)
     Create a new, empty world and return its ID number.
    ODE_API void dWorldDestroy (dWorldID world)
     Destroy a world and everything in it.
    ODE_API void dWorldSetGravity (dWorldID, dReal x, dReal y, dReal z)
     Set the world's global gravity vector.
    +ODE_API void dWorldGetGravity (dWorldID, dVector3 gravity)
     Get the gravity vector for a given world.
    ODE_API void dWorldSetERP (dWorldID, dReal erp)
     Set the global ERP value, that controls how much error correction is performed in each time step.
    ODE_API dReal dWorldGetERP (dWorldID)
     Get the error reduction parameter.
    ODE_API void dWorldSetCFM (dWorldID, dReal cfm)
     Set the global CFM (constraint force mixing) value.
    ODE_API dReal dWorldGetCFM (dWorldID)
     Get the constraint force mixing value.
    ODE_API void dWorldStep (dWorldID, dReal stepsize)
     Step the world.
    ODE_API void dWorldImpulseToForce (dWorldID, dReal stepsize, dReal ix, dReal iy, dReal iz, dVector3 force)
     Converts an impulse to a force.
    ODE_API void dWorldQuickStep (dWorldID w, dReal stepsize)
     Step the world.
    ODE_API void dWorldSetQuickStepNumIterations (dWorldID, int num)
     Set the number of iterations that the QuickStep method performs per step.
    ODE_API int dWorldGetQuickStepNumIterations (dWorldID)
     Get the number of iterations that the QuickStep method performs per step.
    ODE_API void dWorldSetQuickStepW (dWorldID, dReal over_relaxation)
     Set the SOR over-relaxation parameter.
    ODE_API dReal dWorldGetQuickStepW (dWorldID)
     Get the SOR over-relaxation parameter.
    ODE_API void dWorldSetContactMaxCorrectingVel (dWorldID, dReal vel)
     Set the maximum correcting velocity that contacts are allowed to generate.
    +ODE_API dReal dWorldGetContactMaxCorrectingVel (dWorldID)
     Get the maximum correcting velocity that contacts are allowed to generated.
    ODE_API void dWorldSetContactSurfaceLayer (dWorldID, dReal depth)
     Set the depth of the surface layer around all geometry objects.
    ODE_API dReal dWorldGetContactSurfaceLayer (dWorldID)
     Get the depth of the surface layer around all geometry objects.
    ODE_API void dWorldStepFast1 (dWorldID, dReal stepsize, int maxiterations)
     Step the world using the StepFast1 algorithm.
    +

    Detailed Description

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


    Function Documentation

    + +
    +
    + + + + + + + + + +
    ODE_API dWorldID dWorldCreate (void   ) 
    +
    +
    + +

    +Create a new, empty world and return its ID number. +

    +

    Returns:
    an identifier
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API void dWorldDestroy (dWorldID  world  ) 
    +
    +
    + +

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

    +

    Parameters:
    + + +
    world the identifier for the world the be destroyed.
    +
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API dReal dWorldGetCFM (dWorldID   ) 
    +
    +
    + +

    +Get the constraint force mixing value. +

    +

    Returns:
    CFM value
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API dReal dWorldGetContactSurfaceLayer (dWorldID   ) 
    +
    +
    + +

    +Get the depth of the surface layer around all geometry objects. +

    +

    Returns:
    the depth
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API dReal dWorldGetERP (dWorldID   ) 
    +
    +
    + +

    +Get the error reduction parameter. +

    +

    Returns:
    ERP value
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API int dWorldGetQuickStepNumIterations (dWorldID   ) 
    +
    +
    + +

    +Get the number of iterations that the QuickStep method performs per step. +

    +

    Returns:
    nr of iterations
    + +
    +

    + +

    +
    + + + + + + + + + +
    ODE_API dReal dWorldGetQuickStepW (dWorldID   ) 
    +
    +
    + +

    +Get the SOR over-relaxation parameter. +

    +

    Returns:
    the over-relaxation setting
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dWorldImpulseToForce (dWorldID ,
    dReal  stepsize,
    dReal  ix,
    dReal  iy,
    dReal  iz,
    dVector3  force 
    )
    +
    +
    + +

    +Converts an impulse to a force. +

    +

    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 dWorldQuickStep (dWorldID  w,
    dReal  stepsize 
    )
    +
    +
    + +

    +Step the 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.

    +QuickStep is great for stacks of objects especially when the auto-disable feature is used as well. However, it has poor accuracy for near-singular systems. Near-singular systems can occur when using high-friction contacts, motors, or certain articulated structures. For example, a robot with multiple legs sitting on the ground may be near-singular.

    +There are ways to help overcome QuickStep's inaccuracy problems:

      +
    • Increase CFM.
    • +
    • Reduce the number of contacts in your system (e.g. use the minimum number of contacts for the feet of a robot or creature).
    • +
    • Don't use excessive friction in the contacts.
    • +
    • Use contact slip if appropriate
    • +
    • Avoid kinematic loops (however, kinematic loops are inevitable in legged creatures).
    • +
    • Don't use excessive motor strength. 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 dWorldSetCFM (dWorldID ,
    dReal  cfm 
    )
    +
    +
    + +

    +Set the global CFM (constraint force mixing) value. +

    +

    Parameters:
    + + +
    cfm Typical values are in the range {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 dWorldSetContactMaxCorrectingVel (dWorldID ,
    dReal  vel 
    )
    +
    +
    + +

    +Set the maximum correcting velocity that contacts are allowed to generate. +

    +

    Parameters:
    + + +
    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 dWorldSetContactSurfaceLayer (dWorldID ,
    dReal  depth 
    )
    +
    +
    + +

    +Set the depth of the surface layer around all geometry objects. +

    +

    Remarks:
    Contacts are allowed to sink into the surface layer up to the given depth before coming to rest.
    +
    Parameters:
    + + +
    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 dWorldSetERP (dWorldID ,
    dReal  erp 
    )
    +
    +
    + +

    +Set the global ERP value, that controls how much error correction is performed in each time step. +

    +

    Parameters:
    + + + +
    dWorldID the identifier of the world.
    erp Typical values are in the range 0.1--0.8. The default is 0.2.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dWorldSetGravity (dWorldID ,
    dReal  x,
    dReal  y,
    dReal  z 
    )
    +
    +
    + +

    +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). +

    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dWorldSetQuickStepNumIterations (dWorldID ,
    int  num 
    )
    +
    +
    + +

    +Set the number of iterations that the QuickStep method performs per step. +

    +

    Remarks:
    More iterations will give a more accurate solution, but will take longer to compute.
    +
    Parameters:
    + + +
    num The default is 20 iterations.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dWorldSetQuickStepW (dWorldID ,
    dReal  over_relaxation 
    )
    +
    +
    + +

    +Set the SOR over-relaxation parameter. +

    +

    Parameters:
    + + +
    over_relaxation value to use by SOR
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + +
    ODE_API void dWorldStep (dWorldID ,
    dReal  stepsize 
    )
    +
    +
    + +

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

    +

    Parameters:
    + + +
    stepsize The number of seconds that the simulation has to advance.
    +
    + +
    +

    + +

    +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    ODE_API void dWorldStepFast1 (dWorldID ,
    dReal  stepsize,
    int  maxiterations 
    )
    +
    +
    + +

    +Step the world using the StepFast1 algorithm. +

    +

    Parameters:
    + + + +
    stepsize the nr of seconds to advance the simulation.
    maxiterations The number of iterations to perform.
    +
    + +
    +

    +


    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/index.html b/libraries/ode-0.9/docs/index.html new file mode 100644 index 0000000000..a2112e753c --- /dev/null +++ b/libraries/ode-0.9/docs/index.html @@ -0,0 +1,27 @@ + + +Open Dynamics Engine: Open Dynamics Engine API Reference + + + + + +

    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


    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/mass_8h-source.html b/libraries/ode-0.9/docs/mass_8h-source.html new file mode 100644 index 0000000000..145605bd68 --- /dev/null +++ b/libraries/ode-0.9/docs/mass_8h-source.html @@ -0,0 +1,137 @@ + + +Open Dynamics Engine: mass.h Source File + + + + + +

    mass.h

    00001 /*************************************************************************
    +00002  *                                                                       *
    +00003  * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
    +00004  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
    +00005  *                                                                       *
    +00006  * This library is free software; you can redistribute it and/or         *
    +00007  * modify it under the terms of EITHER:                                  *
    +00008  *   (1) The GNU Lesser General Public License as published by the Free  *
    +00009  *       Software Foundation; either version 2.1 of the License, or (at  *
    +00010  *       your option) any later version. The text of the GNU Lesser      *
    +00011  *       General Public License is included with this library in the     *
    +00012  *       file LICENSE.TXT.                                               *
    +00013  *   (2) The BSD-style license that is included with this library in     *
    +00014  *       the file LICENSE-BSD.TXT.                                       *
    +00015  *                                                                       *
    +00016  * This library is distributed in the hope that it will be useful,       *
    +00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
    +00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
    +00019  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
    +00020  *                                                                       *
    +00021  *************************************************************************/
    +00022 
    +00023 #ifndef _ODE_MASS_H_
    +00024 #define _ODE_MASS_H_
    +00025 
    +00026 #include <ode/common.h>
    +00027 
    +00028 #ifdef __cplusplus
    +00029 extern "C" {
    +00030 #endif
    +00031 
    +00032 struct dMass;
    +00033 typedef struct dMass dMass;
    +00034 
    +00043 ODE_API int dMassCheck(const dMass *m);
    +00044 
    +00045 ODE_API void dMassSetZero (dMass *);
    +00046 
    +00047 ODE_API void dMassSetParameters (dMass *, dReal themass,
    +00048           dReal cgx, dReal cgy, dReal cgz,
    +00049           dReal I11, dReal I22, dReal I33,
    +00050           dReal I12, dReal I13, dReal I23);
    +00051 
    +00052 ODE_API void dMassSetSphere (dMass *, dReal density, dReal radius);
    +00053 ODE_API void dMassSetSphereTotal (dMass *, dReal total_mass, dReal radius);
    +00054 
    +00055 ODE_API void dMassSetCapsule (dMass *, dReal density, int direction,
    +00056          dReal radius, dReal length);
    +00057 ODE_API void dMassSetCapsuleTotal (dMass *, dReal total_mass, int direction,
    +00058          dReal radius, dReal length);
    +00059 
    +00060 ODE_API void dMassSetCylinder (dMass *, dReal density, int direction,
    +00061              dReal radius, dReal length);
    +00062 ODE_API void dMassSetCylinderTotal (dMass *, dReal total_mass, int direction,
    +00063              dReal radius, dReal length);
    +00064 
    +00065 ODE_API void dMassSetBox (dMass *, dReal density,
    +00066         dReal lx, dReal ly, dReal lz);
    +00067 ODE_API void dMassSetBoxTotal (dMass *, dReal total_mass,
    +00068              dReal lx, dReal ly, dReal lz);
    +00069 
    +00070 ODE_API void dMassSetTrimesh (dMass *, dReal density, dGeomID g);
    +00071 
    +00072 ODE_API void dMassSetTrimeshTotal (dMass *m, dReal total_mass, dGeomID g);
    +00073 
    +00074 ODE_API void dMassAdjust (dMass *, dReal newmass);
    +00075 
    +00076 ODE_API void dMassTranslate (dMass *, dReal x, dReal y, dReal z);
    +00077 
    +00078 ODE_API void dMassRotate (dMass *, const dMatrix3 R);
    +00079 
    +00080 ODE_API void dMassAdd (dMass *a, const dMass *b);
    +00081 
    +00082 // Backwards compatible API
    +00083 #define dMassSetCappedCylinder dMassSetCapsule
    +00084 #define dMassSetCappedCylinderTotal dMassSetCapsuleTotal
    +00085 
    +00086 
    +00087 struct dMass {
    +00088   dReal mass;
    +00089   dVector4 c;
    +00090   dMatrix3 I;
    +00091 
    +00092 #ifdef __cplusplus
    +00093   dMass()
    +00094     { dMassSetZero (this); }
    +00095   void setZero()
    +00096     { dMassSetZero (this); }
    +00097   void setParameters (dReal themass, dReal cgx, dReal cgy, dReal cgz,
    +00098             dReal I11, dReal I22, dReal I33,
    +00099             dReal I12, dReal I13, dReal I23)
    +00100     { dMassSetParameters (this,themass,cgx,cgy,cgz,I11,I22,I33,I12,I13,I23); }
    +00101   void setSphere (dReal density, dReal radius)
    +00102     { dMassSetSphere (this,density,radius); }
    +00103   void setCapsule (dReal density, int direction, dReal a, dReal b)
    +00104     { dMassSetCappedCylinder (this,density,direction,a,b); }
    +00105   void setCappedCylinder (dReal density, int direction, dReal a, dReal b)
    +00106     { setCapsule(density, direction, a, b); }
    +00107   void setBox (dReal density, dReal lx, dReal ly, dReal lz)
    +00108     { dMassSetBox (this,density,lx,ly,lz); }
    +00109   void adjust (dReal newmass)
    +00110     { dMassAdjust (this,newmass); }
    +00111   void translate (dReal x, dReal y, dReal z)
    +00112     { dMassTranslate (this,x,y,z); }
    +00113   void rotate (const dMatrix3 R)
    +00114     { dMassRotate (this,R); }
    +00115   void add (const dMass *b)
    +00116     { dMassAdd (this,b); }
    +00117 #endif
    +00118 };
    +00119 
    +00120 
    +00121 #ifdef __cplusplus
    +00122 }
    +00123 #endif
    +00124 
    +00125 #endif
    +

    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/matrix_8h-source.html b/libraries/ode-0.9/docs/matrix_8h-source.html new file mode 100644 index 0000000000..8f34e5e6d7 --- /dev/null +++ b/libraries/ode-0.9/docs/matrix_8h-source.html @@ -0,0 +1,214 @@ + + +Open Dynamics Engine: matrix.h Source File + + + + + +

    matrix.h

    00001 /*************************************************************************
    +00002  *                                                                       *
    +00003  * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
    +00004  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
    +00005  *                                                                       *
    +00006  * This library is free software; you can redistribute it and/or         *
    +00007  * modify it under the terms of EITHER:                                  *
    +00008  *   (1) The GNU Lesser General Public License as published by the Free  *
    +00009  *       Software Foundation; either version 2.1 of the License, or (at  *
    +00010  *       your option) any later version. The text of the GNU Lesser      *
    +00011  *       General Public License is included with this library in the     *
    +00012  *       file LICENSE.TXT.                                               *
    +00013  *   (2) The BSD-style license that is included with this library in     *
    +00014  *       the file LICENSE-BSD.TXT.                                       *
    +00015  *                                                                       *
    +00016  * This library is distributed in the hope that it will be useful,       *
    +00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
    +00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
    +00019  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
    +00020  *                                                                       *
    +00021  *************************************************************************/
    +00022 
    +00023 /* optimized and unoptimized vector and matrix functions */
    +00024 
    +00025 #ifndef _ODE_MATRIX_H_
    +00026 #define _ODE_MATRIX_H_
    +00027 
    +00028 #include <ode/common.h>
    +00029 
    +00030 
    +00031 #ifdef __cplusplus
    +00032 extern "C" {
    +00033 #endif
    +00034 
    +00035 
    +00036 /* set a vector/matrix of size n to all zeros, or to a specific value. */
    +00037 
    +00038 ODE_API void dSetZero (dReal *a, int n);
    +00039 ODE_API void dSetValue (dReal *a, int n, dReal value);
    +00040 
    +00041 
    +00042 /* get the dot product of two n*1 vectors. if n <= 0 then
    +00043  * zero will be returned (in which case a and b need not be valid).
    +00044  */
    +00045 
    +00046 ODE_API dReal dDot (const dReal *a, const dReal *b, int n);
    +00047 
    +00048 
    +00049 /* get the dot products of (a0,b), (a1,b), etc and return them in outsum.
    +00050  * all vectors are n*1. if n <= 0 then zeroes will be returned (in which case
    +00051  * the input vectors need not be valid). this function is somewhat faster
    +00052  * than calling dDot() for all of the combinations separately.
    +00053  */
    +00054 
    +00055 /* NOT INCLUDED in the library for now.
    +00056 void dMultidot2 (const dReal *a0, const dReal *a1,
    +00057        const dReal *b, dReal *outsum, int n);
    +00058 */
    +00059 
    +00060 
    +00061 /* matrix multiplication. all matrices are stored in standard row format.
    +00062  * the digit refers to the argument that is transposed:
    +00063  *   0:   A = B  * C   (sizes: A:p*r B:p*q C:q*r)
    +00064  *   1:   A = B' * C   (sizes: A:p*r B:q*p C:q*r)
    +00065  *   2:   A = B  * C'  (sizes: A:p*r B:p*q C:r*q)
    +00066  * case 1,2 are equivalent to saying that the operation is A=B*C but
    +00067  * B or C are stored in standard column format.
    +00068  */
    +00069 
    +00070 ODE_API void dMultiply0 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
    +00071 ODE_API void dMultiply1 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
    +00072 ODE_API void dMultiply2 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
    +00073 
    +00074 
    +00075 /* do an in-place cholesky decomposition on the lower triangle of the n*n
    +00076  * symmetric matrix A (which is stored by rows). the resulting lower triangle
    +00077  * will be such that L*L'=A. return 1 on success and 0 on failure (on failure
    +00078  * the matrix is not positive definite).
    +00079  */
    +00080 
    +00081 ODE_API int dFactorCholesky (dReal *A, int n);
    +00082 
    +00083 
    +00084 /* solve for x: L*L'*x = b, and put the result back into x.
    +00085  * L is size n*n, b is size n*1. only the lower triangle of L is considered.
    +00086  */
    +00087 
    +00088 ODE_API void dSolveCholesky (const dReal *L, dReal *b, int n);
    +00089 
    +00090 
    +00091 /* compute the inverse of the n*n positive definite matrix A and put it in
    +00092  * Ainv. this is not especially fast. this returns 1 on success (A was
    +00093  * positive definite) or 0 on failure (not PD).
    +00094  */
    +00095 
    +00096 ODE_API int dInvertPDMatrix (const dReal *A, dReal *Ainv, int n);
    +00097 
    +00098 
    +00099 /* check whether an n*n matrix A is positive definite, return 1/0 (yes/no).
    +00100  * positive definite means that x'*A*x > 0 for any x. this performs a
    +00101  * cholesky decomposition of A. if the decomposition fails then the matrix
    +00102  * is not positive definite. A is stored by rows. A is not altered.
    +00103  */
    +00104 
    +00105 ODE_API int dIsPositiveDefinite (const dReal *A, int n);
    +00106 
    +00107 
    +00108 /* factorize a matrix A into L*D*L', where L is lower triangular with ones on
    +00109  * the diagonal, and D is diagonal.
    +00110  * A is an n*n matrix stored by rows, with a leading dimension of n rounded
    +00111  * up to 4. L is written into the strict lower triangle of A (the ones are not
    +00112  * written) and the reciprocal of the diagonal elements of D are written into
    +00113  * d.
    +00114  */
    +00115 ODE_API void dFactorLDLT (dReal *A, dReal *d, int n, int nskip);
    +00116 
    +00117 
    +00118 /* solve L*x=b, where L is n*n lower triangular with ones on the diagonal,
    +00119  * and x,b are n*1. b is overwritten with x.
    +00120  * the leading dimension of L is `nskip'.
    +00121  */
    +00122 ODE_API void dSolveL1 (const dReal *L, dReal *b, int n, int nskip);
    +00123 
    +00124 
    +00125 /* solve L'*x=b, where L is n*n lower triangular with ones on the diagonal,
    +00126  * and x,b are n*1. b is overwritten with x.
    +00127  * the leading dimension of L is `nskip'.
    +00128  */
    +00129 ODE_API void dSolveL1T (const dReal *L, dReal *b, int n, int nskip);
    +00130 
    +00131 
    +00132 /* in matlab syntax: a(1:n) = a(1:n) .* d(1:n) */
    +00133 
    +00134 ODE_API void dVectorScale (dReal *a, const dReal *d, int n);
    +00135 
    +00136 
    +00137 /* given `L', a n*n lower triangular matrix with ones on the diagonal,
    +00138  * and `d', a n*1 vector of the reciprocal diagonal elements of an n*n matrix
    +00139  * D, solve L*D*L'*x=b where x,b are n*1. x overwrites b.
    +00140  * the leading dimension of L is `nskip'.
    +00141  */
    +00142 
    +00143 ODE_API void dSolveLDLT (const dReal *L, const dReal *d, dReal *b, int n, int nskip);
    +00144 
    +00145 
    +00146 /* given an L*D*L' factorization of an n*n matrix A, return the updated
    +00147  * factorization L2*D2*L2' of A plus the following "top left" matrix:
    +00148  *
    +00149  *    [ b a' ]     <-- b is a[0]
    +00150  *    [ a 0  ]     <-- a is a[1..n-1]
    +00151  *
    +00152  *   - L has size n*n, its leading dimension is nskip. L is lower triangular
    +00153  *     with ones on the diagonal. only the lower triangle of L is referenced.
    +00154  *   - d has size n. d contains the reciprocal diagonal elements of D.
    +00155  *   - a has size n.
    +00156  * the result is written into L, except that the left column of L and d[0]
    +00157  * are not actually modified. see ldltaddTL.m for further comments. 
    +00158  */
    +00159 ODE_API void dLDLTAddTL (dReal *L, dReal *d, const dReal *a, int n, int nskip);
    +00160 
    +00161 
    +00162 /* given an L*D*L' factorization of a permuted matrix A, produce a new
    +00163  * factorization for row and column `r' removed.
    +00164  *   - A has size n1*n1, its leading dimension in nskip. A is symmetric and
    +00165  *     positive definite. only the lower triangle of A is referenced.
    +00166  *     A itself may actually be an array of row pointers.
    +00167  *   - L has size n2*n2, its leading dimension in nskip. L is lower triangular
    +00168  *     with ones on the diagonal. only the lower triangle of L is referenced.
    +00169  *   - d has size n2. d contains the reciprocal diagonal elements of D.
    +00170  *   - p is a permutation vector. it contains n2 indexes into A. each index
    +00171  *     must be in the range 0..n1-1.
    +00172  *   - r is the row/column of L to remove.
    +00173  * the new L will be written within the old L, i.e. will have the same leading
    +00174  * dimension. the last row and column of L, and the last element of d, are
    +00175  * undefined on exit.
    +00176  *
    +00177  * a fast O(n^2) algorithm is used. see ldltremove.m for further comments.
    +00178  */
    +00179 ODE_API void dLDLTRemove (dReal **A, const int *p, dReal *L, dReal *d,
    +00180         int n1, int n2, int r, int nskip);
    +00181 
    +00182 
    +00183 /* given an n*n matrix A (with leading dimension nskip), remove the r'th row
    +00184  * and column by moving elements. the new matrix will have the same leading
    +00185  * dimension. the last row and column of A are untouched on exit.
    +00186  */
    +00187 ODE_API void dRemoveRowCol (dReal *A, int n, int nskip, int r);
    +00188 
    +00189 
    +00190 #ifdef __cplusplus
    +00191 }
    +00192 #endif
    +00193 
    +00194 #endif
    +

    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/memory_8h-source.html b/libraries/ode-0.9/docs/memory_8h-source.html new file mode 100644 index 0000000000..001fd88ea5 --- /dev/null +++ b/libraries/ode-0.9/docs/memory_8h-source.html @@ -0,0 +1,79 @@ + + +Open Dynamics Engine: memory.h Source File + + + + + +

    memory.h

    00001 /*************************************************************************
    +00002  *                                                                       *
    +00003  * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
    +00004  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
    +00005  *                                                                       *
    +00006  * This library is free software; you can redistribute it and/or         *
    +00007  * modify it under the terms of EITHER:                                  *
    +00008  *   (1) The GNU Lesser General Public License as published by the Free  *
    +00009  *       Software Foundation; either version 2.1 of the License, or (at  *
    +00010  *       your option) any later version. The text of the GNU Lesser      *
    +00011  *       General Public License is included with this library in the     *
    +00012  *       file LICENSE.TXT.                                               *
    +00013  *   (2) The BSD-style license that is included with this library in     *
    +00014  *       the file LICENSE-BSD.TXT.                                       *
    +00015  *                                                                       *
    +00016  * This library is distributed in the hope that it will be useful,       *
    +00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
    +00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
    +00019  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
    +00020  *                                                                       *
    +00021  *************************************************************************/
    +00022 
    +00023 /* this comes from the `reuse' library. copy any changes back to the source */
    +00024 
    +00025 #ifndef _ODE_MEMORY_H_
    +00026 #define _ODE_MEMORY_H_
    +00027 
    +00028 #include "ode/config.h"
    +00029 
    +00030 #ifdef __cplusplus
    +00031 extern "C" {
    +00032 #endif
    +00033 
    +00034 /* function types to allocate and free memory */
    +00035 typedef void * dAllocFunction (size_t size);
    +00036 typedef void * dReallocFunction (void *ptr, size_t oldsize, size_t newsize);
    +00037 typedef void dFreeFunction (void *ptr, size_t size);
    +00038 
    +00039 /* set new memory management functions. if fn is 0, the default handlers are
    +00040  * used. */
    +00041 ODE_API void dSetAllocHandler (dAllocFunction *fn);
    +00042 ODE_API void dSetReallocHandler (dReallocFunction *fn);
    +00043 ODE_API void dSetFreeHandler (dFreeFunction *fn);
    +00044 
    +00045 /* get current memory management functions */
    +00046 ODE_API dAllocFunction *dGetAllocHandler (void);
    +00047 ODE_API dReallocFunction *dGetReallocHandler (void);
    +00048 ODE_API dFreeFunction *dGetFreeHandler (void);
    +00049 
    +00050 /* allocate and free memory. */
    +00051 ODE_API void * dAlloc (size_t size);
    +00052 ODE_API void * dRealloc (void *ptr, size_t oldsize, size_t newsize);
    +00053 ODE_API void dFree (void *ptr, size_t size);
    +00054 
    +00055 #ifdef __cplusplus
    +00056 }
    +00057 #endif
    +00058 
    +00059 #endif
    +

    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/misc_8h-source.html b/libraries/ode-0.9/docs/misc_8h-source.html new file mode 100644 index 0000000000..72bbc1043b --- /dev/null +++ b/libraries/ode-0.9/docs/misc_8h-source.html @@ -0,0 +1,105 @@ + + +Open Dynamics Engine: misc.h Source File + + + + + +

    misc.h

    00001 /*************************************************************************
    +00002  *                                                                       *
    +00003  * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
    +00004  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
    +00005  *                                                                       *
    +00006  * This library is free software; you can redistribute it and/or         *
    +00007  * modify it under the terms of EITHER:                                  *
    +00008  *   (1) The GNU Lesser General Public License as published by the Free  *
    +00009  *       Software Foundation; either version 2.1 of the License, or (at  *
    +00010  *       your option) any later version. The text of the GNU Lesser      *
    +00011  *       General Public License is included with this library in the     *
    +00012  *       file LICENSE.TXT.                                               *
    +00013  *   (2) The BSD-style license that is included with this library in     *
    +00014  *       the file LICENSE-BSD.TXT.                                       *
    +00015  *                                                                       *
    +00016  * This library is distributed in the hope that it will be useful,       *
    +00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
    +00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
    +00019  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
    +00020  *                                                                       *
    +00021  *************************************************************************/
    +00022 
    +00023 /* miscellaneous math functions. these are mostly useful for testing */
    +00024 
    +00025 #ifndef _ODE_MISC_H_
    +00026 #define _ODE_MISC_H_
    +00027 
    +00028 #include <ode/common.h>
    +00029 
    +00030 
    +00031 #ifdef __cplusplus
    +00032 extern "C" {
    +00033 #endif
    +00034 
    +00035 
    +00036 /* return 1 if the random number generator is working. */
    +00037 ODE_API int dTestRand(void);
    +00038 
    +00039 /* return next 32 bit random number. this uses a not-very-random linear
    +00040  * congruential method.
    +00041  */
    +00042 ODE_API unsigned long dRand(void);
    +00043 
    +00044 /* get and set the current random number seed. */
    +00045 ODE_API unsigned long  dRandGetSeed(void);
    +00046 ODE_API void dRandSetSeed (unsigned long s);
    +00047 
    +00048 /* return a random integer between 0..n-1. the distribution will get worse
    +00049  * as n approaches 2^32.
    +00050  */
    +00051 ODE_API int dRandInt (int n);
    +00052 
    +00053 /* return a random real number between 0..1 */
    +00054 ODE_API dReal dRandReal(void);
    +00055 
    +00056 /* print out a matrix */
    +00057 #ifdef __cplusplus
    +00058 ODE_API void dPrintMatrix (const dReal *A, int n, int m, char *fmt = "%10.4f ",
    +00059          FILE *f=stdout);
    +00060 #else
    +00061 ODE_API void dPrintMatrix (const dReal *A, int n, int m, char *fmt, FILE *f);
    +00062 #endif
    +00063 
    +00064 /* make a random vector with entries between +/- range. A has n elements. */
    +00065 ODE_API void dMakeRandomVector (dReal *A, int n, dReal range);
    +00066 
    +00067 /* make a random matrix with entries between +/- range. A has size n*m. */
    +00068 ODE_API void dMakeRandomMatrix (dReal *A, int n, int m, dReal range);
    +00069 
    +00070 /* clear the upper triangle of a square matrix */
    +00071 ODE_API void dClearUpperTriangle (dReal *A, int n);
    +00072 
    +00073 /* return the maximum element difference between the two n*m matrices */
    +00074 ODE_API dReal dMaxDifference (const dReal *A, const dReal *B, int n, int m);
    +00075 
    +00076 /* return the maximum element difference between the lower triangle of two
    +00077  * n*n matrices */
    +00078 ODE_API dReal dMaxDifferenceLowerTriangle (const dReal *A, const dReal *B, int n);
    +00079 
    +00080 
    +00081 #ifdef __cplusplus
    +00082 }
    +00083 #endif
    +00084 
    +00085 #endif
    +

    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/modules.html b/libraries/ode-0.9/docs/modules.html new file mode 100644 index 0000000000..60c4d80f81 --- /dev/null +++ b/libraries/ode-0.9/docs/modules.html @@ -0,0 +1,32 @@ + + +Open Dynamics Engine: Module Index + + + + + +

    Open Dynamics Engine Modules

    Here is a list of all modules: +
    Generated on Fri Oct 12 08:36:52 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/objects_8h-source.html b/libraries/ode-0.9/docs/objects_8h-source.html new file mode 100644 index 0000000000..33871dfd2c --- /dev/null +++ b/libraries/ode-0.9/docs/objects_8h-source.html @@ -0,0 +1,563 @@ + + +Open Dynamics Engine: objects.h Source File + + + + + +

    objects.h

    00001 /*************************************************************************
    +00002  *                                                                       *
    +00003  * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
    +00004  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
    +00005  *                                                                       *
    +00006  * This library is free software; you can redistribute it and/or         *
    +00007  * modify it under the terms of EITHER:                                  *
    +00008  *   (1) The GNU Lesser General Public License as published by the Free  *
    +00009  *       Software Foundation; either version 2.1 of the License, or (at  *
    +00010  *       your option) any later version. The text of the GNU Lesser      *
    +00011  *       General Public License is included with this library in the     *
    +00012  *       file LICENSE.TXT.                                               *
    +00013  *   (2) The BSD-style license that is included with this library in     *
    +00014  *       the file LICENSE-BSD.TXT.                                       *
    +00015  *                                                                       *
    +00016  * This library is distributed in the hope that it will be useful,       *
    +00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
    +00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
    +00019  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
    +00020  *                                                                       *
    +00021  *************************************************************************/
    +00022 
    +00023 #ifndef _ODE_OBJECTS_H_
    +00024 #define _ODE_OBJECTS_H_
    +00025 
    +00026 #include <ode/common.h>
    +00027 #include <ode/mass.h>
    +00028 #include <ode/contact.h>
    +00029 
    +00030 #ifdef __cplusplus
    +00031 extern "C" {
    +00032 #endif
    +00033 
    +00052 ODE_API dWorldID dWorldCreate(void);
    +00053 
    +00054 
    +00064 ODE_API void dWorldDestroy (dWorldID world);
    +00065 
    +00066 
    +00075 ODE_API void dWorldSetGravity (dWorldID, dReal x, dReal y, dReal z);
    +00076 
    +00077 
    +00082 ODE_API void dWorldGetGravity (dWorldID, dVector3 gravity);
    +00083 
    +00084 
    +00092 ODE_API void dWorldSetERP (dWorldID, dReal erp);
    +00093 
    +00099 ODE_API dReal dWorldGetERP (dWorldID);
    +00100 
    +00101 
    +00109 ODE_API void dWorldSetCFM (dWorldID, dReal cfm);
    +00110 
    +00116 ODE_API dReal dWorldGetCFM (dWorldID);
    +00117 
    +00118 
    +00129 ODE_API void dWorldStep (dWorldID, dReal stepsize);
    +00130 
    +00131 
    +00146 ODE_API void dWorldImpulseToForce
    +00147 (
    +00148   dWorldID, dReal stepsize,
    +00149   dReal ix, dReal iy, dReal iz, dVector3 force
    +00150 );
    +00151 
    +00152 
    +00184 ODE_API void dWorldQuickStep (dWorldID w, dReal stepsize);
    +00185 
    +00186 
    +00196 ODE_API void dWorldSetQuickStepNumIterations (dWorldID, int num);
    +00197 
    +00198 
    +00205 ODE_API int dWorldGetQuickStepNumIterations (dWorldID);
    +00206 
    +00212 ODE_API void dWorldSetQuickStepW (dWorldID, dReal over_relaxation);
    +00213 
    +00219 ODE_API dReal dWorldGetQuickStepW (dWorldID);
    +00220 
    +00221 /* World contact parameter functions */
    +00222 
    +00231 ODE_API void dWorldSetContactMaxCorrectingVel (dWorldID, dReal vel);
    +00232 
    +00238 ODE_API dReal dWorldGetContactMaxCorrectingVel (dWorldID);
    +00239 
    +00251 ODE_API void dWorldSetContactSurfaceLayer (dWorldID, dReal depth);
    +00252 
    +00258 ODE_API dReal dWorldGetContactSurfaceLayer (dWorldID);
    +00259 
    +00260 /* StepFast1 functions */
    +00261 
    +00268 ODE_API void dWorldStepFast1(dWorldID, dReal stepsize, int maxiterations);
    +00269 
    +00270 
    +00306 ODE_API void dWorldSetAutoEnableDepthSF1(dWorldID, int autoEnableDepth);
    +00307 
    +00312 ODE_API int dWorldGetAutoEnableDepthSF1(dWorldID);
    +00313 
    +00319 ODE_API dReal dWorldGetAutoDisableLinearThreshold (dWorldID);
    +00320 
    +00326 ODE_API void  dWorldSetAutoDisableLinearThreshold (dWorldID, dReal linear_threshold);
    +00327 
    +00333 ODE_API dReal dWorldGetAutoDisableAngularThreshold (dWorldID);
    +00334 
    +00340 ODE_API void dWorldSetAutoDisableAngularThreshold (dWorldID, dReal angular_threshold);
    +00341 
    +00347 ODE_API dReal dWorldGetAutoDisableLinearAverageThreshold (dWorldID);
    +00348 
    +00354 ODE_API void  dWorldSetAutoDisableLinearAverageThreshold (dWorldID, dReal linear_average_threshold);
    +00355 
    +00361 ODE_API dReal dWorldGetAutoDisableAngularAverageThreshold (dWorldID);
    +00362 
    +00368 ODE_API void dWorldSetAutoDisableAngularAverageThreshold (dWorldID, dReal angular_average_threshold);
    +00369 
    +00375 ODE_API int dWorldGetAutoDisableAverageSamplesCount (dWorldID);
    +00376 
    +00383 ODE_API void dWorldSetAutoDisableAverageSamplesCount (dWorldID, unsigned int average_samples_count );
    +00384 
    +00390 ODE_API int dWorldGetAutoDisableSteps (dWorldID);
    +00391 
    +00397 ODE_API void dWorldSetAutoDisableSteps (dWorldID, int steps);
    +00398 
    +00404 ODE_API dReal dWorldGetAutoDisableTime (dWorldID);
    +00405 
    +00411 ODE_API void dWorldSetAutoDisableTime (dWorldID, dReal time);
    +00412 
    +00418 ODE_API int dWorldGetAutoDisableFlag (dWorldID);
    +00419 
    +00425 ODE_API void dWorldSetAutoDisableFlag (dWorldID, int do_auto_disable);
    +00426 
    +00427 
    +00428 
    +00468 ODE_API dReal dBodyGetAutoDisableLinearThreshold (dBodyID);
    +00469 
    +00475 ODE_API void  dBodySetAutoDisableLinearThreshold (dBodyID, dReal linear_average_threshold);
    +00476 
    +00482 ODE_API dReal dBodyGetAutoDisableAngularThreshold (dBodyID);
    +00483 
    +00489 ODE_API void  dBodySetAutoDisableAngularThreshold (dBodyID, dReal angular_average_threshold);
    +00490 
    +00496 ODE_API int dBodyGetAutoDisableAverageSamplesCount (dBodyID);
    +00497 
    +00503 ODE_API void dBodySetAutoDisableAverageSamplesCount (dBodyID, unsigned int average_samples_count);
    +00504 
    +00505 
    +00511 ODE_API int dBodyGetAutoDisableSteps (dBodyID);
    +00512 
    +00518 ODE_API void dBodySetAutoDisableSteps (dBodyID, int steps);
    +00519 
    +00525 ODE_API dReal dBodyGetAutoDisableTime (dBodyID);
    +00526 
    +00532 ODE_API void  dBodySetAutoDisableTime (dBodyID, dReal time);
    +00533 
    +00539 ODE_API int dBodyGetAutoDisableFlag (dBodyID);
    +00540 
    +00546 ODE_API void dBodySetAutoDisableFlag (dBodyID, int do_auto_disable);
    +00547 
    +00554 ODE_API void  dBodySetAutoDisableDefaults (dBodyID);
    +00555 
    +00556 
    +00563 ODE_API dWorldID dBodyGetWorld (dBodyID);
    +00564 
    +00571 ODE_API dBodyID dBodyCreate (dWorldID);
    +00572 
    +00581 ODE_API void dBodyDestroy (dBodyID);
    +00582 
    +00588 ODE_API void  dBodySetData (dBodyID, void *data);
    +00589 
    +00595 ODE_API void *dBodyGetData (dBodyID);
    +00596 
    +00605 ODE_API void dBodySetPosition   (dBodyID, dReal x, dReal y, dReal z);
    +00606 
    +00615 ODE_API void dBodySetRotation   (dBodyID, const dMatrix3 R);
    +00616 
    +00625 ODE_API void dBodySetQuaternion (dBodyID, const dQuaternion q);
    +00626 
    +00631 ODE_API void dBodySetLinearVel  (dBodyID, dReal x, dReal y, dReal z);
    +00632 
    +00637 ODE_API void dBodySetAngularVel (dBodyID, dReal x, dReal y, dReal z);
    +00638 
    +00648 ODE_API const dReal * dBodyGetPosition   (dBodyID);
    +00649 
    +00650 
    +00658 ODE_API void dBodyCopyPosition (dBodyID body, dVector3 pos);
    +00659 
    +00660 
    +00666 ODE_API const dReal * dBodyGetRotation   (dBodyID);
    +00667 
    +00668 
    +00676 ODE_API void dBodyCopyRotation (dBodyID, dMatrix3 R);
    +00677 
    +00678 
    +00684 ODE_API const dReal * dBodyGetQuaternion (dBodyID);
    +00685 
    +00686 
    +00694 ODE_API void dBodyCopyQuaternion(dBodyID body, dQuaternion quat);
    +00695 
    +00696 
    +00701 ODE_API const dReal * dBodyGetLinearVel  (dBodyID);
    +00702 
    +00707 ODE_API const dReal * dBodyGetAngularVel (dBodyID);
    +00708 
    +00713 ODE_API void dBodySetMass (dBodyID, const dMass *mass);
    +00714 
    +00719 ODE_API void dBodyGetMass (dBodyID, dMass *mass);
    +00720 
    +00725 ODE_API void dBodyAddForce            (dBodyID, dReal fx, dReal fy, dReal fz);
    +00726 
    +00731 ODE_API void dBodyAddTorque           (dBodyID, dReal fx, dReal fy, dReal fz);
    +00732 
    +00737 ODE_API void dBodyAddRelForce         (dBodyID, dReal fx, dReal fy, dReal fz);
    +00738 
    +00743 ODE_API void dBodyAddRelTorque        (dBodyID, dReal fx, dReal fy, dReal fz);
    +00744 
    +00749 ODE_API void dBodyAddForceAtPos       (dBodyID, dReal fx, dReal fy, dReal fz,
    +00750                          dReal px, dReal py, dReal pz);
    +00755 ODE_API void dBodyAddForceAtRelPos    (dBodyID, dReal fx, dReal fy, dReal fz,
    +00756                          dReal px, dReal py, dReal pz);
    +00761 ODE_API void dBodyAddRelForceAtPos    (dBodyID, dReal fx, dReal fy, dReal fz,
    +00762                          dReal px, dReal py, dReal pz);
    +00767 ODE_API void dBodyAddRelForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz,
    +00768                          dReal px, dReal py, dReal pz);
    +00769 
    +00779 ODE_API const dReal * dBodyGetForce   (dBodyID);
    +00780 
    +00790 ODE_API const dReal * dBodyGetTorque  (dBodyID);
    +00791 
    +00800 ODE_API void dBodySetForce  (dBodyID b, dReal x, dReal y, dReal z);
    +00801 
    +00810 ODE_API void dBodySetTorque (dBodyID b, dReal x, dReal y, dReal z);
    +00811 
    +00817 ODE_API void dBodyGetRelPointPos
    +00818 (
    +00819   dBodyID, dReal px, dReal py, dReal pz,
    +00820   dVector3 result
    +00821 );
    +00822 
    +00828 ODE_API void dBodyGetRelPointVel
    +00829 (
    +00830   dBodyID, dReal px, dReal py, dReal pz,
    +00831   dVector3 result
    +00832 );
    +00833 
    +00840 ODE_API void dBodyGetPointVel
    +00841 (
    +00842   dBodyID, dReal px, dReal py, dReal pz,
    +00843   dVector3 result
    +00844 );
    +00845 
    +00854 ODE_API void dBodyGetPosRelPoint
    +00855 (
    +00856   dBodyID, dReal px, dReal py, dReal pz,
    +00857   dVector3 result
    +00858 );
    +00859 
    +00865 ODE_API void dBodyVectorToWorld
    +00866 (
    +00867   dBodyID, dReal px, dReal py, dReal pz,
    +00868   dVector3 result
    +00869 );
    +00870 
    +00876 ODE_API void dBodyVectorFromWorld
    +00877 (
    +00878   dBodyID, dReal px, dReal py, dReal pz,
    +00879   dVector3 result
    +00880 );
    +00881 
    +00899 ODE_API void dBodySetFiniteRotationMode (dBodyID, int mode);
    +00900 
    +00917 ODE_API void dBodySetFiniteRotationAxis (dBodyID, dReal x, dReal y, dReal z);
    +00918 
    +00924 ODE_API int dBodyGetFiniteRotationMode (dBodyID);
    +00925 
    +00931 ODE_API void dBodyGetFiniteRotationAxis (dBodyID, dVector3 result);
    +00932 
    +00938 ODE_API int dBodyGetNumJoints (dBodyID b);
    +00939 
    +00946 ODE_API dJointID dBodyGetJoint (dBodyID, int index);
    +00947 
    +00953 ODE_API void dBodyEnable (dBodyID);
    +00954 
    +00962 ODE_API void dBodyDisable (dBodyID);
    +00963 
    +00969 ODE_API int dBodyIsEnabled (dBodyID);
    +00970 
    +00978 ODE_API void dBodySetGravityMode (dBodyID b, int mode);
    +00979 
    +00985 ODE_API int dBodyGetGravityMode (dBodyID b);
    +00986 
    +00987 
    +00988 
    +01064 ODE_API dJointID dJointCreateBall (dWorldID, dJointGroupID);
    +01065 
    +01072 ODE_API dJointID dJointCreateHinge (dWorldID, dJointGroupID);
    +01073 
    +01080 ODE_API dJointID dJointCreateSlider (dWorldID, dJointGroupID);
    +01081 
    +01088 ODE_API dJointID dJointCreateContact (dWorldID, dJointGroupID, const dContact *);
    +01089 
    +01096 ODE_API dJointID dJointCreateHinge2 (dWorldID, dJointGroupID);
    +01097 
    +01104 ODE_API dJointID dJointCreateUniversal (dWorldID, dJointGroupID);
    +01105 
    +01112 ODE_API dJointID dJointCreatePR (dWorldID, dJointGroupID);
    +01113 
    +01120 ODE_API dJointID dJointCreateFixed (dWorldID, dJointGroupID);
    +01121 
    +01122 ODE_API dJointID dJointCreateNull (dWorldID, dJointGroupID);
    +01123 
    +01130 ODE_API dJointID dJointCreateAMotor (dWorldID, dJointGroupID);
    +01131 
    +01138 ODE_API dJointID dJointCreateLMotor (dWorldID, dJointGroupID);
    +01139 
    +01146 ODE_API dJointID dJointCreatePlane2D (dWorldID, dJointGroupID);
    +01147 
    +01156 ODE_API void dJointDestroy (dJointID);
    +01157 
    +01158 
    +01164 ODE_API dJointGroupID dJointGroupCreate (int max_size);
    +01165 
    +01172 ODE_API void dJointGroupDestroy (dJointGroupID);
    +01173 
    +01181 ODE_API void dJointGroupEmpty (dJointGroupID);
    +01182 
    +01196 ODE_API void dJointAttach (dJointID, dBodyID body1, dBodyID body2);
    +01197 
    +01202 ODE_API void dJointSetData (dJointID, void *data);
    +01203 
    +01208 ODE_API void *dJointGetData (dJointID);
    +01209 
    +01224 ODE_API int dJointGetType (dJointID);
    +01225 
    +01236 ODE_API dBodyID dJointGetBody (dJointID, int index);
    +01237 
    +01245 ODE_API void dJointSetFeedback (dJointID, dJointFeedback *);
    +01246 
    +01251 ODE_API dJointFeedback *dJointGetFeedback (dJointID);
    +01252 
    +01260 ODE_API void dJointSetBallAnchor (dJointID, dReal x, dReal y, dReal z);
    +01261 
    +01266 ODE_API void dJointSetBallAnchor2 (dJointID, dReal x, dReal y, dReal z);
    +01267 
    +01272 ODE_API void dJointSetBallParam (dJointID, int parameter, dReal value);
    +01273 
    +01278 ODE_API void dJointSetHingeAnchor (dJointID, dReal x, dReal y, dReal z);
    +01279 
    +01280 ODE_API void dJointSetHingeAnchorDelta (dJointID, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az);
    +01281 
    +01286 ODE_API void dJointSetHingeAxis (dJointID, dReal x, dReal y, dReal z);
    +01287 
    +01292 ODE_API void dJointSetHingeParam (dJointID, int parameter, dReal value);
    +01293 
    +01302 ODE_API void dJointAddHingeTorque(dJointID joint, dReal torque);
    +01303 
    +01308 ODE_API void dJointSetSliderAxis (dJointID, dReal x, dReal y, dReal z);
    +01309 
    +01313 ODE_API void dJointSetSliderAxisDelta (dJointID, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az);
    +01314 
    +01319 ODE_API void dJointSetSliderParam (dJointID, int parameter, dReal value);
    +01320 
    +01329 ODE_API void dJointAddSliderForce(dJointID joint, dReal force);
    +01330 
    +01335 ODE_API void dJointSetHinge2Anchor (dJointID, dReal x, dReal y, dReal z);
    +01336 
    +01341 ODE_API void dJointSetHinge2Axis1 (dJointID, dReal x, dReal y, dReal z);
    +01342 
    +01347 ODE_API void dJointSetHinge2Axis2 (dJointID, dReal x, dReal y, dReal z);
    +01348 
    +01353 ODE_API void dJointSetHinge2Param (dJointID, int parameter, dReal value);
    +01354 
    +01361 ODE_API void dJointAddHinge2Torques(dJointID joint, dReal torque1, dReal torque2);
    +01362 
    +01367 ODE_API void dJointSetUniversalAnchor (dJointID, dReal x, dReal y, dReal z);
    +01368 
    +01373 ODE_API void dJointSetUniversalAxis1 (dJointID, dReal x, dReal y, dReal z);
    +01374 
    +01379 ODE_API void dJointSetUniversalAxis2 (dJointID, dReal x, dReal y, dReal z);
    +01380 
    +01385 ODE_API void dJointSetUniversalParam (dJointID, int parameter, dReal value);
    +01386 
    +01393 ODE_API void dJointAddUniversalTorques(dJointID joint, dReal torque1, dReal torque2);
    +01394 
    +01395 
    +01400 ODE_API void dJointSetPRAnchor (dJointID, dReal x, dReal y, dReal z);
    +01401 
    +01406 ODE_API void dJointSetPRAxis1 (dJointID, dReal x, dReal y, dReal z);
    +01407 
    +01412 ODE_API void dJointSetPRAxis2 (dJointID, dReal x, dReal y, dReal z);
    +01413 
    +01420 ODE_API void dJointSetPRParam (dJointID, int parameter, dReal value);
    +01421 
    +01430 ODE_API void dJointAddPRTorque (dJointID j, dReal torque);
    +01431 
    +01432 
    +01439 ODE_API void dJointSetFixed (dJointID);
    +01440 
    +01441 /*
    +01442  * @brief Sets joint parameter
    +01443  *
    +01444  * @ingroup joints
    +01445  */
    +01446 ODE_API void dJointSetFixedParam (dJointID, int parameter, dReal value);
    +01447 
    +01453 ODE_API void dJointSetAMotorNumAxes (dJointID, int num);
    +01454 
    +01459 ODE_API void dJointSetAMotorAxis (dJointID, int anum, int rel,
    +01460            dReal x, dReal y, dReal z);
    +01461 
    +01471 ODE_API void dJointSetAMotorAngle (dJointID, int anum, dReal angle);
    +01472 
    +01477 ODE_API void dJointSetAMotorParam (dJointID, int parameter, dReal value);
    +01478 
    +01483 ODE_API void dJointSetAMotorMode (dJointID, int mode);
    +01484 
    +01493 ODE_API void dJointAddAMotorTorques (dJointID, dReal torque1, dReal torque2, dReal torque3);
    +01494 
    +01500 ODE_API void dJointSetLMotorNumAxes (dJointID, int num);
    +01501 
    +01513 ODE_API void dJointSetLMotorAxis (dJointID, int anum, int rel, dReal x, dReal y, dReal z);
    +01514 
    +01519 ODE_API void dJointSetLMotorParam (dJointID, int parameter, dReal value);
    +01520 
    +01524 ODE_API void dJointSetPlane2DXParam (dJointID, int parameter, dReal value);
    +01525 
    +01530 ODE_API void dJointSetPlane2DYParam (dJointID, int parameter, dReal value);
    +01531 
    +01535 ODE_API void dJointSetPlane2DAngleParam (dJointID, int parameter, dReal value);
    +01536 
    +01543 ODE_API void dJointGetBallAnchor (dJointID, dVector3 result);
    +01544 
    +01555 ODE_API void dJointGetBallAnchor2 (dJointID, dVector3 result);
    +01556 
    +01561 ODE_API dReal dJointGetBallParam (dJointID, int parameter);
    +01562 
    +01570 ODE_API void dJointGetHingeAnchor (dJointID, dVector3 result);
    +01571 
    +01580 ODE_API void dJointGetHingeAnchor2 (dJointID, dVector3 result);
    +01581 
    +01586 ODE_API void dJointGetHingeAxis (dJointID, dVector3 result);
    +01587 
    +01592 ODE_API dReal dJointGetHingeParam (dJointID, int parameter);
    +01593 
    +01604 ODE_API dReal dJointGetHingeAngle (dJointID);
    +01605 
    +01610 ODE_API dReal dJointGetHingeAngleRate (dJointID);
    +01611 
    +01619 ODE_API dReal dJointGetSliderPosition (dJointID);
    +01620 
    +01625 ODE_API dReal dJointGetSliderPositionRate (dJointID);
    +01626 
    +01631 ODE_API void dJointGetSliderAxis (dJointID, dVector3 result);
    +01632 
    +01637 ODE_API dReal dJointGetSliderParam (dJointID, int parameter);
    +01638 
    +01645 ODE_API void dJointGetHinge2Anchor (dJointID, dVector3 result);
    +01646 
    +01655 ODE_API void dJointGetHinge2Anchor2 (dJointID, dVector3 result);
    +01656 
    +01661 ODE_API void dJointGetHinge2Axis1 (dJointID, dVector3 result);
    +01662 
    +01667 ODE_API void dJointGetHinge2Axis2 (dJointID, dVector3 result);
    +01668 
    +01673 ODE_API dReal dJointGetHinge2Param (dJointID, int parameter);
    +01674 
    +01679 ODE_API dReal dJointGetHinge2Angle1 (dJointID);
    +01680 
    +01685 ODE_API dReal dJointGetHinge2Angle1Rate (dJointID);
    +01686 
    +01691 ODE_API dReal dJointGetHinge2Angle2Rate (dJointID);
    +01692 
    +01699 ODE_API void dJointGetUniversalAnchor (dJointID, dVector3 result);
    +01700 
    +01714 ODE_API void dJointGetUniversalAnchor2 (dJointID, dVector3 result);
    +01715 
    +01720 ODE_API void dJointGetUniversalAxis1 (dJointID, dVector3 result);
    +01721 
    +01726 ODE_API void dJointGetUniversalAxis2 (dJointID, dVector3 result);
    +01727 
    +01728 
    +01733 ODE_API dReal dJointGetUniversalParam (dJointID, int parameter);
    +01734 
    +01746 ODE_API void dJointGetUniversalAngles (dJointID, dReal *angle1, dReal *angle2);
    +01747 
    +01752 ODE_API dReal dJointGetUniversalAngle1 (dJointID);
    +01753 
    +01758 ODE_API dReal dJointGetUniversalAngle2 (dJointID);
    +01759 
    +01764 ODE_API dReal dJointGetUniversalAngle1Rate (dJointID);
    +01765 
    +01770 ODE_API dReal dJointGetUniversalAngle2Rate (dJointID);
    +01771 
    +01772 
    +01773 
    +01780 ODE_API void dJointGetPRAnchor (dJointID, dVector3 result);
    +01781 
    +01793 ODE_API dReal dJointGetPRPosition (dJointID);
    +01794 
    +01800 ODE_API dReal dJointGetPRPositionRate (dJointID);
    +01801 
    +01802 
    +01807 ODE_API void dJointGetPRAxis1 (dJointID, dVector3 result);
    +01808 
    +01813 ODE_API void dJointGetPRAxis2 (dJointID, dVector3 result);
    +01814 
    +01819 ODE_API dReal dJointGetPRParam (dJointID, int parameter);
    +01820 
    +01821 
    +01822 
    +01831 ODE_API int dJointGetAMotorNumAxes (dJointID);
    +01832 
    +01842 ODE_API void dJointGetAMotorAxis (dJointID, int anum, dVector3 result);
    +01843 
    +01860 ODE_API int dJointGetAMotorAxisRel (dJointID, int anum);
    +01861 
    +01870 ODE_API dReal dJointGetAMotorAngle (dJointID, int anum);
    +01871 
    +01880 ODE_API dReal dJointGetAMotorAngleRate (dJointID, int anum);
    +01881 
    +01886 ODE_API dReal dJointGetAMotorParam (dJointID, int parameter);
    +01887 
    +01901 ODE_API int dJointGetAMotorMode (dJointID);
    +01902 
    +01907 ODE_API int dJointGetLMotorNumAxes (dJointID);
    +01908 
    +01913 ODE_API void dJointGetLMotorAxis (dJointID, int anum, dVector3 result);
    +01914 
    +01919 ODE_API dReal dJointGetLMotorParam (dJointID, int parameter);
    +01920 
    +01925 ODE_API dReal dJointGetFixedParam (dJointID, int parameter);
    +01926 
    +01927 
    +01931 ODE_API dJointID dConnectingJoint (dBodyID, dBodyID);
    +01932 
    +01936 ODE_API int dConnectingJointList (dBodyID, dBodyID, dJointID*);
    +01937 
    +01944 ODE_API int dAreConnected (dBodyID, dBodyID);
    +01945 
    +01959 ODE_API int dAreConnectedExcluding (dBodyID body1, dBodyID body2, int joint_type);
    +01960 
    +01961 
    +01962 #ifdef __cplusplus
    +01963 }
    +01964 #endif
    +01965 
    +01966 #endif
    +

    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/ode_8h-source.html b/libraries/ode-0.9/docs/ode_8h-source.html new file mode 100644 index 0000000000..6b083e0965 --- /dev/null +++ b/libraries/ode-0.9/docs/ode_8h-source.html @@ -0,0 +1,67 @@ + + +Open Dynamics Engine: ode.h Source File + + + + + +

    ode.h

    00001 /*************************************************************************
    +00002  *                                                                       *
    +00003  * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
    +00004  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
    +00005  *                                                                       *
    +00006  * This library is free software; you can redistribute it and/or         *
    +00007  * modify it under the terms of EITHER:                                  *
    +00008  *   (1) The GNU Lesser General Public License as published by the Free  *
    +00009  *       Software Foundation; either version 2.1 of the License, or (at  *
    +00010  *       your option) any later version. The text of the GNU Lesser      *
    +00011  *       General Public License is included with this library in the     *
    +00012  *       file LICENSE.TXT.                                               *
    +00013  *   (2) The BSD-style license that is included with this library in     *
    +00014  *       the file LICENSE-BSD.TXT.                                       *
    +00015  *                                                                       *
    +00016  * This library is distributed in the hope that it will be useful,       *
    +00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
    +00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
    +00019  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
    +00020  *                                                                       *
    +00021  *************************************************************************/
    +00022 
    +00023 #ifndef _ODE_ODE_H_
    +00024 #define _ODE_ODE_H_
    +00025 
    +00026 /* include *everything* here */
    +00027 
    +00028 #include <ode/config.h>
    +00029 #include <ode/compatibility.h>
    +00030 #include <ode/common.h>
    +00031 #include <ode/contact.h>
    +00032 #include <ode/error.h>
    +00033 #include <ode/memory.h>
    +00034 #include <ode/odemath.h>
    +00035 #include <ode/matrix.h>
    +00036 #include <ode/timer.h>
    +00037 #include <ode/rotation.h>
    +00038 #include <ode/mass.h>
    +00039 #include <ode/misc.h>
    +00040 #include <ode/objects.h>
    +00041 #include <ode/odecpp.h>
    +00042 #include <ode/collision_space.h>
    +00043 #include <ode/collision.h>
    +00044 #include <ode/odecpp_collision.h>
    +00045 #include <ode/export-dif.h>
    +00046 
    +00047 #endif
    +

    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/odecpp_8h-source.html b/libraries/ode-0.9/docs/odecpp_8h-source.html new file mode 100644 index 0000000000..33c6dacf5f --- /dev/null +++ b/libraries/ode-0.9/docs/odecpp_8h-source.html @@ -0,0 +1,732 @@ + + +Open Dynamics Engine: odecpp.h Source File + + + + + +

    odecpp.h

    00001 /*************************************************************************
    +00002  *                          *
    +00003  * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.    *
    +00004  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org    *
    +00005  *                          *
    +00006  * This library is free software; you can redistribute it and/or   *
    +00007  * modify it under the terms of EITHER:             *
    +00008  *   (1) The GNU Lesser General Public License as published by the Free  *
    +00009  *  Software Foundation; either version 2.1 of the License, or (at  *
    +00010  *  your option) any later version. The text of the GNU Lesser  *
    +00011  *  General Public License is included with this library in the    *
    +00012  *  file LICENSE.TXT.                   *
    +00013  *   (2) The BSD-style license that is included with this library in  *
    +00014  *  the file LICENSE-BSD.TXT.              *
    +00015  *                          *
    +00016  * This library is distributed in the hope that it will be useful,    *
    +00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of  *
    +00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
    +00019  * LICENSE.TXT and LICENSE-BSD.TXT for more details.         *
    +00020  *                          *
    +00021  *************************************************************************/
    +00022 
    +00023 /* C++ interface for non-collision stuff */
    +00024 
    +00025 
    +00026 #ifndef _ODE_ODECPP_H_
    +00027 #define _ODE_ODECPP_H_
    +00028 #ifdef __cplusplus
    +00029 
    +00030 #include <ode/error.h>
    +00031 
    +00032 
    +00033 class dWorld {
    +00034   dWorldID _id;
    +00035 
    +00036   // intentionally undefined, don't use these
    +00037   dWorld (const dWorld &);
    +00038   void operator= (const dWorld &);
    +00039 
    +00040 public:
    +00041   dWorld()
    +00042     { _id = dWorldCreate(); }
    +00043   ~dWorld()
    +00044     { dWorldDestroy (_id); }
    +00045 
    +00046   dWorldID id() const
    +00047     { return _id; }
    +00048   operator dWorldID() const
    +00049     { return _id; }
    +00050 
    +00051   void setGravity (dReal x, dReal y, dReal z)
    +00052     { dWorldSetGravity (_id,x,y,z); }
    +00053   void getGravity (dVector3 g) const
    +00054     { dWorldGetGravity (_id,g); }
    +00055 
    +00056   void setERP (dReal erp)
    +00057     { dWorldSetERP(_id, erp); }
    +00058   dReal getERP() const
    +00059     { return dWorldGetERP(_id); }
    +00060 
    +00061   void setCFM (dReal cfm)
    +00062     { dWorldSetCFM(_id, cfm); }
    +00063   dReal getCFM() const
    +00064     { return dWorldGetCFM(_id); }
    +00065 
    +00066   void step (dReal stepsize)
    +00067     { dWorldStep (_id,stepsize); }
    +00068 
    +00069   void stepFast1 (dReal stepsize, int maxiterations)
    +00070     { dWorldStepFast1 (_id,stepsize,maxiterations); }
    +00071   void setAutoEnableDepthSF1(dWorldID, int depth)
    +00072     { dWorldSetAutoEnableDepthSF1 (_id, depth); }
    +00073   int getAutoEnableDepthSF1(dWorldID)
    +00074     { return dWorldGetAutoEnableDepthSF1 (_id); }
    +00075 
    +00076   void  setAutoDisableLinearThreshold (dReal threshold) 
    +00077     { dWorldSetAutoDisableLinearThreshold (_id,threshold); }
    +00078   dReal getAutoDisableLinearThreshold()
    +00079     { return dWorldGetAutoDisableLinearThreshold (_id); }
    +00080   void setAutoDisableAngularThreshold (dReal threshold)
    +00081     { dWorldSetAutoDisableAngularThreshold (_id,threshold); }
    +00082   dReal getAutoDisableAngularThreshold()
    +00083     { return dWorldGetAutoDisableAngularThreshold (_id); }
    +00084   void setAutoDisableSteps (int steps)
    +00085     { dWorldSetAutoDisableSteps (_id,steps); }
    +00086   int getAutoDisableSteps()
    +00087     { return dWorldGetAutoDisableSteps (_id); }
    +00088   void setAutoDisableTime (dReal time)
    +00089     { dWorldSetAutoDisableTime (_id,time); }
    +00090   dReal getAutoDisableTime()
    +00091     { return dWorldGetAutoDisableTime (_id); }
    +00092   void setAutoDisableFlag (int do_auto_disable)
    +00093     { dWorldSetAutoDisableFlag (_id,do_auto_disable); }
    +00094   int getAutoDisableFlag()
    +00095     { return dWorldGetAutoDisableFlag (_id); }
    +00096 
    +00097   void impulseToForce (dReal stepsize, dReal ix, dReal iy, dReal iz,
    +00098              dVector3 force)
    +00099     { dWorldImpulseToForce (_id,stepsize,ix,iy,iz,force); }
    +00100 };
    +00101 
    +00102 
    +00103 class dBody {
    +00104   dBodyID _id;
    +00105 
    +00106   // intentionally undefined, don't use these
    +00107   dBody (const dBody &);
    +00108   void operator= (const dBody &);
    +00109 
    +00110 public:
    +00111   dBody()
    +00112     { _id = 0; }
    +00113   dBody (dWorldID world)
    +00114     { _id = dBodyCreate (world); }
    +00115   ~dBody()
    +00116     { if (_id) dBodyDestroy (_id); }
    +00117 
    +00118   void create (dWorldID world) {
    +00119     if (_id) dBodyDestroy (_id);
    +00120     _id = dBodyCreate (world);
    +00121   }
    +00122 
    +00123   dBodyID id() const
    +00124     { return _id; }
    +00125   operator dBodyID() const
    +00126     { return _id; }
    +00127 
    +00128   void setData (void *data)
    +00129     { dBodySetData (_id,data); }
    +00130   void *getData() const
    +00131     { return dBodyGetData (_id); }
    +00132 
    +00133   void setPosition (dReal x, dReal y, dReal z)
    +00134     { dBodySetPosition (_id,x,y,z); }
    +00135   void setRotation (const dMatrix3 R)
    +00136     { dBodySetRotation (_id,R); }
    +00137   void setQuaternion (const dQuaternion q)
    +00138     { dBodySetQuaternion (_id,q); }
    +00139   void setLinearVel  (dReal x, dReal y, dReal z)
    +00140     { dBodySetLinearVel (_id,x,y,z); }
    +00141   void setAngularVel (dReal x, dReal y, dReal z)
    +00142     { dBodySetAngularVel (_id,x,y,z); }
    +00143 
    +00144   const dReal * getPosition() const
    +00145     { return dBodyGetPosition (_id); }
    +00146   const dReal * getRotation() const
    +00147     { return dBodyGetRotation (_id); }
    +00148   const dReal * getQuaternion() const
    +00149     { return dBodyGetQuaternion (_id); }
    +00150   const dReal * getLinearVel() const
    +00151     { return dBodyGetLinearVel (_id); }
    +00152   const dReal * getAngularVel() const
    +00153     { return dBodyGetAngularVel (_id); }
    +00154 
    +00155   void setMass (const dMass *mass)
    +00156     { dBodySetMass (_id,mass); }
    +00157   void getMass (dMass *mass) const
    +00158     { dBodyGetMass (_id,mass); }
    +00159 
    +00160   void addForce (dReal fx, dReal fy, dReal fz)
    +00161     { dBodyAddForce (_id, fx, fy, fz); }
    +00162   void addTorque (dReal fx, dReal fy, dReal fz)
    +00163     { dBodyAddTorque (_id, fx, fy, fz); }
    +00164   void addRelForce (dReal fx, dReal fy, dReal fz)
    +00165     { dBodyAddRelForce (_id, fx, fy, fz); }
    +00166   void addRelTorque (dReal fx, dReal fy, dReal fz)
    +00167     { dBodyAddRelTorque (_id, fx, fy, fz); }
    +00168   void addForceAtPos (dReal fx, dReal fy, dReal fz,
    +00169             dReal px, dReal py, dReal pz)
    +00170     { dBodyAddForceAtPos (_id, fx, fy, fz, px, py, pz); }
    +00171   void addForceAtRelPos (dReal fx, dReal fy, dReal fz,
    +00172             dReal px, dReal py, dReal pz)
    +00173     { dBodyAddForceAtRelPos (_id, fx, fy, fz, px, py, pz); }
    +00174   void addRelForceAtPos (dReal fx, dReal fy, dReal fz,
    +00175           dReal px, dReal py, dReal pz)
    +00176     { dBodyAddRelForceAtPos (_id, fx, fy, fz, px, py, pz); }
    +00177   void addRelForceAtRelPos (dReal fx, dReal fy, dReal fz,
    +00178              dReal px, dReal py, dReal pz)
    +00179     { dBodyAddRelForceAtRelPos (_id, fx, fy, fz, px, py, pz); }
    +00180 
    +00181   const dReal * getForce() const
    +00182     { return dBodyGetForce(_id); }
    +00183   const dReal * getTorque() const
    +00184     { return dBodyGetTorque(_id); }
    +00185   void setForce (dReal x, dReal y, dReal z)
    +00186     { dBodySetForce (_id,x,y,z); }
    +00187   void setTorque (dReal x, dReal y, dReal z)
    +00188     { dBodySetTorque (_id,x,y,z); }
    +00189 
    +00190   void enable()
    +00191     { dBodyEnable (_id); }
    +00192   void disable()
    +00193     { dBodyDisable (_id); }
    +00194   int isEnabled() const
    +00195     { return dBodyIsEnabled (_id); }
    +00196 
    +00197   void getRelPointPos (dReal px, dReal py, dReal pz, dVector3 result) const
    +00198     { dBodyGetRelPointPos (_id, px, py, pz, result); }
    +00199   void getRelPointVel (dReal px, dReal py, dReal pz, dVector3 result) const
    +00200     { dBodyGetRelPointVel (_id, px, py, pz, result); }
    +00201   void getPointVel (dReal px, dReal py, dReal pz, dVector3 result) const
    +00202     { dBodyGetPointVel (_id,px,py,pz,result); }
    +00203   void getPosRelPoint (dReal px, dReal py, dReal pz, dVector3 result) const
    +00204     { dBodyGetPosRelPoint (_id,px,py,pz,result); }
    +00205   void vectorToWorld (dReal px, dReal py, dReal pz, dVector3 result) const
    +00206     { dBodyVectorToWorld (_id,px,py,pz,result); }
    +00207   void vectorFromWorld (dReal px, dReal py, dReal pz, dVector3 result) const
    +00208     { dBodyVectorFromWorld (_id,px,py,pz,result); }
    +00209 
    +00210   void setFiniteRotationMode (int mode)
    +00211     { dBodySetFiniteRotationMode (_id, mode); }
    +00212   void setFiniteRotationAxis (dReal x, dReal y, dReal z)
    +00213     { dBodySetFiniteRotationAxis (_id, x, y, z); }
    +00214 
    +00215   int getFiniteRotationMode() const
    +00216     { return dBodyGetFiniteRotationMode (_id); }
    +00217   void getFiniteRotationAxis (dVector3 result) const
    +00218     { dBodyGetFiniteRotationAxis (_id, result); }
    +00219 
    +00220   int getNumJoints() const
    +00221     { return dBodyGetNumJoints (_id); }
    +00222   dJointID getJoint (int index) const
    +00223     { return dBodyGetJoint (_id, index); }
    +00224 
    +00225   void setGravityMode (int mode)
    +00226     { dBodySetGravityMode (_id,mode); }
    +00227   int getGravityMode() const
    +00228     { return dBodyGetGravityMode (_id); }
    +00229 
    +00230   int isConnectedTo (dBodyID body) const
    +00231     { return dAreConnected (_id, body); }
    +00232 
    +00233   void  setAutoDisableLinearThreshold (dReal threshold) 
    +00234     { dBodySetAutoDisableLinearThreshold (_id,threshold); }
    +00235   dReal getAutoDisableLinearThreshold()
    +00236     { return dBodyGetAutoDisableLinearThreshold (_id); }
    +00237   void setAutoDisableAngularThreshold (dReal threshold)
    +00238     { dBodySetAutoDisableAngularThreshold (_id,threshold); }
    +00239   dReal getAutoDisableAngularThreshold()
    +00240     { return dBodyGetAutoDisableAngularThreshold (_id); }
    +00241   void setAutoDisableSteps (int steps)
    +00242     { dBodySetAutoDisableSteps (_id,steps); }
    +00243   int getAutoDisableSteps()
    +00244     { return dBodyGetAutoDisableSteps (_id); }
    +00245   void setAutoDisableTime (dReal time)
    +00246     { dBodySetAutoDisableTime (_id,time); }
    +00247   dReal getAutoDisableTime()
    +00248     { return dBodyGetAutoDisableTime (_id); }
    +00249   void setAutoDisableFlag (int do_auto_disable)
    +00250     { dBodySetAutoDisableFlag (_id,do_auto_disable); }
    +00251   int getAutoDisableFlag()
    +00252     { return dBodyGetAutoDisableFlag (_id); }
    +00253 };
    +00254 
    +00255 
    +00256 class dJointGroup {
    +00257   dJointGroupID _id;
    +00258 
    +00259   // intentionally undefined, don't use these
    +00260   dJointGroup (const dJointGroup &);
    +00261   void operator= (const dJointGroup &);
    +00262 
    +00263 public:
    +00264   dJointGroup (int dummy_arg=0)
    +00265     { _id = dJointGroupCreate (0); }
    +00266   ~dJointGroup()
    +00267     { dJointGroupDestroy (_id); }
    +00268   void create (int dummy_arg=0) {
    +00269     if (_id) dJointGroupDestroy (_id);
    +00270     _id = dJointGroupCreate (0);
    +00271   }
    +00272 
    +00273   dJointGroupID id() const
    +00274     { return _id; }
    +00275   operator dJointGroupID() const
    +00276     { return _id; }
    +00277 
    +00278   void empty()
    +00279     { dJointGroupEmpty (_id); }
    +00280 };
    +00281 
    +00282 
    +00283 class dJoint {
    +00284 private:
    +00285   // intentionally undefined, don't use these
    +00286   dJoint (const dJoint &) ;
    +00287   void operator= (const dJoint &);
    +00288 
    +00289 protected:
    +00290   dJointID _id;
    +00291 
    +00292 public:
    +00293   dJoint()
    +00294     { _id = 0; }
    +00295   ~dJoint()
    +00296     { if (_id) dJointDestroy (_id); }
    +00297 
    +00298   dJointID id() const
    +00299     { return _id; }
    +00300   operator dJointID() const
    +00301     { return _id; }
    +00302 
    +00303   void attach (dBodyID body1, dBodyID body2)
    +00304     { dJointAttach (_id, body1, body2); }
    +00305 
    +00306   void setData (void *data)
    +00307     { dJointSetData (_id, data); }
    +00308   void *getData() const
    +00309     { return dJointGetData (_id); }
    +00310 
    +00311   int getType() const
    +00312     { return dJointGetType (_id); }
    +00313 
    +00314   dBodyID getBody (int index) const
    +00315     { return dJointGetBody (_id, index); }
    +00316 
    +00317   void setFeedback(dJointFeedback *fb)
    +00318     { dJointSetFeedback(_id, fb); }
    +00319   dJointFeedback *getFeedback() const
    +00320     { return dJointGetFeedback(_id); }
    +00321 };
    +00322 
    +00323 
    +00324 class dBallJoint : public dJoint {
    +00325 private:
    +00326   // intentionally undefined, don't use these
    +00327   dBallJoint (const dBallJoint &);
    +00328   void operator= (const dBallJoint &);
    +00329 
    +00330 public:
    +00331   dBallJoint() { }
    +00332   dBallJoint (dWorldID world, dJointGroupID group=0)
    +00333     { _id = dJointCreateBall (world, group); }
    +00334 
    +00335   void create (dWorldID world, dJointGroupID group=0) {
    +00336     if (_id) dJointDestroy (_id);
    +00337     _id = dJointCreateBall (world, group);
    +00338   }
    +00339 
    +00340   void setAnchor (dReal x, dReal y, dReal z)
    +00341     { dJointSetBallAnchor (_id, x, y, z); }
    +00342   void getAnchor (dVector3 result) const
    +00343     { dJointGetBallAnchor (_id, result); }
    +00344   void getAnchor2 (dVector3 result) const
    +00345     { dJointGetBallAnchor2 (_id, result); }
    +00346   void setParam (int parameter, dReal value)
    +00347     { dJointSetBallParam (_id, parameter, value); }
    +00348   dReal getParam (int parameter) const
    +00349     { return dJointGetBallParam (_id, parameter); }
    +00350 } ;
    +00351 
    +00352 
    +00353 class dHingeJoint : public dJoint {
    +00354   // intentionally undefined, don't use these
    +00355   dHingeJoint (const dHingeJoint &);
    +00356   void operator = (const dHingeJoint &);
    +00357 
    +00358 public:
    +00359   dHingeJoint() { }
    +00360   dHingeJoint (dWorldID world, dJointGroupID group=0)
    +00361     { _id = dJointCreateHinge (world, group); }
    +00362 
    +00363   void create (dWorldID world, dJointGroupID group=0) {
    +00364     if (_id) dJointDestroy (_id);
    +00365     _id = dJointCreateHinge (world, group);
    +00366   }
    +00367 
    +00368   void setAnchor (dReal x, dReal y, dReal z)
    +00369     { dJointSetHingeAnchor (_id, x, y, z); }
    +00370   void getAnchor (dVector3 result) const
    +00371     { dJointGetHingeAnchor (_id, result); }
    +00372   void getAnchor2 (dVector3 result) const
    +00373     { dJointGetHingeAnchor2 (_id, result); }
    +00374 
    +00375   void setAxis (dReal x, dReal y, dReal z)
    +00376     { dJointSetHingeAxis (_id, x, y, z); }
    +00377   void getAxis (dVector3 result) const
    +00378     { dJointGetHingeAxis (_id, result); }
    +00379 
    +00380   dReal getAngle() const
    +00381     { return dJointGetHingeAngle (_id); }
    +00382   dReal getAngleRate() const
    +00383     { return dJointGetHingeAngleRate (_id); }
    +00384 
    +00385   void setParam (int parameter, dReal value)
    +00386     { dJointSetHingeParam (_id, parameter, value); }
    +00387   dReal getParam (int parameter) const
    +00388     { return dJointGetHingeParam (_id, parameter); }
    +00389 
    +00390   void addTorque (dReal torque)
    +00391    { dJointAddHingeTorque(_id, torque); }
    +00392 };
    +00393 
    +00394 
    +00395 class dSliderJoint : public dJoint {
    +00396   // intentionally undefined, don't use these
    +00397   dSliderJoint (const dSliderJoint &);
    +00398   void operator = (const dSliderJoint &);
    +00399 
    +00400 public:
    +00401   dSliderJoint() { }
    +00402   dSliderJoint (dWorldID world, dJointGroupID group=0)
    +00403     { _id = dJointCreateSlider (world, group); }
    +00404 
    +00405   void create (dWorldID world, dJointGroupID group=0) {
    +00406     if (_id) dJointDestroy (_id);
    +00407     _id = dJointCreateSlider (world, group);
    +00408   }
    +00409 
    +00410   void setAxis (dReal x, dReal y, dReal z)
    +00411     { dJointSetSliderAxis (_id, x, y, z); }
    +00412   void getAxis (dVector3 result) const
    +00413     { dJointGetSliderAxis (_id, result); }
    +00414 
    +00415   dReal getPosition() const
    +00416     { return dJointGetSliderPosition (_id); }
    +00417   dReal getPositionRate() const
    +00418     { return dJointGetSliderPositionRate (_id); }
    +00419 
    +00420   void setParam (int parameter, dReal value)
    +00421     { dJointSetSliderParam (_id, parameter, value); }
    +00422   dReal getParam (int parameter) const
    +00423     { return dJointGetSliderParam (_id, parameter); }
    +00424 
    +00425   void addForce (dReal force)
    +00426    { dJointAddSliderForce(_id, force); }
    +00427 };
    +00428 
    +00429 
    +00430 class dUniversalJoint : public dJoint {
    +00431   // intentionally undefined, don't use these
    +00432   dUniversalJoint (const dUniversalJoint &);
    +00433   void operator = (const dUniversalJoint &);
    +00434 
    +00435 public:
    +00436   dUniversalJoint() { }
    +00437   dUniversalJoint (dWorldID world, dJointGroupID group=0)
    +00438     { _id = dJointCreateUniversal (world, group); }
    +00439 
    +00440   void create (dWorldID world, dJointGroupID group=0) {
    +00441     if (_id) dJointDestroy (_id);
    +00442     _id = dJointCreateUniversal (world, group);
    +00443   }
    +00444 
    +00445   void setAnchor (dReal x, dReal y, dReal z)
    +00446     { dJointSetUniversalAnchor (_id, x, y, z); }
    +00447   void setAxis1 (dReal x, dReal y, dReal z)
    +00448     { dJointSetUniversalAxis1 (_id, x, y, z); }
    +00449   void setAxis2 (dReal x, dReal y, dReal z)
    +00450     { dJointSetUniversalAxis2 (_id, x, y, z); }
    +00451   void setParam (int parameter, dReal value)
    +00452     { dJointSetUniversalParam (_id, parameter, value); }
    +00453 
    +00454   void getAnchor (dVector3 result) const
    +00455     { dJointGetUniversalAnchor (_id, result); }
    +00456   void getAnchor2 (dVector3 result) const
    +00457     { dJointGetUniversalAnchor2 (_id, result); }
    +00458   void getAxis1 (dVector3 result) const
    +00459     { dJointGetUniversalAxis1 (_id, result); }
    +00460   void getAxis2 (dVector3 result) const
    +00461     { dJointGetUniversalAxis2 (_id, result); }
    +00462   dReal getParam (int parameter) const
    +00463     { return dJointGetUniversalParam (_id, parameter); }
    +00464  void getAngles(dReal *angle1, dReal *angle2) const
    +00465     { dJointGetUniversalAngles (_id, angle1, angle2); }
    +00466 
    +00467   dReal getAngle1() const
    +00468     { return dJointGetUniversalAngle1 (_id); }
    +00469   dReal getAngle1Rate() const
    +00470     { return dJointGetUniversalAngle1Rate (_id); }
    +00471   dReal getAngle2() const
    +00472     { return dJointGetUniversalAngle2 (_id); }
    +00473   dReal getAngle2Rate() const
    +00474     { return dJointGetUniversalAngle2Rate (_id); }
    +00475 
    +00476   void addTorques (dReal torque1, dReal torque2)
    +00477    { dJointAddUniversalTorques(_id, torque1, torque2); }
    +00478 };
    +00479 
    +00480 
    +00481 class dHinge2Joint : public dJoint {
    +00482   // intentionally undefined, don't use these
    +00483   dHinge2Joint (const dHinge2Joint &);
    +00484   void operator = (const dHinge2Joint &);
    +00485 
    +00486 public:
    +00487   dHinge2Joint() { }
    +00488   dHinge2Joint (dWorldID world, dJointGroupID group=0)
    +00489     { _id = dJointCreateHinge2 (world, group); }
    +00490 
    +00491   void create (dWorldID world, dJointGroupID group=0) {
    +00492     if (_id) dJointDestroy (_id);
    +00493     _id = dJointCreateHinge2 (world, group);
    +00494   }
    +00495 
    +00496   void setAnchor (dReal x, dReal y, dReal z)
    +00497     { dJointSetHinge2Anchor (_id, x, y, z); }
    +00498   void setAxis1 (dReal x, dReal y, dReal z)
    +00499     { dJointSetHinge2Axis1 (_id, x, y, z); }
    +00500   void setAxis2 (dReal x, dReal y, dReal z)
    +00501     { dJointSetHinge2Axis2 (_id, x, y, z); }
    +00502 
    +00503   void getAnchor (dVector3 result) const
    +00504     { dJointGetHinge2Anchor (_id, result); }
    +00505   void getAnchor2 (dVector3 result) const
    +00506     { dJointGetHinge2Anchor2 (_id, result); }
    +00507   void getAxis1 (dVector3 result) const
    +00508     { dJointGetHinge2Axis1 (_id, result); }
    +00509   void getAxis2 (dVector3 result) const
    +00510     { dJointGetHinge2Axis2 (_id, result); }
    +00511 
    +00512   dReal getAngle1() const
    +00513     { return dJointGetHinge2Angle1 (_id); }
    +00514   dReal getAngle1Rate() const
    +00515     { return dJointGetHinge2Angle1Rate (_id); }
    +00516   dReal getAngle2Rate() const
    +00517     { return dJointGetHinge2Angle2Rate (_id); }
    +00518 
    +00519   void setParam (int parameter, dReal value)
    +00520     { dJointSetHinge2Param (_id, parameter, value); }
    +00521   dReal getParam (int parameter) const
    +00522     { return dJointGetHinge2Param (_id, parameter); }
    +00523 
    +00524   void addTorques(dReal torque1, dReal torque2)
    +00525    { dJointAddHinge2Torques(_id, torque1, torque2); }
    +00526 };
    +00527 
    +00528 
    +00529 class dPRJoint : public dJoint {
    +00530   dPRJoint (const dPRJoint &);
    +00531   void operator = (const dPRJoint &);
    +00532 
    +00533 public:
    +00534   dPRJoint() { }
    +00535   dPRJoint (dWorldID world, dJointGroupID group=0)
    +00536     { _id = dJointCreatePR (world, group); }
    +00537 
    +00538   void create (dWorldID world, dJointGroupID group=0) {
    +00539     if (_id) dJointDestroy (_id);
    +00540     _id = dJointCreatePR (world, group);
    +00541   }
    +00542 
    +00543   void setAnchor (dReal x, dReal y, dReal z)
    +00544     { dJointSetPRAnchor (_id, x, y, z); }
    +00545   void setAxis1 (dReal x, dReal y, dReal z)
    +00546     { dJointSetPRAxis1 (_id, x, y, z); }
    +00547   void setAxis2 (dReal x, dReal y, dReal z)
    +00548     { dJointSetPRAxis2 (_id, x, y, z); }
    +00549 
    +00550   void getAnchor (dVector3 result) const
    +00551     { dJointGetPRAnchor (_id, result); }
    +00552   void getAxis1 (dVector3 result) const
    +00553     { dJointGetPRAxis1 (_id, result); }
    +00554   void getAxis2 (dVector3 result) const
    +00555     { dJointGetPRAxis2 (_id, result); }
    +00556 
    +00557   dReal getPosition() const
    +00558     { return dJointGetPRPosition (_id); }
    +00559   dReal getPositionRate() const
    +00560     { return dJointGetPRPositionRate (_id); }
    +00561 
    +00562   void setParam (int parameter, dReal value)
    +00563     { dJointSetPRParam (_id, parameter, value); }
    +00564   dReal getParam (int parameter) const
    +00565     { return dJointGetPRParam (_id, parameter); }
    +00566 };
    +00567 
    +00568 
    +00569 class dFixedJoint : public dJoint {
    +00570   // intentionally undefined, don't use these
    +00571   dFixedJoint (const dFixedJoint &);
    +00572   void operator = (const dFixedJoint &);
    +00573 
    +00574 public:
    +00575   dFixedJoint() { }
    +00576   dFixedJoint (dWorldID world, dJointGroupID group=0)
    +00577     { _id = dJointCreateFixed (world, group); }
    +00578 
    +00579   void create (dWorldID world, dJointGroupID group=0) {
    +00580     if (_id) dJointDestroy (_id);
    +00581     _id = dJointCreateFixed (world, group);
    +00582   }
    +00583 
    +00584   void set()
    +00585     { dJointSetFixed (_id); }
    +00586 
    +00587   void setParam (int parameter, dReal value)
    +00588     { dJointSetFixedParam (_id, parameter, value); }
    +00589 
    +00590   dReal getParam (int parameter) const
    +00591     { return dJointGetFixedParam (_id, parameter); }
    +00592 };
    +00593 
    +00594 
    +00595 class dContactJoint : public dJoint {
    +00596   // intentionally undefined, don't use these
    +00597   dContactJoint (const dContactJoint &);
    +00598   void operator = (const dContactJoint &);
    +00599 
    +00600 public:
    +00601   dContactJoint() { }
    +00602   dContactJoint (dWorldID world, dJointGroupID group, dContact *contact)
    +00603     { _id = dJointCreateContact (world, group, contact); }
    +00604 
    +00605   void create (dWorldID world, dJointGroupID group, dContact *contact) {
    +00606     if (_id) dJointDestroy (_id);
    +00607     _id = dJointCreateContact (world, group, contact);
    +00608   }
    +00609 };
    +00610 
    +00611 
    +00612 class dNullJoint : public dJoint {
    +00613   // intentionally undefined, don't use these
    +00614   dNullJoint (const dNullJoint &);
    +00615   void operator = (const dNullJoint &);
    +00616 
    +00617 public:
    +00618   dNullJoint() { }
    +00619   dNullJoint (dWorldID world, dJointGroupID group=0)
    +00620     { _id = dJointCreateNull (world, group); }
    +00621 
    +00622   void create (dWorldID world, dJointGroupID group=0) {
    +00623     if (_id) dJointDestroy (_id);
    +00624     _id = dJointCreateNull (world, group);
    +00625   }
    +00626 };
    +00627 
    +00628 
    +00629 class dAMotorJoint : public dJoint {
    +00630   // intentionally undefined, don't use these
    +00631   dAMotorJoint (const dAMotorJoint &);
    +00632   void operator = (const dAMotorJoint &);
    +00633 
    +00634 public:
    +00635   dAMotorJoint() { }
    +00636   dAMotorJoint (dWorldID world, dJointGroupID group=0)
    +00637     { _id = dJointCreateAMotor (world, group); }
    +00638 
    +00639   void create (dWorldID world, dJointGroupID group=0) {
    +00640     if (_id) dJointDestroy (_id);
    +00641     _id = dJointCreateAMotor (world, group);
    +00642   }
    +00643 
    +00644   void setMode (int mode)
    +00645     { dJointSetAMotorMode (_id, mode); }
    +00646   int getMode() const
    +00647     { return dJointGetAMotorMode (_id); }
    +00648 
    +00649   void setNumAxes (int num)
    +00650     { dJointSetAMotorNumAxes (_id, num); }
    +00651   int getNumAxes() const
    +00652     { return dJointGetAMotorNumAxes (_id); }
    +00653 
    +00654   void setAxis (int anum, int rel, dReal x, dReal y, dReal z)
    +00655     { dJointSetAMotorAxis (_id, anum, rel, x, y, z); }
    +00656   void getAxis (int anum, dVector3 result) const
    +00657     { dJointGetAMotorAxis (_id, anum, result); }
    +00658   int getAxisRel (int anum) const
    +00659     { return dJointGetAMotorAxisRel (_id, anum); }
    +00660 
    +00661   void setAngle (int anum, dReal angle)
    +00662     { dJointSetAMotorAngle (_id, anum, angle); }
    +00663   dReal getAngle (int anum) const
    +00664     { return dJointGetAMotorAngle (_id, anum); }
    +00665   dReal getAngleRate (int anum)
    +00666     { return dJointGetAMotorAngleRate (_id,anum); }
    +00667 
    +00668   void setParam (int parameter, dReal value)
    +00669     { dJointSetAMotorParam (_id, parameter, value); }
    +00670   dReal getParam (int parameter) const
    +00671     { return dJointGetAMotorParam (_id, parameter); }
    +00672 
    +00673   void addTorques(dReal torque1, dReal torque2, dReal torque3)
    +00674    { dJointAddAMotorTorques(_id, torque1, torque2, torque3); }
    +00675 };
    +00676 
    +00677 
    +00678 class dLMotorJoint : public dJoint {
    +00679   // intentionally undefined, don't use these
    +00680   dLMotorJoint (const dLMotorJoint &);
    +00681   void operator = (const dLMotorJoint &);
    +00682 
    +00683 public:
    +00684   dLMotorJoint() { }
    +00685   dLMotorJoint (dWorldID world, dJointGroupID group=0)
    +00686     { _id = dJointCreateLMotor (world, group); }
    +00687 
    +00688   void create (dWorldID world, dJointGroupID group=0) {
    +00689     if (_id) dJointDestroy (_id);
    +00690     _id = dJointCreateLMotor (world, group);
    +00691   }
    +00692 
    +00693   void setNumAxes (int num)
    +00694     { dJointSetLMotorNumAxes (_id, num); }
    +00695   int getNumAxes() const
    +00696     { return dJointGetLMotorNumAxes (_id); }
    +00697 
    +00698   void setAxis (int anum, int rel, dReal x, dReal y, dReal z)
    +00699     { dJointSetLMotorAxis (_id, anum, rel, x, y, z); }
    +00700   void getAxis (int anum, dVector3 result) const
    +00701     { dJointGetLMotorAxis (_id, anum, result); }
    +00702 
    +00703   void setParam (int parameter, dReal value)
    +00704     { dJointSetLMotorParam (_id, parameter, value); }
    +00705   dReal getParam (int parameter) const
    +00706     { return dJointGetLMotorParam (_id, parameter); }
    +00707 };
    +00708 
    +00709 
    +00710 
    +00711 #endif
    +00712 #endif
    +

    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/odecpp__collision_8h-source.html b/libraries/ode-0.9/docs/odecpp__collision_8h-source.html new file mode 100644 index 0000000000..f4943ba891 --- /dev/null +++ b/libraries/ode-0.9/docs/odecpp__collision_8h-source.html @@ -0,0 +1,366 @@ + + +Open Dynamics Engine: odecpp_collision.h Source File + + + + + +

    odecpp_collision.h

    00001 /*************************************************************************
    +00002  *                          *
    +00003  * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.    *
    +00004  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org    *
    +00005  *                          *
    +00006  * This library is free software; you can redistribute it and/or   *
    +00007  * modify it under the terms of EITHER:             *
    +00008  *   (1) The GNU Lesser General Public License as published by the Free  *
    +00009  *  Software Foundation; either version 2.1 of the License, or (at  *
    +00010  *  your option) any later version. The text of the GNU Lesser  *
    +00011  *  General Public License is included with this library in the    *
    +00012  *  file LICENSE.TXT.                   *
    +00013  *   (2) The BSD-style license that is included with this library in  *
    +00014  *  the file LICENSE-BSD.TXT.              *
    +00015  *                          *
    +00016  * This library is distributed in the hope that it will be useful,    *
    +00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of  *
    +00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
    +00019  * LICENSE.TXT and LICENSE-BSD.TXT for more details.         *
    +00020  *                          *
    +00021  *************************************************************************/
    +00022 
    +00023 /* C++ interface for new collision API */
    +00024 
    +00025 
    +00026 #ifndef _ODE_ODECPP_COLLISION_H_
    +00027 #define _ODE_ODECPP_COLLISION_H_
    +00028 #ifdef __cplusplus
    +00029 
    +00030 #include <ode/error.h>
    +00031 
    +00032 
    +00033 class dGeom {
    +00034   // intentionally undefined, don't use these
    +00035   dGeom (dGeom &);
    +00036   void operator= (dGeom &);
    +00037 
    +00038 protected:
    +00039   dGeomID _id;
    +00040 
    +00041 public:
    +00042   dGeom()
    +00043     { _id = 0; }
    +00044   ~dGeom()
    +00045     { if (_id) dGeomDestroy (_id); }
    +00046 
    +00047   dGeomID id() const
    +00048     { return _id; }
    +00049   operator dGeomID() const
    +00050     { return _id; }
    +00051 
    +00052   void destroy() {
    +00053     if (_id) dGeomDestroy (_id);
    +00054     _id = 0;
    +00055   }
    +00056 
    +00057   int getClass() const
    +00058     { return dGeomGetClass (_id); }
    +00059 
    +00060   dSpaceID getSpace() const
    +00061     { return dGeomGetSpace (_id); }
    +00062 
    +00063   void setData (void *data)
    +00064     { dGeomSetData (_id,data); }
    +00065   void *getData() const
    +00066     { return dGeomGetData (_id); }
    +00067 
    +00068   void setBody (dBodyID b)
    +00069     { dGeomSetBody (_id,b); }
    +00070   dBodyID getBody() const
    +00071     { return dGeomGetBody (_id); }
    +00072 
    +00073   void setPosition (dReal x, dReal y, dReal z)
    +00074     { dGeomSetPosition (_id,x,y,z); }
    +00075   const dReal * getPosition() const
    +00076     { return dGeomGetPosition (_id); }
    +00077 
    +00078   void setRotation (const dMatrix3 R)
    +00079     { dGeomSetRotation (_id,R); }
    +00080   const dReal * getRotation() const
    +00081     { return dGeomGetRotation (_id); }
    +00082     
    +00083   void setQuaternion (const dQuaternion quat)
    +00084     { dGeomSetQuaternion (_id,quat); }
    +00085   void getQuaternion (dQuaternion quat) const
    +00086     { dGeomGetQuaternion (_id,quat); }
    +00087 
    +00088   void getAABB (dReal aabb[6]) const
    +00089     { dGeomGetAABB (_id, aabb); }
    +00090 
    +00091   int isSpace()
    +00092     { return dGeomIsSpace (_id); }
    +00093 
    +00094   void setCategoryBits (unsigned long bits)
    +00095     { dGeomSetCategoryBits (_id, bits); }
    +00096   void setCollideBits (unsigned long bits)
    +00097     { dGeomSetCollideBits (_id, bits); }
    +00098   unsigned long getCategoryBits()
    +00099     { return dGeomGetCategoryBits (_id); }
    +00100   unsigned long getCollideBits()
    +00101     { return dGeomGetCollideBits (_id); }
    +00102 
    +00103   void enable()
    +00104     { dGeomEnable (_id); }
    +00105   void disable()
    +00106     { dGeomDisable (_id); }
    +00107   int isEnabled()
    +00108     { return dGeomIsEnabled (_id); }
    +00109 
    +00110   void collide2 (dGeomID g, void *data, dNearCallback *callback)
    +00111     { dSpaceCollide2 (_id,g,data,callback); }
    +00112 };
    +00113 
    +00114 
    +00115 class dSpace : public dGeom {
    +00116   // intentionally undefined, don't use these
    +00117   dSpace (dSpace &);
    +00118   void operator= (dSpace &);
    +00119 
    +00120 protected:
    +00121   // the default constructor is protected so that you
    +00122   // can't instance this class. you must instance one
    +00123   // of its subclasses instead.
    +00124   dSpace () { _id = 0; }
    +00125 
    +00126 public:
    +00127   dSpaceID id() const
    +00128     { return (dSpaceID) _id; }
    +00129   operator dSpaceID() const
    +00130     { return (dSpaceID) _id; }
    +00131 
    +00132   void setCleanup (int mode)
    +00133     { dSpaceSetCleanup (id(), mode); }
    +00134   int getCleanup()
    +00135     { return dSpaceGetCleanup (id()); }
    +00136 
    +00137   void add (dGeomID x)
    +00138     { dSpaceAdd (id(), x); }
    +00139   void remove (dGeomID x)
    +00140     { dSpaceRemove (id(), x); }
    +00141   int query (dGeomID x)
    +00142     { return dSpaceQuery (id(),x); }
    +00143 
    +00144   int getNumGeoms()
    +00145     { return dSpaceGetNumGeoms (id()); }
    +00146   dGeomID getGeom (int i)
    +00147     { return dSpaceGetGeom (id(),i); }
    +00148 
    +00149   void collide (void *data, dNearCallback *callback)
    +00150     { dSpaceCollide (id(),data,callback); }
    +00151 };
    +00152 
    +00153 
    +00154 class dSimpleSpace : public dSpace {
    +00155   // intentionally undefined, don't use these
    +00156   dSimpleSpace (dSimpleSpace &);
    +00157   void operator= (dSimpleSpace &);
    +00158 
    +00159 public:
    +00160   dSimpleSpace (dSpaceID space)
    +00161     { _id = (dGeomID) dSimpleSpaceCreate (space); }
    +00162 };
    +00163 
    +00164 
    +00165 class dHashSpace : public dSpace {
    +00166   // intentionally undefined, don't use these
    +00167   dHashSpace (dHashSpace &);
    +00168   void operator= (dHashSpace &);
    +00169 
    +00170 public:
    +00171   dHashSpace (dSpaceID space)
    +00172     { _id = (dGeomID) dHashSpaceCreate (space); }
    +00173   void setLevels (int minlevel, int maxlevel)
    +00174     { dHashSpaceSetLevels (id(),minlevel,maxlevel); }
    +00175 };
    +00176 
    +00177 
    +00178 class dQuadTreeSpace : public dSpace {
    +00179   // intentionally undefined, don't use these
    +00180   dQuadTreeSpace (dQuadTreeSpace &);
    +00181   void operator= (dQuadTreeSpace &);
    +00182 
    +00183 public:
    +00184   dQuadTreeSpace (dSpaceID space, dVector3 center, dVector3 extents, int depth)
    +00185     { _id = (dGeomID) dQuadTreeSpaceCreate (space,center,extents,depth); }
    +00186 };
    +00187 
    +00188 
    +00189 class dSphere : public dGeom {
    +00190   // intentionally undefined, don't use these
    +00191   dSphere (dSphere &);
    +00192   void operator= (dSphere &);
    +00193 
    +00194 public:
    +00195   dSphere () { }
    +00196   dSphere (dSpaceID space, dReal radius)
    +00197     { _id = dCreateSphere (space, radius); }
    +00198 
    +00199   void create (dSpaceID space, dReal radius) {
    +00200     if (_id) dGeomDestroy (_id);
    +00201     _id = dCreateSphere (space, radius);
    +00202   }
    +00203 
    +00204   void setRadius (dReal radius)
    +00205     { dGeomSphereSetRadius (_id, radius); }
    +00206   dReal getRadius() const
    +00207     { return dGeomSphereGetRadius (_id); }
    +00208 };
    +00209 
    +00210 
    +00211 class dBox : public dGeom {
    +00212   // intentionally undefined, don't use these
    +00213   dBox (dBox &);
    +00214   void operator= (dBox &);
    +00215 
    +00216 public:
    +00217   dBox () { }
    +00218   dBox (dSpaceID space, dReal lx, dReal ly, dReal lz)
    +00219     { _id = dCreateBox (space,lx,ly,lz); }
    +00220 
    +00221   void create (dSpaceID space, dReal lx, dReal ly, dReal lz) {
    +00222     if (_id) dGeomDestroy (_id);
    +00223     _id = dCreateBox (space,lx,ly,lz);
    +00224   }
    +00225 
    +00226   void setLengths (dReal lx, dReal ly, dReal lz)
    +00227     { dGeomBoxSetLengths (_id, lx, ly, lz); }
    +00228   void getLengths (dVector3 result) const
    +00229     { dGeomBoxGetLengths (_id,result); }
    +00230 };
    +00231 
    +00232 
    +00233 class dPlane : public dGeom {
    +00234   // intentionally undefined, don't use these
    +00235   dPlane (dPlane &);
    +00236   void operator= (dPlane &);
    +00237 
    +00238 public:
    +00239   dPlane() { }
    +00240   dPlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d)
    +00241     { _id = dCreatePlane (space,a,b,c,d); }
    +00242 
    +00243   void create (dSpaceID space, dReal a, dReal b, dReal c, dReal d) {
    +00244     if (_id) dGeomDestroy (_id);
    +00245     _id = dCreatePlane (space,a,b,c,d);
    +00246   }
    +00247 
    +00248   void setParams (dReal a, dReal b, dReal c, dReal d)
    +00249     { dGeomPlaneSetParams (_id, a, b, c, d); }
    +00250   void getParams (dVector4 result) const
    +00251     { dGeomPlaneGetParams (_id,result); }
    +00252 };
    +00253 
    +00254 
    +00255 class dCapsule : public dGeom {
    +00256   // intentionally undefined, don't use these
    +00257   dCapsule (dCapsule &);
    +00258   void operator= (dCapsule &);
    +00259 
    +00260 public:
    +00261   dCapsule() { }
    +00262   dCapsule (dSpaceID space, dReal radius, dReal length)
    +00263     { _id = dCreateCapsule (space,radius,length); }
    +00264 
    +00265   void create (dSpaceID space, dReal radius, dReal length) {
    +00266     if (_id) dGeomDestroy (_id);
    +00267     _id = dCreateCapsule (space,radius,length);
    +00268   }
    +00269 
    +00270   void setParams (dReal radius, dReal length)
    +00271     { dGeomCapsuleSetParams (_id, radius, length); }
    +00272   void getParams (dReal *radius, dReal *length) const
    +00273     { dGeomCapsuleGetParams (_id,radius,length); }
    +00274 };
    +00275 
    +00276 
    +00277 class dRay : public dGeom {
    +00278   // intentionally undefined, don't use these
    +00279   dRay (dRay &);
    +00280   void operator= (dRay &);
    +00281 
    +00282 public:
    +00283   dRay() { }
    +00284   dRay (dSpaceID space, dReal length)
    +00285     { _id = dCreateRay (space,length); }
    +00286 
    +00287   void create (dSpaceID space, dReal length) {
    +00288     if (_id) dGeomDestroy (_id);
    +00289     _id = dCreateRay (space,length);
    +00290   }
    +00291 
    +00292   void setLength (dReal length)
    +00293     { dGeomRaySetLength (_id, length); }
    +00294   dReal getLength()
    +00295     { return dGeomRayGetLength (_id); }
    +00296 
    +00297   void set (dReal px, dReal py, dReal pz, dReal dx, dReal dy, dReal dz)
    +00298     { dGeomRaySet (_id, px, py, pz, dx, dy, dz); }
    +00299   void get (dVector3 start, dVector3 dir)
    +00300     { dGeomRayGet (_id, start, dir); }
    +00301 
    +00302   void setParams (int firstContact, int backfaceCull)
    +00303     { dGeomRaySetParams (_id, firstContact, backfaceCull); }
    +00304   void getParams (int *firstContact, int *backfaceCull)
    +00305     { dGeomRayGetParams (_id, firstContact, backfaceCull); }
    +00306   void setClosestHit (int closestHit)
    +00307     { dGeomRaySetClosestHit (_id, closestHit); }
    +00308   int getClosestHit()
    +00309     { return dGeomRayGetClosestHit (_id); }
    +00310 };
    +00311 
    +00312 
    +00313 class dGeomTransform : public dGeom {
    +00314   // intentionally undefined, don't use these
    +00315   dGeomTransform (dGeomTransform &);
    +00316   void operator= (dGeomTransform &);
    +00317 
    +00318 public:
    +00319   dGeomTransform() { }
    +00320   dGeomTransform (dSpaceID space)
    +00321     { _id = dCreateGeomTransform (space); }
    +00322 
    +00323   void create (dSpaceID space=0) {
    +00324     if (_id) dGeomDestroy (_id);
    +00325     _id = dCreateGeomTransform (space);
    +00326   }
    +00327 
    +00328   void setGeom (dGeomID geom)
    +00329     { dGeomTransformSetGeom (_id, geom); }
    +00330   dGeomID getGeom() const
    +00331     { return dGeomTransformGetGeom (_id); }
    +00332 
    +00333   void setCleanup (int mode)
    +00334     { dGeomTransformSetCleanup (_id,mode); }
    +00335   int getCleanup ()
    +00336     { return dGeomTransformGetCleanup (_id); }
    +00337 
    +00338   void setInfo (int mode)
    +00339     { dGeomTransformSetInfo (_id,mode); }
    +00340   int getInfo()
    +00341     { return dGeomTransformGetInfo (_id); }
    +00342 };
    +00343 
    +00344 
    +00345 #endif
    +00346 #endif
    +

    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/odemath_8h-source.html b/libraries/ode-0.9/docs/odemath_8h-source.html new file mode 100644 index 0000000000..b330c60df6 --- /dev/null +++ b/libraries/ode-0.9/docs/odemath_8h-source.html @@ -0,0 +1,350 @@ + + +Open Dynamics Engine: odemath.h Source File + + + + + +

    odemath.h

    00001 /*************************************************************************
    +00002  *                                                                       *
    +00003  * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
    +00004  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
    +00005  *                                                                       *
    +00006  * This library is free software; you can redistribute it and/or         *
    +00007  * modify it under the terms of EITHER:                                  *
    +00008  *   (1) The GNU Lesser General Public License as published by the Free  *
    +00009  *       Software Foundation; either version 2.1 of the License, or (at  *
    +00010  *       your option) any later version. The text of the GNU Lesser      *
    +00011  *       General Public License is included with this library in the     *
    +00012  *       file LICENSE.TXT.                                               *
    +00013  *   (2) The BSD-style license that is included with this library in     *
    +00014  *       the file LICENSE-BSD.TXT.                                       *
    +00015  *                                                                       *
    +00016  * This library is distributed in the hope that it will be useful,       *
    +00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
    +00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
    +00019  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
    +00020  *                                                                       *
    +00021  *************************************************************************/
    +00022 
    +00023 #ifndef _ODE_ODEMATH_H_
    +00024 #define _ODE_ODEMATH_H_
    +00025 
    +00026 #include <ode/common.h>
    +00027 
    +00028 #ifdef __GNUC__
    +00029 #define PURE_INLINE extern inline
    +00030 #else
    +00031 #define PURE_INLINE inline
    +00032 #endif
    +00033 
    +00034 /*
    +00035  * macro to access elements i,j in an NxM matrix A, independent of the
    +00036  * matrix storage convention.
    +00037  */
    +00038 #define dACCESS33(A,i,j) ((A)[(i)*4+(j)])
    +00039 
    +00040 /*
    +00041  * Macro to test for valid floating point values
    +00042  */
    +00043 #define dVALIDVEC3(v) (!(dIsNan(v[0]) || dIsNan(v[1]) || dIsNan(v[2])))
    +00044 #define dVALIDVEC4(v) (!(dIsNan(v[0]) || dIsNan(v[1]) || dIsNan(v[2]) || dIsNan(v[3])))
    +00045 #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])))
    +00046 #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]) ))
    +00047 
    +00048 
    +00049 
    +00050 /*
    +00051  * General purpose vector operations with other vectors or constants.
    +00052  */
    +00053 
    +00054 #define dOP(a,op,b,c) \
    +00055     (a)[0] = ((b)[0]) op ((c)[0]); \
    +00056     (a)[1] = ((b)[1]) op ((c)[1]); \
    +00057     (a)[2] = ((b)[2]) op ((c)[2]);
    +00058 #define dOPC(a,op,b,c) \
    +00059     (a)[0] = ((b)[0]) op (c); \
    +00060     (a)[1] = ((b)[1]) op (c); \
    +00061     (a)[2] = ((b)[2]) op (c);
    +00062 #define dOPE(a,op,b) \
    +00063     (a)[0] op ((b)[0]); \
    +00064     (a)[1] op ((b)[1]); \
    +00065     (a)[2] op ((b)[2]);
    +00066 #define dOPEC(a,op,c) \
    +00067     (a)[0] op (c); \
    +00068     (a)[1] op (c); \
    +00069     (a)[2] op (c);
    +00070 
    +00071 
    +00072 /*
    +00073  * Length, and squared length helpers. dLENGTH returns the length of a dVector3.
    +00074  * dLENGTHSQUARED return the squared length of a dVector3.
    +00075  */
    +00076 
    +00077 #define dLENGTHSQUARED(a) (((a)[0])*((a)[0]) + ((a)[1])*((a)[1]) + ((a)[2])*((a)[2]))
    +00078 
    +00079 #ifdef __cplusplus
    +00080 
    +00081 PURE_INLINE dReal dLENGTH (const dReal *a) { return dSqrt(dLENGTHSQUARED(a)); }
    +00082 
    +00083 #else
    +00084 
    +00085 #define dLENGTH(a) ( dSqrt( ((a)[0])*((a)[0]) + ((a)[1])*((a)[1]) + ((a)[2])*((a)[2]) ) )
    +00086 
    +00087 #endif /* __cplusplus */
    +00088 
    +00089 
    +00090 
    +00091 
    +00092 
    +00093 /*
    +00094  * 3-way dot product. dDOTpq means that elements of `a' and `b' are spaced
    +00095  * p and q indexes apart respectively. dDOT() means dDOT11.
    +00096  * in C++ we could use function templates to get all the versions of these
    +00097  * functions - but on some compilers this will result in sub-optimal code.
    +00098  */
    +00099 
    +00100 #define dDOTpq(a,b,p,q) ((a)[0]*(b)[0] + (a)[p]*(b)[q] + (a)[2*(p)]*(b)[2*(q)])
    +00101 
    +00102 #ifdef __cplusplus
    +00103 
    +00104 PURE_INLINE dReal dDOT   (const dReal *a, const dReal *b) { return dDOTpq(a,b,1,1); }
    +00105 PURE_INLINE dReal dDOT13 (const dReal *a, const dReal *b) { return dDOTpq(a,b,1,3); }
    +00106 PURE_INLINE dReal dDOT31 (const dReal *a, const dReal *b) { return dDOTpq(a,b,3,1); }
    +00107 PURE_INLINE dReal dDOT33 (const dReal *a, const dReal *b) { return dDOTpq(a,b,3,3); }
    +00108 PURE_INLINE dReal dDOT14 (const dReal *a, const dReal *b) { return dDOTpq(a,b,1,4); }
    +00109 PURE_INLINE dReal dDOT41 (const dReal *a, const dReal *b) { return dDOTpq(a,b,4,1); }
    +00110 PURE_INLINE dReal dDOT44 (const dReal *a, const dReal *b) { return dDOTpq(a,b,4,4); }
    +00111 
    +00112 #else
    +00113 
    +00114 #define dDOT(a,b)   dDOTpq(a,b,1,1)
    +00115 #define dDOT13(a,b) dDOTpq(a,b,1,3)
    +00116 #define dDOT31(a,b) dDOTpq(a,b,3,1)
    +00117 #define dDOT33(a,b) dDOTpq(a,b,3,3)
    +00118 #define dDOT14(a,b) dDOTpq(a,b,1,4)
    +00119 #define dDOT41(a,b) dDOTpq(a,b,4,1)
    +00120 #define dDOT44(a,b) dDOTpq(a,b,4,4)
    +00121 
    +00122 #endif /* __cplusplus */
    +00123 
    +00124 
    +00125 /*
    +00126  * cross product, set a = b x c. dCROSSpqr means that elements of `a', `b'
    +00127  * and `c' are spaced p, q and r indexes apart respectively.
    +00128  * dCROSS() means dCROSS111. `op' is normally `=', but you can set it to
    +00129  * +=, -= etc to get other effects.
    +00130  */
    +00131 
    +00132 #define dCROSS(a,op,b,c) \
    +00133 do { \
    +00134   (a)[0] op ((b)[1]*(c)[2] - (b)[2]*(c)[1]); \
    +00135   (a)[1] op ((b)[2]*(c)[0] - (b)[0]*(c)[2]); \
    +00136   (a)[2] op ((b)[0]*(c)[1] - (b)[1]*(c)[0]); \
    +00137 } while(0)
    +00138 #define dCROSSpqr(a,op,b,c,p,q,r) \
    +00139 do { \
    +00140   (a)[  0] op ((b)[  q]*(c)[2*r] - (b)[2*q]*(c)[  r]); \
    +00141   (a)[  p] op ((b)[2*q]*(c)[  0] - (b)[  0]*(c)[2*r]); \
    +00142   (a)[2*p] op ((b)[  0]*(c)[  r] - (b)[  q]*(c)[  0]); \
    +00143 } while(0)
    +00144 #define dCROSS114(a,op,b,c) dCROSSpqr(a,op,b,c,1,1,4)
    +00145 #define dCROSS141(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,1)
    +00146 #define dCROSS144(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,4)
    +00147 #define dCROSS411(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,1)
    +00148 #define dCROSS414(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,4)
    +00149 #define dCROSS441(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,1)
    +00150 #define dCROSS444(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,4)
    +00151 
    +00152 
    +00153 /*
    +00154  * set a 3x3 submatrix of A to a matrix such that submatrix(A)*b = a x b.
    +00155  * A is stored by rows, and has `skip' elements per row. the matrix is
    +00156  * assumed to be already zero, so this does not write zero elements!
    +00157  * if (plus,minus) is (+,-) then a positive version will be written.
    +00158  * if (plus,minus) is (-,+) then a negative version will be written.
    +00159  */
    +00160 
    +00161 #define dCROSSMAT(A,a,skip,plus,minus) \
    +00162 do { \
    +00163   (A)[1] = minus (a)[2]; \
    +00164   (A)[2] = plus (a)[1]; \
    +00165   (A)[(skip)+0] = plus (a)[2]; \
    +00166   (A)[(skip)+2] = minus (a)[0]; \
    +00167   (A)[2*(skip)+0] = minus (a)[1]; \
    +00168   (A)[2*(skip)+1] = plus (a)[0]; \
    +00169 } while(0)
    +00170 
    +00171 
    +00172 /*
    +00173  * compute the distance between two 3D-vectors
    +00174  */
    +00175 
    +00176 #ifdef __cplusplus
    +00177 PURE_INLINE dReal dDISTANCE (const dVector3 a, const dVector3 b)
    +00178    { 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]) ); }
    +00179 #else
    +00180 #define dDISTANCE(a,b) \
    +00181    (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]) ))
    +00182 #endif
    +00183 
    +00184 
    +00185 /*
    +00186  * special case matrix multipication, with operator selection
    +00187  */
    +00188 
    +00189 #define dMULTIPLYOP0_331(A,op,B,C) \
    +00190 do { \
    +00191   (A)[0] op dDOT((B),(C)); \
    +00192   (A)[1] op dDOT((B+4),(C)); \
    +00193   (A)[2] op dDOT((B+8),(C)); \
    +00194 } while(0)
    +00195 #define dMULTIPLYOP1_331(A,op,B,C) \
    +00196 do { \
    +00197   (A)[0] op dDOT41((B),(C)); \
    +00198   (A)[1] op dDOT41((B+1),(C)); \
    +00199   (A)[2] op dDOT41((B+2),(C)); \
    +00200 } while(0)
    +00201 #define dMULTIPLYOP0_133(A,op,B,C) \
    +00202 do { \
    +00203   (A)[0] op dDOT14((B),(C)); \
    +00204   (A)[1] op dDOT14((B),(C+1)); \
    +00205   (A)[2] op dDOT14((B),(C+2)); \
    +00206 } while(0)
    +00207 #define dMULTIPLYOP0_333(A,op,B,C) \
    +00208 do { \
    +00209   (A)[0] op dDOT14((B),(C)); \
    +00210   (A)[1] op dDOT14((B),(C+1)); \
    +00211   (A)[2] op dDOT14((B),(C+2)); \
    +00212   (A)[4] op dDOT14((B+4),(C)); \
    +00213   (A)[5] op dDOT14((B+4),(C+1)); \
    +00214   (A)[6] op dDOT14((B+4),(C+2)); \
    +00215   (A)[8] op dDOT14((B+8),(C)); \
    +00216   (A)[9] op dDOT14((B+8),(C+1)); \
    +00217   (A)[10] op dDOT14((B+8),(C+2)); \
    +00218 } while(0)
    +00219 #define dMULTIPLYOP1_333(A,op,B,C) \
    +00220 do { \
    +00221   (A)[0] op dDOT44((B),(C)); \
    +00222   (A)[1] op dDOT44((B),(C+1)); \
    +00223   (A)[2] op dDOT44((B),(C+2)); \
    +00224   (A)[4] op dDOT44((B+1),(C)); \
    +00225   (A)[5] op dDOT44((B+1),(C+1)); \
    +00226   (A)[6] op dDOT44((B+1),(C+2)); \
    +00227   (A)[8] op dDOT44((B+2),(C)); \
    +00228   (A)[9] op dDOT44((B+2),(C+1)); \
    +00229   (A)[10] op dDOT44((B+2),(C+2)); \
    +00230 } while(0)
    +00231 #define dMULTIPLYOP2_333(A,op,B,C) \
    +00232 do { \
    +00233   (A)[0] op dDOT((B),(C)); \
    +00234   (A)[1] op dDOT((B),(C+4)); \
    +00235   (A)[2] op dDOT((B),(C+8)); \
    +00236   (A)[4] op dDOT((B+4),(C)); \
    +00237   (A)[5] op dDOT((B+4),(C+4)); \
    +00238   (A)[6] op dDOT((B+4),(C+8)); \
    +00239   (A)[8] op dDOT((B+8),(C)); \
    +00240   (A)[9] op dDOT((B+8),(C+4)); \
    +00241   (A)[10] op dDOT((B+8),(C+8)); \
    +00242 } while(0)
    +00243 
    +00244 #ifdef __cplusplus
    +00245 
    +00246 #define DECL template <class TA, class TB, class TC> PURE_INLINE void
    +00247 
    +00248 DECL dMULTIPLY0_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_331(A,=,B,C); }
    +00249 DECL dMULTIPLY1_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_331(A,=,B,C); }
    +00250 DECL dMULTIPLY0_133(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_133(A,=,B,C); }
    +00251 DECL dMULTIPLY0_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_333(A,=,B,C); }
    +00252 DECL dMULTIPLY1_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_333(A,=,B,C); }
    +00253 DECL dMULTIPLY2_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP2_333(A,=,B,C); }
    +00254 
    +00255 DECL dMULTIPLYADD0_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_331(A,+=,B,C); }
    +00256 DECL dMULTIPLYADD1_331(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_331(A,+=,B,C); }
    +00257 DECL dMULTIPLYADD0_133(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_133(A,+=,B,C); }
    +00258 DECL dMULTIPLYADD0_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP0_333(A,+=,B,C); }
    +00259 DECL dMULTIPLYADD1_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP1_333(A,+=,B,C); }
    +00260 DECL dMULTIPLYADD2_333(TA *A, const TB *B, const TC *C) { dMULTIPLYOP2_333(A,+=,B,C); }
    +00261 
    +00262 #undef DECL
    +00263 
    +00264 #else
    +00265 
    +00266 #define dMULTIPLY0_331(A,B,C) dMULTIPLYOP0_331(A,=,B,C)
    +00267 #define dMULTIPLY1_331(A,B,C) dMULTIPLYOP1_331(A,=,B,C)
    +00268 #define dMULTIPLY0_133(A,B,C) dMULTIPLYOP0_133(A,=,B,C)
    +00269 #define dMULTIPLY0_333(A,B,C) dMULTIPLYOP0_333(A,=,B,C)
    +00270 #define dMULTIPLY1_333(A,B,C) dMULTIPLYOP1_333(A,=,B,C)
    +00271 #define dMULTIPLY2_333(A,B,C) dMULTIPLYOP2_333(A,=,B,C)
    +00272 
    +00273 #define dMULTIPLYADD0_331(A,B,C) dMULTIPLYOP0_331(A,+=,B,C)
    +00274 #define dMULTIPLYADD1_331(A,B,C) dMULTIPLYOP1_331(A,+=,B,C)
    +00275 #define dMULTIPLYADD0_133(A,B,C) dMULTIPLYOP0_133(A,+=,B,C)
    +00276 #define dMULTIPLYADD0_333(A,B,C) dMULTIPLYOP0_333(A,+=,B,C)
    +00277 #define dMULTIPLYADD1_333(A,B,C) dMULTIPLYOP1_333(A,+=,B,C)
    +00278 #define dMULTIPLYADD2_333(A,B,C) dMULTIPLYOP2_333(A,+=,B,C)
    +00279 
    +00280 #endif
    +00281 
    +00282 
    +00283 #ifdef __cplusplus
    +00284 extern "C" {
    +00285 #endif
    +00286 
    +00287 /*
    +00288  * normalize 3x1 and 4x1 vectors (i.e. scale them to unit length)
    +00289  */
    +00290 ODE_API int  dSafeNormalize3 (dVector3 a);
    +00291 ODE_API int  dSafeNormalize4 (dVector4 a);
    +00292 
    +00293 // For some reason demo_chain1.c does not understand "inline" keyword.
    +00294 static __inline void _dNormalize3(dVector3 a)
    +00295 {
    +00296    int bNormalizationResult = dSafeNormalize3(a);
    +00297    dIASSERT(bNormalizationResult);
    +00298    dVARIABLEUSED(bNormalizationResult);
    +00299 }
    +00300 
    +00301 static __inline void _dNormalize4(dVector4 a)
    +00302 {
    +00303    int bNormalizationResult = dSafeNormalize4(a);
    +00304    dIASSERT(bNormalizationResult);
    +00305    dVARIABLEUSED(bNormalizationResult);
    +00306 }
    +00307 
    +00308 // For DLL export
    +00309 ODE_API void dNormalize3 (dVector3 a); // Potentially asserts on zero vec
    +00310 ODE_API void dNormalize4 (dVector4 a); // Potentially asserts on zero vec
    +00311 
    +00312 // For internal use
    +00313 #define dNormalize3(a) _dNormalize3(a)
    +00314 #define dNormalize4(a) _dNormalize4(a)
    +00315 
    +00316 /*
    +00317  * given a unit length "normal" vector n, generate vectors p and q vectors
    +00318  * that are an orthonormal basis for the plane space perpendicular to n.
    +00319  * i.e. this makes p,q such that n,p,q are all perpendicular to each other.
    +00320  * q will equal n x p. if n is not unit length then p will be unit length but
    +00321  * q wont be.
    +00322  */
    +00323 
    +00324 ODE_API void dPlaneSpace (const dVector3 n, dVector3 p, dVector3 q);
    +00325 
    +00326 #ifdef __cplusplus
    +00327 }
    +00328 #endif
    +00329 
    +00330 #endif
    +

    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/rotation_8h-source.html b/libraries/ode-0.9/docs/rotation_8h-source.html new file mode 100644 index 0000000000..54ca2485d8 --- /dev/null +++ b/libraries/ode-0.9/docs/rotation_8h-source.html @@ -0,0 +1,90 @@ + + +Open Dynamics Engine: rotation.h Source File + + + + + +

    rotation.h

    00001 /*************************************************************************
    +00002  *                                                                       *
    +00003  * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
    +00004  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
    +00005  *                                                                       *
    +00006  * This library is free software; you can redistribute it and/or         *
    +00007  * modify it under the terms of EITHER:                                  *
    +00008  *   (1) The GNU Lesser General Public License as published by the Free  *
    +00009  *       Software Foundation; either version 2.1 of the License, or (at  *
    +00010  *       your option) any later version. The text of the GNU Lesser      *
    +00011  *       General Public License is included with this library in the     *
    +00012  *       file LICENSE.TXT.                                               *
    +00013  *   (2) The BSD-style license that is included with this library in     *
    +00014  *       the file LICENSE-BSD.TXT.                                       *
    +00015  *                                                                       *
    +00016  * This library is distributed in the hope that it will be useful,       *
    +00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
    +00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
    +00019  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
    +00020  *                                                                       *
    +00021  *************************************************************************/
    +00022 
    +00023 #ifndef _ODE_ROTATION_H_
    +00024 #define _ODE_ROTATION_H_
    +00025 
    +00026 #include <ode/common.h>
    +00027 #include <ode/compatibility.h>
    +00028 
    +00029 #ifdef __cplusplus
    +00030 extern "C" {
    +00031 #endif
    +00032 
    +00033 
    +00034 ODE_API void dRSetIdentity (dMatrix3 R);
    +00035 
    +00036 ODE_API void dRFromAxisAndAngle (dMatrix3 R, dReal ax, dReal ay, dReal az,
    +00037           dReal angle);
    +00038 
    +00039 ODE_API void dRFromEulerAngles (dMatrix3 R, dReal phi, dReal theta, dReal psi);
    +00040 
    +00041 ODE_API void dRFrom2Axes (dMatrix3 R, dReal ax, dReal ay, dReal az,
    +00042         dReal bx, dReal by, dReal bz);
    +00043 
    +00044 ODE_API void dRFromZAxis (dMatrix3 R, dReal ax, dReal ay, dReal az);
    +00045 
    +00046 ODE_API void dQSetIdentity (dQuaternion q);
    +00047 
    +00048 ODE_API void dQFromAxisAndAngle (dQuaternion q, dReal ax, dReal ay, dReal az,
    +00049           dReal angle);
    +00050 
    +00051 /* Quaternion multiplication, analogous to the matrix multiplication routines. */
    +00052 /* qa = rotate by qc, then qb */
    +00053 ODE_API void dQMultiply0 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
    +00054 /* qa = rotate by qc, then by inverse of qb */
    +00055 ODE_API void dQMultiply1 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
    +00056 /* qa = rotate by inverse of qc, then by qb */
    +00057 ODE_API void dQMultiply2 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
    +00058 /* qa = rotate by inverse of qc, then by inverse of qb */
    +00059 ODE_API void dQMultiply3 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
    +00060 
    +00061 ODE_API void dRfromQ (dMatrix3 R, const dQuaternion q);
    +00062 ODE_API void dQfromR (dQuaternion q, const dMatrix3 R);
    +00063 ODE_API void dDQfromW (dReal dq[4], const dVector3 w, const dQuaternion q);
    +00064 
    +00065 
    +00066 #ifdef __cplusplus
    +00067 }
    +00068 #endif
    +00069 
    +00070 #endif
    +

    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/structd_contact_geom.html b/libraries/ode-0.9/docs/structd_contact_geom.html new file mode 100644 index 0000000000..9be3fca7af --- /dev/null +++ b/libraries/ode-0.9/docs/structd_contact_geom.html @@ -0,0 +1,70 @@ + + +Open Dynamics Engine: dContactGeom Struct Reference + + + + + + +

    dContactGeom Struct Reference
    + +[Collision Detection] +

    Describe the contact point between two geoms. +More... +

    +#include <contact.h> +

    + + + + + + + + + + + + + + + + + + + + + + +

    Data Fields

    +dVector3 pos
     contact position
    +dVector3 normal
     normal vector
    +dReal depth
     penetration depth
    +dGeomID g1
    +dGeomID g2
     the colliding geoms
    +int side1
    +int side2
     (to be documented)
    +


    Detailed Description

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


    The documentation for this struct was generated from the following file: +
    Generated on Fri Oct 12 08:36:52 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/structds_functions.html b/libraries/ode-0.9/docs/structds_functions.html new file mode 100644 index 0000000000..6d5685aa7c --- /dev/null +++ b/libraries/ode-0.9/docs/structds_functions.html @@ -0,0 +1,59 @@ + + +Open Dynamics Engine: dsFunctions Struct Reference + + + + + + +

    dsFunctions Struct Reference
    + +[DrawStuff] +

    Set of functions to be used as callbacks by the simulation loop. +More... +

    +#include <drawstuff.h> +

    + + + + + + + + + + + + + + + +

    Data Fields

    +int version
    +void(* start )()
    +void(* step )(int pause)
    +void(* command )(int cmd)
    +void(* stop )()
    +char * path_to_textures
    +


    Detailed Description

    +Set of functions to be used as callbacks by the simulation loop.
    The documentation for this struct was generated from the following file: +
    Generated on Fri Oct 12 08:36:52 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/tab_b.gif b/libraries/ode-0.9/docs/tab_b.gif new file mode 100644 index 0000000000..0d623483ff Binary files /dev/null and b/libraries/ode-0.9/docs/tab_b.gif differ diff --git a/libraries/ode-0.9/docs/tab_l.gif b/libraries/ode-0.9/docs/tab_l.gif new file mode 100644 index 0000000000..9b1e6337c9 Binary files /dev/null and b/libraries/ode-0.9/docs/tab_l.gif differ diff --git a/libraries/ode-0.9/docs/tab_r.gif b/libraries/ode-0.9/docs/tab_r.gif new file mode 100644 index 0000000000..ce9dd9f533 Binary files /dev/null and b/libraries/ode-0.9/docs/tab_r.gif differ diff --git a/libraries/ode-0.9/docs/tabs.css b/libraries/ode-0.9/docs/tabs.css new file mode 100644 index 0000000000..c37faafe80 --- /dev/null +++ b/libraries/ode-0.9/docs/tabs.css @@ -0,0 +1,102 @@ +/* tabs styles, based on http://www.alistapart.com/articles/slidingdoors */ + +DIV.tabs +{ + float : left; + width : 100%; + background : url("tab_b.gif") repeat-x bottom; + margin-bottom : 4px; +} + +DIV.tabs UL +{ + margin : 0px; + padding-left : 10px; + list-style : none; +} + +DIV.tabs LI, DIV.tabs FORM +{ + display : inline; + margin : 0px; + padding : 0px; +} + +DIV.tabs FORM +{ + float : right; +} + +DIV.tabs A +{ + float : left; + background : url("tab_r.gif") no-repeat right top; + border-bottom : 1px solid #84B0C7; + font-size : x-small; + font-weight : bold; + text-decoration : none; +} + +DIV.tabs A:hover +{ + background-position: 100% -150px; +} + +DIV.tabs A:link, DIV.tabs A:visited, +DIV.tabs A:active, DIV.tabs A:hover +{ + color: #1A419D; +} + +DIV.tabs SPAN +{ + float : left; + display : block; + background : url("tab_l.gif") no-repeat left top; + padding : 5px 9px; + white-space : nowrap; +} + +DIV.tabs INPUT +{ + float : right; + display : inline; + font-size : 1em; +} + +DIV.tabs TD +{ + font-size : x-small; + font-weight : bold; + text-decoration : none; +} + + + +/* Commented Backslash Hack hides rule from IE5-Mac \*/ +DIV.tabs SPAN {float : none;} +/* End IE5-Mac hack */ + +DIV.tabs A:hover SPAN +{ + background-position: 0% -150px; +} + +DIV.tabs LI.current A +{ + background-position: 100% -150px; + border-width : 0px; +} + +DIV.tabs LI.current SPAN +{ + background-position: 0% -150px; + padding-bottom : 6px; +} + +DIV.nav +{ + background : none; + border : none; + border-bottom : 1px solid #84B0C7; +} diff --git a/libraries/ode-0.9/docs/timer_8h-source.html b/libraries/ode-0.9/docs/timer_8h-source.html new file mode 100644 index 0000000000..3d0b1e63ae --- /dev/null +++ b/libraries/ode-0.9/docs/timer_8h-source.html @@ -0,0 +1,96 @@ + + +Open Dynamics Engine: timer.h Source File + + + + + +

    timer.h

    00001 /*************************************************************************
    +00002  *                                                                       *
    +00003  * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
    +00004  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
    +00005  *                                                                       *
    +00006  * This library is free software; you can redistribute it and/or         *
    +00007  * modify it under the terms of EITHER:                                  *
    +00008  *   (1) The GNU Lesser General Public License as published by the Free  *
    +00009  *       Software Foundation; either version 2.1 of the License, or (at  *
    +00010  *       your option) any later version. The text of the GNU Lesser      *
    +00011  *       General Public License is included with this library in the     *
    +00012  *       file LICENSE.TXT.                                               *
    +00013  *   (2) The BSD-style license that is included with this library in     *
    +00014  *       the file LICENSE-BSD.TXT.                                       *
    +00015  *                                                                       *
    +00016  * This library is distributed in the hope that it will be useful,       *
    +00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
    +00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
    +00019  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
    +00020  *                                                                       *
    +00021  *************************************************************************/
    +00022 
    +00023 #ifndef _ODE_TIMER_H_
    +00024 #define _ODE_TIMER_H_
    +00025 
    +00026 #include <ode/config.h>
    +00027 
    +00028 #ifdef __cplusplus
    +00029 extern "C" {
    +00030 #endif
    +00031 
    +00032 
    +00033 /* stop watch objects */
    +00034 
    +00035 typedef struct dStopwatch {
    +00036   double time;       /* total clock count */
    +00037   unsigned long cc[2];     /* clock count since last `start' */
    +00038 } dStopwatch;
    +00039 
    +00040 ODE_API void dStopwatchReset (dStopwatch *);
    +00041 ODE_API void dStopwatchStart (dStopwatch *);
    +00042 ODE_API void dStopwatchStop  (dStopwatch *);
    +00043 ODE_API double dStopwatchTime (dStopwatch *);   /* returns total time in secs */
    +00044 
    +00045 
    +00046 /* code timers */
    +00047 
    +00048 ODE_API void dTimerStart (const char *description);   /* pass a static string here */
    +00049 ODE_API void dTimerNow (const char *description);  /* pass a static string here */
    +00050 ODE_API void dTimerEnd(void);
    +00051 
    +00052 /* print out a timer report. if `average' is nonzero, print out the average
    +00053  * time for each slot (this is only meaningful if the same start-now-end
    +00054  * calls are being made repeatedly.
    +00055  */
    +00056 ODE_API void dTimerReport (FILE *fout, int average);
    +00057 
    +00058 
    +00059 /* resolution */
    +00060 
    +00061 /* returns the timer ticks per second implied by the timing hardware or API.
    +00062  * the actual timer resolution may not be this great.
    +00063  */
    +00064 ODE_API double dTimerTicksPerSecond(void);
    +00065 
    +00066 /* returns an estimate of the actual timer resolution, in seconds. this may
    +00067  * be greater than 1/ticks_per_second.
    +00068  */
    +00069 ODE_API double dTimerResolution(void);
    +00070 
    +00071 
    +00072 #ifdef __cplusplus
    +00073 }
    +00074 #endif
    +00075 
    +00076 #endif
    +

    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/docs/version_8h-source.html b/libraries/ode-0.9/docs/version_8h-source.html new file mode 100644 index 0000000000..74430d1db2 --- /dev/null +++ b/libraries/ode-0.9/docs/version_8h-source.html @@ -0,0 +1,49 @@ + + +Open Dynamics Engine: version.h Source File + + + + + +

    version.h

    00001 /*************************************************************************
    +00002  *                                                                       *
    +00003  * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
    +00004  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
    +00005  *                                                                       *
    +00006  * This library is free software; you can redistribute it and/or         *
    +00007  * modify it under the terms of EITHER:                                  *
    +00008  *   (1) The GNU Lesser General Public License as published by the Free  *
    +00009  *       Software Foundation; either version 2.1 of the License, or (at  *
    +00010  *       your option) any later version. The text of the GNU Lesser      *
    +00011  *       General Public License is included with this library in the     *
    +00012  *       file LICENSE.TXT.                                               *
    +00013  *   (2) The BSD-style license that is included with this library in     *
    +00014  *       the file LICENSE-BSD.TXT.                                       *
    +00015  *                                                                       *
    +00016  * This library is distributed in the hope that it will be useful,       *
    +00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
    +00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
    +00019  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
    +00020  *                                                                       *
    +00021  *************************************************************************/
    +00022 
    +00023 #ifndef __VERSION_H
    +00024 #define __VERSION_H
    +00025 
    +00026 /* high byte is major version, low byte is minor version */
    +00027 #define DS_VERSION 0x0002
    +00028 
    +00029 #endif
    +

    Generated on Fri Oct 12 08:36:51 2007 for Open Dynamics Engine by  + +doxygen 1.5.3
    + + diff --git a/libraries/ode-0.9/drawstuff/Makefile.am b/libraries/ode-0.9/drawstuff/Makefile.am new file mode 100644 index 0000000000..2993d0b475 --- /dev/null +++ b/libraries/ode-0.9/drawstuff/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = src dstest \ No newline at end of file diff --git a/libraries/ode-0.9/drawstuff/Makefile.in b/libraries/ode-0.9/drawstuff/Makefile.in new file mode 100644 index 0000000000..974102bb2a --- /dev/null +++ b/libraries/ode-0.9/drawstuff/Makefile.in @@ -0,0 +1,488 @@ +# Makefile.in generated by automake 1.10 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 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@ +target_triplet = @target@ +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)/include/ode/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@ +ARCHFLAGS = @ARCHFLAGS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DRAWSTUFF = @DRAWSTUFF@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +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@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +ODE_AGE = @ODE_AGE@ +ODE_CURRENT = @ODE_CURRENT@ +ODE_RELEASE = @ODE_RELEASE@ +ODE_REVISION = @ODE_REVISION@ +ODE_SONAME = @ODE_SONAME@ +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@ +SET_MAKE = @SET_MAKE@ +SHARED_LDFLAGS = @SHARED_LDFLAGS@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TOPDIR = @TOPDIR@ +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_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +so_ext = @so_ext@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = src dstest +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 \ + && exit 0; \ + 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 + +# 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; } \ + END { 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; } \ + END { 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=; \ + 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; } \ + END { 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 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 + +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 ctags \ + ctags-recursive distclean distclean-generic 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 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: diff --git a/libraries/ode-0.9/drawstuff/dstest/Makefile.am b/libraries/ode-0.9/drawstuff/dstest/Makefile.am new file mode 100644 index 0000000000..9d74664511 --- /dev/null +++ b/libraries/ode-0.9/drawstuff/dstest/Makefile.am @@ -0,0 +1,13 @@ +noinst_PROGRAMS= dstest +dstest_CXXFLAGS = -I$(top_srcdir)/include -I$(top_builddir) + +dstest_SOURCES= dstest.cpp +dstest_DEPENDENCIES=$(top_builddir)/drawstuff/src/libdrawstuff.a +dstest_LDFLAGS = -L$(top_builddir)/drawstuff/src +dstest_LDADD=-ldrawstuff @LDFLAGS@ @GL_LIBS@ @LIBS@ +if WIN32 +dstest_DEPENDENCIES+=resources.o +resources.o: ../src/resources.rc ../src/resource.h + @WINDRES@ ../src/resources.rc -o resources.o +dstest_LDADD+= resources.o +endif diff --git a/libraries/ode-0.9/drawstuff/dstest/Makefile.in b/libraries/ode-0.9/drawstuff/dstest/Makefile.in new file mode 100644 index 0000000000..0b7aed3443 --- /dev/null +++ b/libraries/ode-0.9/drawstuff/dstest/Makefile.in @@ -0,0 +1,446 @@ +# Makefile.in generated by automake 1.10 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 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@ +target_triplet = @target@ +noinst_PROGRAMS = dstest$(EXEEXT) +@WIN32_TRUE@am__append_1 = resources.o +@WIN32_TRUE@am__append_2 = resources.o +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)/include/ode/config.h +CONFIG_CLEAN_FILES = +PROGRAMS = $(noinst_PROGRAMS) +am_dstest_OBJECTS = dstest-dstest.$(OBJEXT) +dstest_OBJECTS = $(am_dstest_OBJECTS) +dstest_LINK = $(CXXLD) $(dstest_CXXFLAGS) $(CXXFLAGS) \ + $(dstest_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I. -I$(top_builddir)/include/ode@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(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@ +ARCHFLAGS = @ARCHFLAGS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DRAWSTUFF = @DRAWSTUFF@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +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@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +ODE_AGE = @ODE_AGE@ +ODE_CURRENT = @ODE_CURRENT@ +ODE_RELEASE = @ODE_RELEASE@ +ODE_REVISION = @ODE_REVISION@ +ODE_SONAME = @ODE_SONAME@ +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@ +SET_MAKE = @SET_MAKE@ +SHARED_LDFLAGS = @SHARED_LDFLAGS@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TOPDIR = @TOPDIR@ +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_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +so_ext = @so_ext@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +dstest_CXXFLAGS = -I$(top_srcdir)/include -I$(top_builddir) +dstest_SOURCES = dstest.cpp +dstest_DEPENDENCIES = $(top_builddir)/drawstuff/src/libdrawstuff.a \ + $(am__append_1) +dstest_LDFLAGS = -L$(top_builddir)/drawstuff/src +dstest_LDADD = -ldrawstuff @LDFLAGS@ @GL_LIBS@ @LIBS@ $(am__append_2) +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .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 \ + && exit 0; \ + 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: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) +dstest$(EXEEXT): $(dstest_OBJECTS) $(dstest_DEPENDENCIES) + @rm -f dstest$(EXEEXT) + $(dstest_LINK) $(dstest_OBJECTS) $(dstest_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dstest-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) '$<'` + +dstest-dstest.o: dstest.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dstest_CXXFLAGS) $(CXXFLAGS) -MT dstest-dstest.o -MD -MP -MF $(DEPDIR)/dstest-dstest.Tpo -c -o dstest-dstest.o `test -f 'dstest.cpp' || echo '$(srcdir)/'`dstest.cpp +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dstest-dstest.Tpo $(DEPDIR)/dstest-dstest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dstest.cpp' object='dstest-dstest.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) $(dstest_CXXFLAGS) $(CXXFLAGS) -c -o dstest-dstest.o `test -f 'dstest.cpp' || echo '$(srcdir)/'`dstest.cpp + +dstest-dstest.obj: dstest.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dstest_CXXFLAGS) $(CXXFLAGS) -MT dstest-dstest.obj -MD -MP -MF $(DEPDIR)/dstest-dstest.Tpo -c -o dstest-dstest.obj `if test -f 'dstest.cpp'; then $(CYGPATH_W) 'dstest.cpp'; else $(CYGPATH_W) '$(srcdir)/dstest.cpp'; fi` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/dstest-dstest.Tpo $(DEPDIR)/dstest-dstest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dstest.cpp' object='dstest-dstest.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) $(dstest_CXXFLAGS) $(CXXFLAGS) -c -o dstest-dstest.obj `if test -f 'dstest.cpp'; then $(CYGPATH_W) 'dstest.cpp'; else $(CYGPATH_W) '$(srcdir)/dstest.cpp'; fi` + +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; } \ + END { 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; } \ + END { 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=; \ + 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; } \ + END { 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-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 + +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-noinstPROGRAMS ctags distclean distclean-compile \ + distclean-generic 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 pdf pdf-am ps ps-am tags uninstall \ + uninstall-am + +@WIN32_TRUE@resources.o: ../src/resources.rc ../src/resource.h +@WIN32_TRUE@ @WINDRES@ ../src/resources.rc -o resources.o +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libraries/ode-0.9/drawstuff/dstest/dstest.cpp b/libraries/ode-0.9/drawstuff/dstest/dstest.cpp new file mode 100644 index 0000000000..27f042fc7e --- /dev/null +++ b/libraries/ode-0.9/drawstuff/dstest/dstest.cpp @@ -0,0 +1,125 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include +#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; +} diff --git a/libraries/ode-0.9/drawstuff/src/Makefile.am b/libraries/ode-0.9/drawstuff/src/Makefile.am new file mode 100644 index 0000000000..ed9b2f5b64 --- /dev/null +++ b/libraries/ode-0.9/drawstuff/src/Makefile.am @@ -0,0 +1,21 @@ +# We build drawstuff as a non libtool static library manually +# so it doesn't get installed when 'make install' is called, +# drawstuff is meant as an aid for testing and not as a full +# rendering library. + +noinst_LIBRARIES = libdrawstuff.a +libdrawstuff_a_SOURCES = drawstuff.cpp internal.h +libdrawstuff_a_CXXFLAGS = @ARCHFLAGS@ -I$(top_srcdir)/include -I$(top_builddir)/include + +# libdrawstuff_a_LIBADD = @GL_LIBS@ + +if WIN32 +libdrawstuff_a_SOURCES+= windows.cpp +endif +if X11 +libdrawstuff_a_SOURCES+= x11.cpp +endif +if OSX +libdrawstuff_a_SOURCES+= osx.cpp +endif + diff --git a/libraries/ode-0.9/drawstuff/src/Makefile.in b/libraries/ode-0.9/drawstuff/src/Makefile.in new file mode 100644 index 0000000000..0e0f633f54 --- /dev/null +++ b/libraries/ode-0.9/drawstuff/src/Makefile.in @@ -0,0 +1,507 @@ +# Makefile.in generated by automake 1.10 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 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@ + +# We build drawstuff as a non libtool static library manually +# so it doesn't get installed when 'make install' is called, +# 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@ +target_triplet = @target@ + +# libdrawstuff_a_LIBADD = @GL_LIBS@ +@WIN32_TRUE@am__append_1 = windows.cpp +@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)/include/ode/config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) +AR = ar +ARFLAGS = cru +libdrawstuff_a_AR = $(AR) $(ARFLAGS) +libdrawstuff_a_LIBADD = +am__libdrawstuff_a_SOURCES_DIST = drawstuff.cpp internal.h windows.cpp \ + x11.cpp osx.cpp +@WIN32_TRUE@am__objects_1 = libdrawstuff_a-windows.$(OBJEXT) +@X11_TRUE@am__objects_2 = libdrawstuff_a-x11.$(OBJEXT) +@OSX_TRUE@am__objects_3 = libdrawstuff_a-osx.$(OBJEXT) +am_libdrawstuff_a_OBJECTS = libdrawstuff_a-drawstuff.$(OBJEXT) \ + $(am__objects_1) $(am__objects_2) $(am__objects_3) +libdrawstuff_a_OBJECTS = $(am_libdrawstuff_a_OBJECTS) +DEFAULT_INCLUDES = -I. -I$(top_builddir)/include/ode@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libdrawstuff_a_SOURCES) +DIST_SOURCES = $(am__libdrawstuff_a_SOURCES_DIST) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +ARCHFLAGS = @ARCHFLAGS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DRAWSTUFF = @DRAWSTUFF@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +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@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +ODE_AGE = @ODE_AGE@ +ODE_CURRENT = @ODE_CURRENT@ +ODE_RELEASE = @ODE_RELEASE@ +ODE_REVISION = @ODE_REVISION@ +ODE_SONAME = @ODE_SONAME@ +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@ +SET_MAKE = @SET_MAKE@ +SHARED_LDFLAGS = @SHARED_LDFLAGS@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TOPDIR = @TOPDIR@ +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_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +so_ext = @so_ext@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LIBRARIES = libdrawstuff.a +libdrawstuff_a_SOURCES = drawstuff.cpp internal.h $(am__append_1) \ + $(am__append_2) $(am__append_3) +libdrawstuff_a_CXXFLAGS = @ARCHFLAGS@ -I$(top_srcdir)/include -I$(top_builddir)/include +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .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 \ + && exit 0; \ + 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-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libdrawstuff.a: $(libdrawstuff_a_OBJECTS) $(libdrawstuff_a_DEPENDENCIES) + -rm -f libdrawstuff.a + $(libdrawstuff_a_AR) libdrawstuff.a $(libdrawstuff_a_OBJECTS) $(libdrawstuff_a_LIBADD) + $(RANLIB) libdrawstuff.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrawstuff_a-drawstuff.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrawstuff_a-osx.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrawstuff_a-windows.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrawstuff_a-x11.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) '$<'` + +libdrawstuff_a-drawstuff.o: drawstuff.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -MT libdrawstuff_a-drawstuff.o -MD -MP -MF $(DEPDIR)/libdrawstuff_a-drawstuff.Tpo -c -o libdrawstuff_a-drawstuff.o `test -f 'drawstuff.cpp' || echo '$(srcdir)/'`drawstuff.cpp +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libdrawstuff_a-drawstuff.Tpo $(DEPDIR)/libdrawstuff_a-drawstuff.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='drawstuff.cpp' object='libdrawstuff_a-drawstuff.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) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -c -o libdrawstuff_a-drawstuff.o `test -f 'drawstuff.cpp' || echo '$(srcdir)/'`drawstuff.cpp + +libdrawstuff_a-drawstuff.obj: drawstuff.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -MT libdrawstuff_a-drawstuff.obj -MD -MP -MF $(DEPDIR)/libdrawstuff_a-drawstuff.Tpo -c -o libdrawstuff_a-drawstuff.obj `if test -f 'drawstuff.cpp'; then $(CYGPATH_W) 'drawstuff.cpp'; else $(CYGPATH_W) '$(srcdir)/drawstuff.cpp'; fi` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libdrawstuff_a-drawstuff.Tpo $(DEPDIR)/libdrawstuff_a-drawstuff.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='drawstuff.cpp' object='libdrawstuff_a-drawstuff.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) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -c -o libdrawstuff_a-drawstuff.obj `if test -f 'drawstuff.cpp'; then $(CYGPATH_W) 'drawstuff.cpp'; else $(CYGPATH_W) '$(srcdir)/drawstuff.cpp'; fi` + +libdrawstuff_a-windows.o: windows.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -MT libdrawstuff_a-windows.o -MD -MP -MF $(DEPDIR)/libdrawstuff_a-windows.Tpo -c -o libdrawstuff_a-windows.o `test -f 'windows.cpp' || echo '$(srcdir)/'`windows.cpp +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libdrawstuff_a-windows.Tpo $(DEPDIR)/libdrawstuff_a-windows.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='windows.cpp' object='libdrawstuff_a-windows.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) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -c -o libdrawstuff_a-windows.o `test -f 'windows.cpp' || echo '$(srcdir)/'`windows.cpp + +libdrawstuff_a-windows.obj: windows.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -MT libdrawstuff_a-windows.obj -MD -MP -MF $(DEPDIR)/libdrawstuff_a-windows.Tpo -c -o libdrawstuff_a-windows.obj `if test -f 'windows.cpp'; then $(CYGPATH_W) 'windows.cpp'; else $(CYGPATH_W) '$(srcdir)/windows.cpp'; fi` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libdrawstuff_a-windows.Tpo $(DEPDIR)/libdrawstuff_a-windows.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='windows.cpp' object='libdrawstuff_a-windows.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) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -c -o libdrawstuff_a-windows.obj `if test -f 'windows.cpp'; then $(CYGPATH_W) 'windows.cpp'; else $(CYGPATH_W) '$(srcdir)/windows.cpp'; fi` + +libdrawstuff_a-x11.o: x11.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -MT libdrawstuff_a-x11.o -MD -MP -MF $(DEPDIR)/libdrawstuff_a-x11.Tpo -c -o libdrawstuff_a-x11.o `test -f 'x11.cpp' || echo '$(srcdir)/'`x11.cpp +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libdrawstuff_a-x11.Tpo $(DEPDIR)/libdrawstuff_a-x11.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='x11.cpp' object='libdrawstuff_a-x11.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) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -c -o libdrawstuff_a-x11.o `test -f 'x11.cpp' || echo '$(srcdir)/'`x11.cpp + +libdrawstuff_a-x11.obj: x11.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -MT libdrawstuff_a-x11.obj -MD -MP -MF $(DEPDIR)/libdrawstuff_a-x11.Tpo -c -o libdrawstuff_a-x11.obj `if test -f 'x11.cpp'; then $(CYGPATH_W) 'x11.cpp'; else $(CYGPATH_W) '$(srcdir)/x11.cpp'; fi` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libdrawstuff_a-x11.Tpo $(DEPDIR)/libdrawstuff_a-x11.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='x11.cpp' object='libdrawstuff_a-x11.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) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -c -o libdrawstuff_a-x11.obj `if test -f 'x11.cpp'; then $(CYGPATH_W) 'x11.cpp'; else $(CYGPATH_W) '$(srcdir)/x11.cpp'; fi` + +libdrawstuff_a-osx.o: osx.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -MT libdrawstuff_a-osx.o -MD -MP -MF $(DEPDIR)/libdrawstuff_a-osx.Tpo -c -o libdrawstuff_a-osx.o `test -f 'osx.cpp' || echo '$(srcdir)/'`osx.cpp +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libdrawstuff_a-osx.Tpo $(DEPDIR)/libdrawstuff_a-osx.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='osx.cpp' object='libdrawstuff_a-osx.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) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -c -o libdrawstuff_a-osx.o `test -f 'osx.cpp' || echo '$(srcdir)/'`osx.cpp + +libdrawstuff_a-osx.obj: osx.cpp +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -MT libdrawstuff_a-osx.obj -MD -MP -MF $(DEPDIR)/libdrawstuff_a-osx.Tpo -c -o libdrawstuff_a-osx.obj `if test -f 'osx.cpp'; then $(CYGPATH_W) 'osx.cpp'; else $(CYGPATH_W) '$(srcdir)/osx.cpp'; fi` +@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libdrawstuff_a-osx.Tpo $(DEPDIR)/libdrawstuff_a-osx.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='osx.cpp' object='libdrawstuff_a-osx.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) $(libdrawstuff_a_CXXFLAGS) $(CXXFLAGS) -c -o libdrawstuff_a-osx.obj `if test -f 'osx.cpp'; then $(CYGPATH_W) 'osx.cpp'; else $(CYGPATH_W) '$(srcdir)/osx.cpp'; fi` + +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; } \ + END { 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; } \ + END { 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=; \ + 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; } \ + END { 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 $(LIBRARIES) +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-noinstLIBRARIES 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 + +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-noinstLIBRARIES ctags distclean distclean-compile \ + distclean-generic 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 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: diff --git a/libraries/ode-0.9/drawstuff/src/drawstuff.cpp b/libraries/ode-0.9/drawstuff/src/drawstuff.cpp new file mode 100644 index 0000000000..f588266f8c --- /dev/null +++ b/libraries/ode-0.9/drawstuff/src/drawstuff.cpp @@ -0,0 +1,1597 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +simple graphics. + +the following command line flags can be used (typically under unix) + -notex Do not use any textures + -noshadow[s] Do not draw any shadows + -pause Start the simulation paused + +TODO +---- + +manage openGL state changes better + +*/ + +#ifdef WIN32 +#include +#endif + +#include +#ifdef HAVE_APPLE_OPENGL_FRAMEWORK +#include +#include +#else +#include +#include +#endif + +#include "drawstuff/drawstuff.h" +#include "internal.h" + +//*************************************************************************** +// misc + +#ifdef WIN32 +#define DEFAULT_PATH_TO_TEXTURES "..\\textures\\" +#else +#define DEFAULT_PATH_TO_TEXTURES "../textures/" +#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 + +#define dCROSS(a,op,b,c) \ + (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]); + + +inline float dDOT (const float *a, const float *b) + { return ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2]); } + + +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; + } + + glPopMatrix(); +} + + +// 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; + + +#ifndef macintosh + +void dsStartGraphics (int width, int height, dsFunctions *fn) +{ + 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"); + 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); +} + +#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); + wood_texture->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; iversion > 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; +} diff --git a/libraries/ode-0.9/drawstuff/src/internal.h b/libraries/ode-0.9/drawstuff/src/internal.h new file mode 100644 index 0000000000..de1aa1162f --- /dev/null +++ b/libraries/ode-0.9/drawstuff/src/internal.h @@ -0,0 +1,50 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* functions supplied and used by the platform specific code */ + +#ifndef __DS_INTERNAL_H +#define __DS_INTERNAL_H + +#include "drawstuff/drawstuff.h" + + +// supplied by platform specific code + +void dsPlatformSimLoop (int window_width, int window_height, + dsFunctions *fn, int initial_pause); + + +// used by platform specific code + +void dsStartGraphics (int width, int height, dsFunctions *fn); +void dsDrawFrame (int width, int height, dsFunctions *fn, int pause); +void dsStopGraphics(); +void dsMotion (int mode, int deltax, int deltay); + +int dsGetShadows(); +void dsSetShadows (int a); + +int dsGetTextures(); +void dsSetTextures (int a); + +#endif diff --git a/libraries/ode-0.9/drawstuff/src/osx.cpp b/libraries/ode-0.9/drawstuff/src/osx.cpp new file mode 100644 index 0000000000..fcecba907a --- /dev/null +++ b/libraries/ode-0.9/drawstuff/src/osx.cpp @@ -0,0 +1,542 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +// Platform-specific code for Mac OS X using Carbon+AGL +// +// Created using x11.cpp and the window-initialization -routines from GLFW +// as reference. +// Not thoroughly tested and is certain to contain deficiencies and bugs + +#include +#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 (char *msg1, 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 (char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + printMessage ("Error",msg,ap); + exit (1); +} + + +extern "C" void dsDebug (char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + printMessage ("INTERNAL ERROR",msg,ap); + // *((char *)0) = 0; ... commit SEGVicide ? + abort(); +} + +extern "C" void dsPrint (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(); +} diff --git a/libraries/ode-0.9/drawstuff/src/resource.h b/libraries/ode-0.9/drawstuff/src/resource.h new file mode 100644 index 0000000000..15802b6040 --- /dev/null +++ b/libraries/ode-0.9/drawstuff/src/resource.h @@ -0,0 +1,28 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by resources.rc +// +#define IDD_MSGDLG 101 +#define IDR_MENU1 102 +#define IDD_ABOUT 103 +#define IDR_ACCELERATOR1 104 +#define IDC_LIST1 1000 +#define IDM_EXIT 40001 +#define IDM_ABOUT 40002 +#define IDM_PAUSE 40003 +#define IDM_PERF_MONITOR 40004 +#define IDM_SHADOWS 40005 +#define IDM_TEXTURES 40006 +#define IDM_SAVE_SETTINGS 40007 +#define IDM_SINGLE_STEP 40008 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 108 +#define _APS_NEXT_COMMAND_VALUE 40009 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/libraries/ode-0.9/drawstuff/src/resources.rc b/libraries/ode-0.9/drawstuff/src/resources.rc new file mode 100644 index 0000000000..61611f7b41 --- /dev/null +++ b/libraries/ode-0.9/drawstuff/src/resources.rc @@ -0,0 +1,153 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +//#include "afxres.h" + +// added by RLS to make this work with windres +#include "winresrc.h" +#define IDC_STATIC (-1) + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUT DIALOG DISCARDABLE 0, 0, 257, 105 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "About" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,200,84,50,14 + LTEXT "Simulation test environment",IDC_STATIC,7,7,243,8 + LTEXT "Change the camera position by clicking + dragging in the main window.", + IDC_STATIC,7,24,243,8 + LTEXT "Left button - pan and tilt.",IDC_STATIC,25,37,225,8 + LTEXT "Right button - forward and sideways.",IDC_STATIC,25,48, + 225,8 + LTEXT "Left + Right button (or middle button) - sideways and up.", + IDC_STATIC,25,59,225,8 +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + //"#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MENU1 MENU DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Exit\tCtrl+X", IDM_EXIT + END + POPUP "&Simulation" + BEGIN + MENUITEM "&Pause\tCtrl+P", IDM_PAUSE + MENUITEM "Single Step\tCtrl+O", IDM_SINGLE_STEP + MENUITEM "Performance &Monitor", IDM_PERF_MONITOR, GRAYED + MENUITEM SEPARATOR + MENUITEM "&Shadows\tCtrl+S", IDM_SHADOWS, CHECKED + MENUITEM "&Textures\tCtrl+T", IDM_TEXTURES, CHECKED + MENUITEM SEPARATOR + MENUITEM "S&ave Settings", IDM_SAVE_SETTINGS, GRAYED + END + POPUP "&Help" + BEGIN + MENUITEM "&About", IDM_ABOUT + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_ABOUT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 250 + VERTGUIDE, 25 + TOPMARGIN, 7 + BOTTOMMARGIN, 98 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDR_ACCELERATOR1 ACCELERATORS DISCARDABLE +BEGIN + "O", IDM_SINGLE_STEP, VIRTKEY, CONTROL, NOINVERT + "P", IDM_PAUSE, VIRTKEY, CONTROL, NOINVERT + "S", IDM_SHADOWS, VIRTKEY, CONTROL, NOINVERT + "T", IDM_TEXTURES, VIRTKEY, CONTROL, NOINVERT + "X", IDM_EXIT, VIRTKEY, CONTROL, NOINVERT +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/libraries/ode-0.9/drawstuff/src/windows.cpp b/libraries/ode-0.9/drawstuff/src/windows.cpp new file mode 100644 index 0000000000..e2b442a557 --- /dev/null +++ b/libraries/ode-0.9/drawstuff/src/windows.cpp @@ -0,0 +1,527 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#if defined(WIN32) || defined(__CYGWIN__)// this prevents warnings when dependencies built +#include +#endif +#include +#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 (char *title, 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 (char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + errorBox ("Warning",msg,ap); +} + + +extern "C" void dsError (char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + errorBox ("Error",msg,ap); + exit (1); +} + + +extern "C" void dsDebug (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 (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) +#ifndef __CYGWIN__ + 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 +#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 (char *msg1, 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 (char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + printMessage ("Error",msg,ap); + exit (1); +} + + +extern "C" void dsDebug (char *msg, ...) +{ + va_list ap; + va_start (ap,msg); + printMessage ("INTERNAL ERROR",msg,ap); + // *((char *)0) = 0; ... commit SEGVicide ? + abort(); +} + + +extern "C" void dsPrint (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 attribList[] = {GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE,16, + GLX_RED_SIZE,4, GLX_GREEN_SIZE,4, + GLX_BLUE_SIZE,4, None}; + 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 (retvalB9o€wulttslnv‚“Ś”ŁśĄŚ‹“Ś‹“…„’ŚŚš}‡’{||”“›Ś”•|„…ultnv‚Ś”•™š¤{{„†™™š¤…„’ŚŚšŚ”•u{{u{{|„…lksmk…Ś—Łś§˛{{‰ŠˇŚ”•}‡’{{™š¤Ś”•ŽŁ™š¤™š¤ŚŚš™š¤„Š„|‚z”››ś››{||”š””š”Ł››‹„‹““““““red„„…‹‹‹‹„{u{‹’Šlri””‹‹„„|‚z||‹‹„š””{tttsl||„„™š¤„„Š{tt„Š„sle‹‹‹’ŚŚ‹’Šz‚l”››|uzt¦§¨ŚŚš{u{’ŚŚ›”›{u{„Š„ztl{{tlldś¤¦‚usle“““sleŠŠ}tt{j]\f]cf]cultult™š¤ŽŁlks{ttedk\[b{{llkddc]bZ{{tlld{tt}¦§¨‹„„]cd„„Š{u{tts…‹‹UTS|‚ztts“““uztekdlld|„…›˘›ztl\[b‹‹„ŁśĄ“““‹‹‹„„Šmtt›˘›lksSKJ{ttlrikk]dc\UUYsle[[TjcVmttkd\||rg]tts{||‹‹„tllsleJHFddcdc\b[Uult{||›”›\[[:97‹„„zll{{ttslztlsreUMRztltts\UZ{{t{{tttslekŠ}|”“›ult…„’{{tŠ}kk]d\\{u{„‰vtzlŚ”•‹„„tslzlllrif]c‹„‹‚|u‚utUTSult‹‹‹tzl“Ś”’ŚŚ“““Ś‹“f]c||‹‹‹‹„‹‹„„ult{u{{u{|Š}ldd[TTSKJ{{t“Ś”Š~‹ztl{tt{ttreddc\{tt‹„„‹…’‹„„””‹{||uztSKJ{zmek]lrittsldd‚v‚u{{UMRultD;9UTSLKRlri…‹’›˘›{u{{u{’ŚŚ{{Ś”•{{tt{lekttslri}tts]cd{{u{{{{lksŽŁ‰Šˇ„†™‹„‹¦§¨Şł·mtt{{^fsś¤¦…„’…‹’…‹šŚŚš|„…ś¤¦Ś—Łmttś¤¦Ś”•ś¤¦{{Ś”•~’“™š¤tt{…‹‹”“›tll„„“Ś”Ś”•ŚŚš“Ś”„„Š{{‹…’Ś‹“””‹{|||‚zedk|„…|„…¦§¨„Š„{tt“Ś”’ŚŚŁ››„„SKJ’ŚŚš””{ttŠ}|j]\tllJHF{{™š¤{{lri|‚zdc\„„tsl{||{{‹’Š„„Š{{kd\ztl””‹š””„„Š…‹‹\UZ}|{||f]c‚v‚Š~‹f]c{{ŽŁ¦§¨{tt”››||lek‚|u{ttuztult…‹’ttsŚ”•}||Š}}””‹lld}{tt‹…’™š¤“Ś”u{{ultlks’…‹“““Ś”•{{‹„„ś››‹‹‹Ś”•tts|‚z\UZllk[TTddctsl]bZtzlSKJreduzt”“›u{{lddŠ}|‹‹„{ttekd‹„„ztfred[[T{{tek]redllkŠ}¦§¨[TT:97‹‹„zll””‹kk]d\\kd\lldred\[bf]clldlri{u{„„Š’ŚŚ{||tzllddś¤¦f]c|llkult’ŚŚ{zmztl”“›ŠŠ}‚v{kd\tts‘…„ŁśĄlks‹„‹}mttu{{mttuzt‹„„„„]cd‹„„’ŚŚult‚ut|„…“““„„¤¤ť„Š„„Š„|[[T|„…{tt|„„{||||lri„Š„||‹…’ztlbVZ“““[[T‹‹„||cbVlldMRKd\\ekd}„„SKJj]\SKJUMRult„„{zm|mwŚ‹“Ś‹“{{Ś”•}}Šult…‹‹…„’„†™Ś‹“‹‹„{{„„›ť˛„„Š|„…ś¤¦…„’”“›”››Ś”•]cd]cd}‡’lkslks…„’tt{ŽŁ{{\[b{{f]c…‹’mtt™š¤„„Š…‹‹™š¤{zm}Š‚v{”“›„„Š…‹’ś¤¦ś¤¦™š¤¨©´¨©´¬¶Ă“““‹’Š¤¤ť‹’Š‹’Š¨©´‹‹‹Şł·ś¤¦›˘›{zm‹’Š‹‹„„„“Ś”tts|„…„„Š]cd“Ś”„„Šlek…‹‹tsltt{ztltts|‚ztsl{zmŁ››ŁśĄtsl‹‹‹ultu{{tll‰|v|tlltsl{{ŠŠ}b[U‰Šˇ™š¤“Ś”‹…š‚v{}‚v{ldd”“›{{”“›…‹‹fkk}ŠUTS}“Ś”‹„‹“Ś”‹‹‹{|||„…„„Šllk{tt{{t‹„‹š””Ł››‹„‹Ł››}tlllek‚v‚}Šldd{u{||tt{Ś‹“|„……„’‹‹‹{u{‹„„cbV„„Š|„…lldiq]jV[Š}”››››”ztl‹„„tslSKJ‚utVTLlri‚v‚lriUTSlddJHFFD;llktts›˘›SKJ:97lld{u{Ś”•‘…„Ł››||rg]JHFlek[[T|‚zekdldd™š¤bVU‹‹‹|‚zVTLek]|‚zdc\…‹‹|‚z„Š}‹‹‹‹‹„š””||tsl‹‹‹…‹’ŁśĄtll‹„‹‹‹‹„„Š‚ut{||tt{‹‹„llk“Ś”ekd‘…„tll‚u„„{{t[[Tś››{{…‹‹|‚z{{VTLtt{””‹tllttsŠ}tsl“Ś”{tttts[TTyl„{u{lddekdVTLUMR‚wlsre{u{kd\lksu{{\UZf]csleg\rred™š¤mtt‚v{{||Ś‹“{u{}||lek{||{{{{Ś‹“™š¤{||‹…š}‡’‹„‹„„Š{{…‹šŚ”•tt{„„Š…‹’|„…mttmtt^fs{{‰Šˇ|„…„„Š{{{{Ś‹“Ś”•{{¦§¨|„…Ś‹“Ś”•‹‹‹¨©´¦§¨™š¤…‹’™š¤¨©´„Š„›˘›}‡’¦§¨¨©´··Ä„„‹‹‹}ldd‚v{‹‹‹‹’ŠšŤŚ›˘›””‹™š¤tlluzt“Ś”tsl{{tf]cJHFf]cult¦§¨Ś”•tt{ś¤¦Ś”•ś››‚u”š”Ś”•‹‹‹||„…ś¤¦™š¤”“›[[Tsle[[Tkd\f]c‹„„›”›“Ś”Ś‹“||tt{\UZ{{|„…\[blkslri]bZ¦§¨ttssle{ttŚ”•tts„Š„zllkd\tllultŠ}lekmttedk“Ś”{{“Ś”{{{{…‹‹{{lld¨©´„„|‚z„Š„lld‹‹‹¦§¨¦§¨ś››lri¦§¨tts…‹‹‹’ŠcbVUTStt{|‚z\[[{{t\UZ{ttttssre„Š„slerfk||‚|u{tt„„fkkddc[[Tllkz‚lmttlriztl¦§¨UMR:97|‚|ukd\ztlu{{šŤŚylekd\{tttll„Š„ek]llk|„…{tt||{||‚wl„Š}]bZ‹’Šlriuzt…‹‹””‹ldd”“›}{{t‚|u‹„‹uztult“Ś”{{ult{||”š”||“““||‚z{{f]czllult||SKJ{ttsleuzt||{{MRKUMRlek‘Ś…””‹“Ś”š””f]c{ttdc\tlld\\tsltllj]\VTLVTL‹u…tt{‚v‚tsl|[[T[TT\UZult’ŚŚzll“Ś”ultedkldd|‚z””‹{u{›”›lddddc{{tts{{”“›Ś”•…‹’‹„‹{{yl„„„Š™š¤lksŚŚšŚ—Ł|„…\UZŚ‹“mtt|„…{{nv‚{{…‹š¦§¨ŽŁ“Ś”Ś‹“™š¤‹„‹|„…”“›{{nv‚{{{{}‡’”›››˘›‹‹„Ś—Ł››”‹…’¦§¨“““’ŚŚ¨©´Şł·u{{”››”››„Š}™š¤‹’Š…‹‹Ś”•lri‹‹‹uzt”š”llk‹‹„lek{||f]c\[[›”›¤¤ťś›››˘›“Ś”Ś‹“”“›…‹‹‹‹‹“““„„Š‹’Šllk|‚zŚ”•Ś”•{ttultmwlekb[Ulri”š”‘…„”››mtt’…‹“““f]c„„sle“Ś”›˘›{ttVZ[mtt‹’Š]cdnv‚|„…lks]bZŚ”•Ł››››”Ś”•Ś”•‹‹„‹‹„‹„‹¦§¨‹…’“Ś”“Ś”Şł·‹‹‹zlltsl‹‹‹”š”ldd{ttultfkku{{“““{{™š¤Ś”•‹„‹‹…’ldd„Š„tsl\[[lri{{t¤¤ťtt{d\\VTL||‹‹‹””‹ttslrikd\|SKJaWM[[Tf]c[TTVTL‹’Šlldlri«˛«JHFUUYsle||ldd||‹’Š‹„‹…‹‹{ttultedk‰vlritsltts{{||{zmult’ŚŚ‚ntzlsretts|‚zztl‹‹„{tt{{t{{|‚z‹‹„Łť˛tllŁ››‚ut”š”¨©´’ŚŚ|]bZkd\’ŚŚŚ‹“{u{ztlldd{{d\\edktt{‹‹„ś››||UUY[[TLKR{{f]cultttslksultUMRlksddc\UZ\UZlek}rfkŠ}|‹„„tsl|„…{{tulttts}{||šŤŚtll“Ś”f]cmtt{{tj]\f]c}mk…{tt|‚zmttu{{lks{{|„…lksult\UZtlllek‹…’„„\[b|^^qŚ”•\[[mtt|„…Ś”•n…{{MSSultś§˛¨©´›ť˛{{~’“{{ś¤¦^fs}‡’Ś—Łś¤¦‰Šˇš””š””¦§¨“““‹‹‹¦§¨‹„„‹’Š“““ś¤¦›˘›{||„„Š}‡’Ś‹“™š¤|„…›˘›ś¤¦‹’ŠŚ”•llk{tt|]bZ|‹‹‹„Š„„Š}„„{{‚ut“Ś”tll‹’Š¨©´ś››‹„„“““|‚u||‹„„‹„‹¦§¨ś¤¦{{t||‹‹‹…‹‹lriŚ”•|‚z‹„‹tt{{||SKJekd„„{{t„Š„ś¤¦|„…{{lri|„…Ś‹“ś››|‹„‹{{t“““‹‹‹uzt”š””››‹’Šś¤¦”››ś››Ś‹“¦§¨”“›‹‹‹ŁśĄ””‹“Ś”“Ś”{u{}Ś—Łmttfkkult‚|uuztuzt”››lks¨©´ult“Ś”ttsb[U|‚zult””‹lek|||srerg]||d\\ddc„Š„ztllldFD;f]clkskk]|‚z|‚z””‹””‹››”llk3+*ttsUMRf]cr]g{u{‹„‹Ś”•tsl‹„„lek{zmsletzl…‹‹š””„Š„lek’…‹””‹ŁśĄŠ}Š}ttsldd|‚zztl{{t{u{{||Š}||Š}|Š}|‹„„kd\ult{{‹’Š›˘›Ś”•…‹‹tsl|}Š‹„‹{u{[[TddclldŚ‹“„Š„„„{||VTLJHFVZTtsllks‹„„{u{„„Š“““{||{{t{{„„Š\[[\[[„Š}f]c{ttlldš””tts‹‹„f]c‚|uttskk]aWMVTLedklksmtt||f]clddtt{\[bult{||Ś‹“ŚŚš„„Š™š¤ŚŚšŚŚš{{‹„‹{u{|„…{{t™š¤}Š„Š„{{ttstts…‹’mtt™š¤\[bedk\[bŚŚš™š¤™š¤™š¤…‹šmttŞł·Ś”•{{mttnv‚Ś”•ś§˛µ¶·ŁśĄŁť˛Š~‹{{t’ŚŚ‹‹‹”››¦§¨¦§¨…‹‹ttssre|tts{||‹…’ś¤¦|„…‹’Š›˘›¦§¨|„…‹’Štts…‹‹|‚z„Š}ś¤¦‹’Š|‚z„Š}”››„Š„¦§¨“““¦§¨{{t|‚z‚wl‚uŁ››’ŚŚ’ŚŚ˛««{u{ultŚŚš›”›tt{ś››lek””‹“““‹’Š™š¤\[[||{||llk{{\[blks}‡’}‡’VZ[UMRedk…‹’uzt™š¤}{{t™š¤¨©´Şł·ś¤¦ś¤¦™š¤›˘›”š”‹’Š”››ś¤¦ś¤¦fkk{{{{{{‘…„f]cŠ}“““‹„‹ultult[[Tmttfkk„„Š„„…‹‹‹„‹lek{tt„Š„{tt¨©´|‹„„ddckk]yfdttsŁśĄ||kk]|„…ttsSKJtt{tzl[[T]cdlek‘}˛««UTS*)(“Ś”ultbVZlek{{t{u{||{{‚wluztlri””‹u{{{||f]cu{{|‚z||‹„„Ł››Š}|šŤŚultrg]››”‚wl””‹Ł››Ś”•‹‹„sle‚ut||{tt|tt{…‹’ś››{{t|‚z’ŚŚ|‹’ŠŚ‹“uztf]c[TTddctlld\\tllkd\ldd\[[ultttsekdlks‹„‹lks||UTSd\\llk…‹‹VTLtt{tts|{||{||[[Tg\rLKR‹„„lksf]cek]dc\‹„„VTLkd\]cd]cdek]||„„‹…’™š¤”“›…„’}Š…‹‹…„’“““ultŚ”•|„…llk¦§¨”“›ś¤¦™š¤lks“Ś”mtt{{{{|„…{{edk|„…\[[edk{{{{„vŚŚ”•uzt{{™š¤{{tt{™š¤Ś”•ś¤¦™š¤¦§¨„„Š}{u{‹„„|‚z››”‹’Š“Ś”™š¤tsllksultult||ś¤¦„„Štll|Ś”•¨©´|„…{||„„Šś››…‹‹Ś”•]bZtts”“›tt{…‹‹…‹‹\[[lri””‹|‚z¦§¨tzl]bZttsu{{tll‚wl}Š„„‚u„„|‚zedkuztu{{Ś”•{{™š¤„„…‹’mttult{{t{{lri\[b]cdmtt|‚zz}lri|„…lksś¤¦„„Š¨©´Ś”•ś¤¦…‹’Ś”•ś¤¦Şł·”››f]c|„…‹’Šš””u{{ś››Ś‹““Ś”\UZŠ}|ult}tll{tt‚|uUMRllk“Ś”{{tŁśĄ™š¤lksultlks‹…’{u{mttttsŠ}}[[TSKJbVZŠ}tt{‹„„„Š}[TTllktslkd\||sle|‚ztll{{t¦§¨llk74,SKJtll’…‹ddcmttldd{{tsle‘Ś…“Ś”f]cslesle|„…lri|‚z‚|u{tt‹‹„Ł››¦§¨‚|u…‹‹„„‹’Šsre|Ś‹“™š¤’ŚŚlld‹‹‹mtt‹„„|ddctt{”š”‹’Š„Š„{u{tslr]Zu{{‹‹„‚|uultllkfkkSKJ]bZ]bZF=CF=Cmttlriś¤¦„„|„…{{t‹…’Ś”•tsllkstlltts]bZlekuzt|„…ddc„Š„lkslrid\\sleu{{slesred\\cbVtll}uztlritll{tt„„Š…‹‹Ś‹“ŚŚšŁśĄś§˛{{‹„‹ś¤¦™š¤ŚŚšllk™š¤‹„‹Ś‹“‹„‹{u{}lks|„…{{Ś”•|„…tt{|„…|„…›ť˛›”›nv‚|„…{{lks“Ś”{||…„’}ŠŁť˛“Ś”ŁśĄ™š¤{{™š¤tll‹„„tts[TT{ttŚŚš”“›¦§¨¦§¨}’…‹‚v{š””‹‹‹ztl||mtt{u{…„’{||Ś”•ś¤¦„„™š¤SKJŚ‹“‚|u{{tŠ~‹…‹’Ś‹“{{|„…”š”edk|„…tsltzl{{t‹’Š‹‹‹›˘››˘›’ŚŚ{{„„lekŚ”•Ś‹“tt{Ś”•…‹’{{mttldd]cd‚v‚lksu{{\[bUUYŚ—ŁmttŚ—Ł|„…{{{{VZ[„„Š…‹‹Ś”•«˛«™š¤¦§¨|„…mtt”“›™š¤™š¤tt{„„Šlks™š¤lks…„’Ś‹“ult\[[dc\||UMRyflreddc\j]\„„Šj]\{ttllkedkb[Uultult]cddc\[TTVTLtll[[Ttllr]g}{{t››”‹‹„ekdultbVZj]\UTSC8.JHFldd˛««›˘›JHF!ekd{{{{tultllksle|‚zb[Uš””‹„‹{{“Ś”Ł››||ś››…‹‹|’ŚŚŠŠ}{ttŠŠ}‹„„ś››‚v{‹„„‘Ś…|ttssle’ŚŚ‚u„„„Š„‹„‹ś¤¦”››f]cŠ}’ŚŚmtt{{t…‹‹lri|„…‹’Š{||‹„‹tt{™š¤dc\tllekdlld‚v‚mk…mttŚ”•ś››Ś”•„„Š{|||„…„Š„rfkekd„„[TTekdlld‹‹„mttek]…‹‹}‹„„lek\UZVTLlksŠ}red’ŚŚult„„Š‹‹„d\\“““››”…„’”“›…‹’‹…’{{ŚŚš{||¦§¨}‡’ŽŁ\[[ddcult{||}Š„„¦§¨lks|„…ttsŚ”•„Š„ŚŚš‹‹‹|„…”››„vŚ‹…’…‹‹„„Š|„…”››|„…”››™š¤Ś‹“Š~‹™š¤‹…’Ś”•|„…Ś”•ś¤¦™š¤”››Ś”•›”›‹‹„ŁśĄ”“›lks{u{ŁśĄ›”›…‹‹“““…‹‹…‹‹ldd{{‹‹‹mttś¤¦Ś”•ś¤¦MSSUTSttsŚ”•“~ztl‹„‹‰v|]bZ””‹cbV¦§¨””‹|‚z””‹Ś‹“Ś‹“„„Š„„Š„„Š\UZddc\[[[TT{||™š¤Ś”•|„…™š¤mtt\UZlksultJHF\[bŚŚšUMR}Š|„…Ś”•||ś››“““ult{{tultś¤¦ś¤¦…„’Ś‹“™š¤µ¶·|„…|‚z‹’ŠŚ”•…‹’“Ś”Š~‹‹„‹{{ś¤¦ŁśĄ}Šf]c[TTleksleztl{u{red“Ś”{tt‹„„‘…„™š¤rfkult|ddc‹‹‹”“›ztl|ś››||j]\„„Š‚u|cbVddcztlllk}kd\‚u{{t||{zmµ¶·MRK*)(|‚ztlltts[TTlriredtsl|””‹}’ŚŚlld||„„Š‹‹‹‚n‹„„˛¬µ|‚|uŠ}ś››«˛«‹„‹“““{zmlri™š¤’ŚŚztlbVUŚ‹“{tt|‚ztt{””‹uzttts””‹‹’Š‹„„|‚z”››||“Ś”tts‹‹‹…‹‹“Ś”š””“““mttUTS^^qlks{u{…‹‹™š¤…‹‹Ś”•{{Ś”•{||‹’Šlddztldc\ś››ult„Š„…‹‹ŠŠ}‹„„‹…’||}{{”“›…‹‹“““Ł››Š}\UZ{{||}µ¶·¦§¨Ś‹“™š¤‹‹‹†~‘|„…Ś‹“{u{uzt…‹‹{{|„…‹‹‹ult‹‹‹„„Š„„Šś¤¦mtt™š¤…‹‹ś¤¦…‹’…‹’Ś”•„„¦§¨„„Š™š¤””‹“““edk‹‹‹“““Ś”•{tt…‹‹¦§¨™š¤llkŚ‹“‹’Šult|„…ult“““Ś”•“““‹‹‹›˘›ś››¨©´|‚z|{||Ł››‹‹„tzl‹’Šsle{||„„Š|„……‹‹”š”‹‹„]bZŚ”•ult{||{zm||{{|‚zŚ”•›˘›{{t””‹„Š}{{t{{t|Ł›››˘›„„{{tdc\tsl[TT‹‹„kk]f]cf]c{{tt{„„Štt{lek|„…tt{fkkmtt]cdŚ”•}‡’…„’™š¤”š”’ŚŚŁśĄ‹…’|„…Łť˛¬¶Ă™š¤™š¤‰Šˇ{{”“›ŁśĄ™š¤™š¤””‹š””ult|”“›}{||tsl{||llkedkŚ”•„„Š‹„‹¨©´}||“Ś”Ś‹“{u{“Ś”ldd“Ś”{tt“Ś”||slesleŚ‹“‹„„{{tj]\„Š}kd\ek]dc\ekdredVTLb[UVTL]bZSKJlksµ¶·VTL*)(|{u{{u{ztltts‚utsre‚|u””‹{{‹’Š™š¤b[U|‚zult‚ut”››|„…iq]{{t””‹‹‹„ś››{||™‹†b[U{zmŚ”•Ś”•{{t‹‹‹‹„‹|‚z{||{u{tt{tt{”››«˛«”š”tslmttuzt|‚z…‹‹}Ś‹“„„Štts¤¤ťuztlritsl]cdMRKllkmtttll‹’Š\[[Ś‹“|„…ztl{{{{t{tt‚|utsl{tt|‚zbVZ‹‹‹Š}Š}“““‹„‹›”›{ttmtt‹‹„‘Ś…lldSKJlddJHF’ŚŚ|‚z}|„…}Šlri’…‹ś››mttŁśĄ‹„„mtt{{|„…}›”›‚wl†~‘¨©´¦§¨™š¤Ś”•ś››ś¤¦mtt|‚z”››ś¤¦…‹’tt{|„……‹’‹…’{||…‹‹ultu{{mttmttŚ—Ł…„’lks””‹¦§¨«˛«¦§¨¦§¨ś››ś¤¦{||Ś”•”››…„’ś¤¦„„Š”“›lks…‹‹|„……‹’ddcf]c”“›µ¶·{{{u{¦§¨…‹‹„„Ś‹“lks””‹[TT\[[dc\|‚ztsl“Ś””“›«˛«„Š„››”ś››|‚z‹‹„Š}}{{d\\llk’ŚŚ‹‹„tsl™š¤{{t}ttsdc\ult[[TUUYlriuztMRKtllllkyl„ddc{{“Ś”Łť˛ŚŚš”“›ult””‹{||}‹…’™š¤tt{¨©´„„Š„„„„Ś”•„„Šztl„Š„”š”{||tsltt{u{{ddc”“›™š¤ś¤¦”“›”››‹’Š„Š„‹‹‹„Š„Ś”•“Ś”\[blldlddedkdc\‹’Š{{t‹„„lldj]\{ttSKJSKJ]bZlridc\d\\j]\j]\lddekdtts„„˛««UTS*)({tti\Vldd{ttŚ‹“‹„‹Š}Ł››zllsre‹„„{{t{{tllkš””’ŚŚtsl›”›lrid\\yle’ŚŚ‹’Š¦§¨||“Ś”‹‹„{u{lldyle‹‹‹ttsŠ}|{||„„Šd\\…‹‹‚|u‹‹„|{|||„…lrikd\…‹‹kd\„Š„ś¤¦”››“Ś”uztu{{uzt]cdUMR]cdddcd\\Ś‹“]bZult\UZd\\‚nsleu{{||{ttf]c{{tdc\|„„Š}JHF{tt[TT‚|utsl|mwUMRtts“Ś”‹„„lksultlkstts{u{‹’Š™š¤“““{{š””ŁśĄ|„…|„…{||ś››“Ś”””‹Ś—Ł„Š„‹…’ŚŚš…‹’„„…‹‹{{tŹˇˇ“““|„…lks{{{{…‹’¨©´{{”“›‰Šˇ{{{{…„’{{nv‚lksŚ”•»ÂÇŚ‹“…‹š”“›…‹‹››””š”ś››‹’Š„„Š¨©´ś¤¦”››ult‹’Šu{{‹„„›”›‹„‹“Ś”¦§¨‚ut„„Š”“›‹’ŠŁśĄ™š¤{{”“›tts{{{||‹„„”›››”›¦§¨ŚŚš…‹’¦§¨“Ś”\UZŚ‹“”“›ult‹…’]cdult„„Š{ttult™š¤“Ś”llkŚ‹“|„…ultedk“Ś”…„’Ś‹“tts\[bf]cult¨©´{u{ŚŚš{{Ś”•„„„„Šttsmtt|„…tt{„„ŠmttŚ”•{{›˘›Ś‹“ś¤¦‹’ŠŠ}Ś”•lld|‚z‹…’ś››“““dc\‚v{tts”š”|‚z„Š„š””d\\lks…‹‹|„…d\\red{{“““}Š\[[tslSKJ||tsl{ttultdkVSKJVTLVZTmtt\UZredtllztl\[[SKJ{{t˛««JHF*)(dc\ultd\\i\V„„{tt››”‘Ś…|~’“…„’sre‹„„d\\‚v{„„Š’ŚŚ„„lldek]f]c‹„„…‹‹|‚z||Ł››‹„„’…‹””‹zll‹‹„„„‹‹„tll‹’Š‹„„„Š„{tt‹‹„””‹„„tt{|‚z‹‹„|„…llk››”™š¤|„…||„Š}ek]|„…cbV„„Šlldmttd\\lldllkedk{{Ś‹“llkultttsŠ~‹’…‹bVU››”[[T‹„‹|sreddcttsf]c‰v|||„„sleb[U‚|u‹‹‹„„tt{d\\\[bLKR™š¤”“›™š¤“Ś”{{„„“Ś”llku{{”››”“›{||Š}rfkŠ}™š¤{{{u{zllś¤¦Ś”•¦§¨Ś‹“u{{…‹‹™š¤™š¤ult™š¤…„’ult…„’™š¤{{‹…’{{›ť˛›ť˛ś§˛”“›{{‹‹‹™š¤””‹”“›ś››“““tsl…‹‹”“›}Ś‹“Ś”•|„…{||lldmtt…‹‹›˘›Žˇ›ś¤¦¦§¨lri›˘›Ś”•tts…‹‹‹‹„slemtt\[bult}|‚z“““uzt‹‹‹›˘›…‹‹lld„Š„‹‹‹…‹‹ttslri“““ś››‚u„„rfk}“Ś”‹„„dc\JHFf]c„„ultlldult{u{f]c}Š…‹‹{||mttlldŚ”•ś¤¦{{”“›‹„‹}„„Š…‹‹™š¤›”›{u{”››ztl|‚z¤¤ť‹‹‹{{ttslsle‚udc\„Š„ztl|tzl“““slelksekd{{t¦§¨{||ultleksleUTSŚ‹“{||d\\slett{‰vldd{ttsle‹’Š{{tUUYztlult|„…„„”š”sremttSKJcbV””‹F=C*)(d\\tts[TT‚v{{tt”“›{{t‚u{zmultred{{tŠ}ldd‘Ś…“Ś”llk|‚z\[blld{{‹‹‹Ś‹“„„‹‹„‚|u‚u””‹Ł››|„…µ¶·”“›„„Šult„Š„‹„‹|‚z“““››”‹‹„”š”f]c”››|‚z‹’Š„Š„Š}ttsu{{]cd”š”JHF}Š[[Tf]c\[[tt{ulttlllriŚ”•{{}lekedkllk|‚z„Š„‚|u‚|udc\llkb[Ui\VUTSlddUMRkd\VTLrg]f]cf]c“Ś”‹„‹¦§¨‹„‹‚|u|„……„’„„Š…‹‹‰v…„’ŚŚš„„ś¤¦Ś‹“™š¤{{{||tll¦§¨Š}‹„‹™š¤”“›Ś”•“““Ś”•Şł·„„|‹’Šuztlks{{{{™š¤Ś‹“‹’Š…‹’|„…}‡’{{^fs}|’~’““Ś”ś¤¦ś¤¦}Š„„‹‹‹„„tll|tt{‹‹„ś¤¦tsl››”lri‚u‹„‹llk}lektt{¦§¨¨©´}Ś‹““Ś”‹’Šlld“Ś”f]ctts{tt|„…uztj]\™š¤’ŚŚś››‹‹„|„Š}tzl””‹ŠŠ}”››µ¶·‚ukjVš””||ztlšŤŚtll\[[„„Šddcult‹…’„„Šult‹„‹›”›{u{{{tll‹’Šuzt‚|uś››tll{{ŽŁ„„Š|„……‹’”››…‹‹{{“Ś”{u{Ś‹“u{{„„ś¤¦ś››{||]bZlriUTSd\\u{{‹„‹f]cŠ}ult{||™š¤d\\{ttsle‚|uztl}‹„‹u{{Ś”•|’ŚŚ{||{u{||’…‹¦§¨„Š„¦§¨‹’Š{||||Ś”•Ś”•‚|u}JHF[TTkd\¤¤ťVTL74,ulttsltts“Ś””š”“Ś”bVU|‚wl[TTsle{tt{ttult‰vlek‹„‹lldlriekd||tllŚ”•|„…‚ut‚|uŠŠ}|’ŚŚ{||‹‹„|‚z‹„„„„Š””‹{tt{{t›”›¤¤ť‹‹„|‚zult…‹’„Š„‹’Štslult}”“›{||”››ekdf]cUMRVZ[\[b}||‹‹‹u{{Ś”•ek]”››”“›™š¤‹„„[TTlri{{|ddclridc\j]\Ś”•lriultlekŠ}””‹[TT}„„Š…‹‹¨©´Š}Ś”•”››™š¤Łť˛…‹‹…‹‹¦§¨{{Š~‹|„…„Š„ŚŚštt{}uzt“Ś”lri}„„Š™š¤Ś”•”“›‹’Š|‚zu{{Ś‹“lriuzt{||“Ś”“““Ś”•lkstt{‹…’›”›™š¤¨©´™š¤¨©´¨©´{{™š¤Ś”•¨©´™š¤“““||lld|„…”››|‚z|||‚z”››ś››¦§¨¦§¨››”¦§¨‘…„tts{tt“Ś”Ś‹“¨©´“““ŁśĄ…‹‹‹‹„lekŚ”•UTSttsŚ‹“‹…’„„Š‹‹‹„„“Ś”}š””Š}|Ł››{zm¤¤ť¤¤ť››”ś››¦§¨‹‹„{{t‚v{tts„Š„““““““VTLlldlldSKJ‹„‹™š¤lekedk›˘›«˛«ś§˛uzttts}}„„…„’™š¤ŁśĄ“Ś”™š¤‹„‹{u{”“›{ttult¨©´µ¶·Š~‹tts||mttf]cŚŚš}Š„„lld‹‹„‚v{”››‹…’}tt{ztlrfkult›”›bVU™š¤u{{|ult…‹‹sle”“›‰v‹„„{{„„‹‹„}{||„Š„‹‹‹’ŚŚcbV{{tedk{||„Š„¤¤ťJHF*)({{lddttsztl“““ultcbV||””‹rfk{zm’ŚŚ„Š}tll‹‹„j]\‘Ś…uztuztztflddd\\|tt{¦§¨™š¤‚u|’ŚŚ{||„„Šlri{{t”“›ś››››”™š¤‹„„”“›|llklek…‹‹«˛«Ł››{||||‹’Štts…‹‹|„…‘Ś…‹„‹|„…}‡’mtt}d\\š””{||srett{Ś”•›˘››”›™š¤lekztltzlkd\“Ś”|kk]kd\{zm}Š{ttu{{lrilld‹„„f]cztlŠ~‹{{tddc‹„„Ś”•„vŚŚ”•„Š„…‹‹mtt›”›rfkUTStsl{{|„…lld’ŚŚ‹…’…‹‹tslyl„ult™š¤{||…‹’mtt{||{{tleku{{›”›}‹„‹|„…Ś‹“‹’Š“Ś”ś¤¦ś››¨©´”“›„„Š{u{„Š„”“›Ś”•„„Ś”•lri‹’Š„„ś¤¦‹’Š…‹‹uzt{u{··Ä“““¨©´„„Š’ŚŚŠ}’ŚŚ’ŚŚbVZ„„ŠsleŁ››“Ś”‹’Šult””‹¦§¨›”›‘Ś…Š}¦§¨˛¬µ›”›”“›¨©´¦§¨lek˘—Ť‹’Š›˘›ś››››”›˘›“““rg]sleŠŠ}lri{zm“““tzl{{t””‹[[Tllduzt‚u™š¤Ś”•{{mtt„„Š™š¤}Š]bZ…„’ult‹uŠ{u{‹„‹“Ś”ŁśĄ“Ś”ult‹…’tsl“Ś”lksVZT{{Ś”•u{{‹„‹™š¤}{u{}„„Š‹…’‹…’{{}Šlldsle|‚z{{ttslkd\ultlksult}ddcu{{bVZ…‹‹„Š„’ŚŚ[TTd\\{tt{tttygtts{{t‹‹„lektllkd\‚|ulkslldtslŁśĄFD;*)(Ś”•‰|vtt{rg]|„„‚|u‹‹„tsltsltll{u{kd\|„…‰vztl›”›lri‹’Š’ŚŚedk{{Ł››Ś‹“‚|uultz‚llld{{Š}›”›”››lldf]c}Š{{tŚ”•tll“““›˘›Ś”•ttsś¤¦”››¦§¨|„…\[[rfk||uzt|‚z”“›Ś”•u{{‹„‹ŚŚšlri{{””‹‹’Š…‹‹{{‹„„|‚zś››||}Š‹’ŠŚ”•{tt}rg]‹‹‹{{t|‚z„Š}}“““|‚zlriuzt}lek‹…’‹„„lldllk”š”†~‘u{{…‹‹llkŚ‹“{u{Ś‹“||{||ttsś››™š¤{||‚v‚tts‹„„{ttf]ctt{Ł››|„…‹„„”“›{{t”š”{{t›˘›ddc}u{{¸Áąś§˛™š¤¦§¨¦§¨‹’Štts{{|„…mtt™š¤ś¤¦tt{Ś‹“u{{{{|„…”“›”››“Ś”||‹‹‹˛¬µś¤¦””‹{u{edk‹„„{{…„’”››“““u{{¦§¨”“›‹…’’ŚŚŁ››¤¤ťŁ››¦§¨¨©´Ś‹““Ś”¨©´¦§¨”“›‹‹„redtllš””›˘›¦§¨Š}ŁśĄVTLztl„Š}¤¤ť‚u‹„„sleztlVTL{u{Ś‹“Š}“Ś”“Ś”‹„‹f]c™š¤Łť˛ŁśĄ…„’|„…u{{mtttt{lksŚ”•“““ś¤¦™š¤™š¤ś¤¦››”||‚z„Š„|„…‹’Š‹‹„|„…u{{¨©´Ś‹““Ś”“~bVUtslŠ~‹”››„„ŠJHFek]lks\[[¦§¨lrilri\UZbVUŚŚš„„’…‹ult“““kd\zll[TTd\\uzt‚|usre’ŚŚd\\uztmw[[TSKJ|JHFd\\ult”“›JHF*)(‚|uztl”š”red‚ulekrg]ztl¦§¨’…‹”š”‹‹„ult‹’ŠŠ}sreŁ››ult|‚z‘Ś…tts‹„‹fkk|‚zŠ}‹„„””‹Ł››’ŚŚ“Ś”sre…‹‹ś¤¦llk{u{›˘›“Ś”¤¤ť„„›˘›{||„Š„¨©´¦§¨¦§¨”››{u{lldu{{…‹š|„…uztultLKRVTL\UZlek“Ś””››”››uzt‹„„‹‹‹tts{u{…‹’™š¤ś¤¦[[T{{lldultllk|‚|u‹’Šztl}red„Š„„„‚v‚lddš””tsl{ttś››¨©´uzt…‹‹lldlks||Š~‹›”›‹„„lri[TTtslf]c„„Š‚uttsltll‚v{Š}”“›||||‹„‹lks||‹‹‹|‚zult{{¦§¨Ś”•ś¤¦™š¤Ś”•Źˇˇś¤¦ś¤¦|„…|„…Ś”•„„Š¦§¨{{”“›„„Š“Ś”ŁśĄ™š¤™š¤‹„‹¨©´¦§¨{{¨©´›”›™š¤™š¤““““Ś”Š}˛««{u{llk…‹‹’…‹··Ä‚v‚yfd||‹‹‹‹„‹™š¤™š¤rfk“Ś”‹…’}‹’Š›”›™š¤„„‹‹‹Ś‹“{||„„ztluztlri‹’Š|„…lrillktt{|„…‹’Š{{]cd]cdś¤¦mttfkkfkk{{Ś—Ł¬¶Ă™š¤|„…}‡’™š¤…‹’…„’”“›|„…Ś”•{{‹…’mtt{||„„Š‹‹‹¸Áąlld””‹Ś”•lri‹‹„kk]„„„„lldŚ‹“…‹‹‹„‹…‹’ddc|‚zlld‹„‹||„„Šddcldd{{{{JHFUUYu{{lddJHFf]cldd||ttsllkŚ‹“lri‚v{ddclldj]\dc\Š}„„Š}lri|¦§¨JHFJHFuztlld{ttztlšŤŚllkjV[|‚z|‚zkd\“Ś””š”Ś”•uzttsl””‹‘…„„„Š„Š}|‚z“““ztlŠ}tsltts{tt„Š„¦§¨‹„„ś¤¦”››{||“Ś”Ś‹“ult|‚zlekŁ››µ¶·Şł·›˘›…‹’¦§¨Ś”•‹‹‹ŁśĄś¤¦‹‹‹”››uzt]bZMRKlld]bZ|„…tt{‹„‹…‹‹‹‹„™š¤{{tllk…‹‹‹’Š||ś››u{{…‹‹„Š„|Ś‹“|‚zbVUtsl‹’Šlldfkk|„…‹„„tslsred\\fkklddŠ}|{{t}Š¦§¨{||…„’‹’Štts]bZ{u{¦§¨†~‘¤¤ť|||{u{tts{||f]c‚|u“Ś”|„…ttsś¤¦””‹ŚŚšŠ~‹ldduztu{{…‹‹…‹’„„|„……‹‹Ś—ŁŚ”•}‡’|„…|„…mtt|„…„„‰ŠˇŚ”•‹…’ś››™š¤{{|„…Ś”•™š¤|„…ŁśĄ‹…’“Ś”ttstt{˛¬µ””‹¨©´“Ś”…‹‹™š¤uzt{tt„„‚ut¦§¨Š~‹“Ś”}‘Ś…Š~‹f]cmw’…‹}š”””“›‹„‹Şł·‹„‹llklek“““ś››tts{{lrilri’ŚŚŚ‹“…‹‹…‹’™š¤edkultJHFlks{{…‹š{{lksedk|‚z’|‚zŚ—ŁŚ”•lks””‹|‚zuzt‹‹‹„Š„¦§¨¦§¨‹„‹Ś‹“›˘›Š}|””‹Š}|‚u””‹VTL””‹‰|vŠŠ}slerr]tzl|‚z|[TT|lriŠŠ}‹’Š|tslUTS”“›d\\|„…ekd‹…’uztyl„[[TŠ}“““‹„‹Š~‹””‹VZT””‹lek‚v‚lldultztlf]c{ttF=Ckk]rg]˛««UTS*)(slej]\…‹‹Š}|‚|ulddŠŠ}ŠŠ}‹’Š›”›”“›””‹“““ttsrg]sle‚|utt{VTLsleztlŠ}„„Š‹„„zll›”›”š”””‹¤¤ť|ś¤¦“Ś”¦§¨Š}‹„‹u{{{{“Ś”¤¤ť’…‹Ś”•ttsŚ‹“‹’Š¦§¨“Ś”¦§¨ŁśĄ™š¤|‚z‹‹‹lriUTSJHF[TT{{{{„„ś››ŠŠ}ś¤¦|uzt{{t{||fkkŚ”•ś¤¦tslmttsre{ttu{{Š}b[U„„…‹‹}{||””‹tzlkd\74,{u{ztlŠ}ztl™š¤||uztmtt{u{™š¤‹…’f]clriŚ”•‹„„d\\„„ŠŚ‹“„„lddttsultult›ť˛Ś‹“}Š“““„„[TTlks{{Ś”•‹‹‹…„’|‚z|„…fkk‹’Š|„…‹’Š|„…¦§¨““““Ś”{{“Ś”‹‹‹‹…’”“›ttsu{{›˘›””‹]cdtts{u{||\[[}”“›“Ś”|kd\{zm‹‹‹Ś‹“ttsšŤŚŚ”•ekdttsf]ctlldc\tzlJHF{||lkstll’…‹¦§¨’…‹ŁśĄ‹…’”“›{{”“›¦§¨lkszlld\\dc\‚v{red‰v|{u{f]cedku{{Şł·””‹„„“~llkekduzt›˘›|‚z‹’Š›˘›‹’ŠŚ”•ttsmtt‹’Š‹‹‹}ŠŁ››“““›˘›{||tll„Š„kk]{||tll›˘›‹‹„llklri|‚zVTLek]„Š„””‹dc\‹’Š|‚z””‹|dc\{{t{||lksmttultś¤¦mtt{{}{{…„’Ś”•‹‹„””‹™š¤|[TTsresle{||lld]bZrr]JHFttsJHF{zm‚|u””‹JHF:97tsllrilld|Š}‹„„|‘Ś…‹’Š””‹Ś‹“‹’Š„„‹’ŠŠ}Š}‘Ś…’ŚŚ‚u‚ukd\Ś”•‚v{™š¤ś¤¦Ś‹“””‹››”|”“›¦§¨“Ś”Ś”•tt{}{u{”“›Ś‹“›”›u{{“Ś”lks||lriš””ś¤¦’ŚŚ„„|„…|„…{||llkmttf]c{{{||“Ś”‹‹„{{t|‚zś››„„Ś”•”š”uzt„Š„lek„„Šdc\tt{Ś‹“kk]lek||d\\|‚z|‚z{||||||‹‹„kd\VTL{||tllŁśĄsre¨©´¦§¨|„…„Š„||”š”’…‹UMR†~‘’ŚŚś››}‹„„{ttš””ś››‹’Š||kk]}{{›”›¦§¨‹„‹‹’Š{u{Ś”•{{|„…{tt‹’Š|‚z|„„Š“““Ś‹“„Š„{||{||{{…‹‹™š¤„„{||„Š„…‹‹„„Šś¤¦„Š}ttsuztUTSUTSSKJSKJ|‹„‹“Ś”…‹’Ś‹“Š}‚utŁśĄultš””sle„Š„lksddcd\\lek||uztddctsl}¦§¨{u{…‹‹\[b}””‹„„Š„„Š{{f]c]cdJHFultllkŚ”•‹‹‹tsl||””‹lddD;9lldbVUuztekd|‚z{ttek]|‚z›˘›Ś”•‹’Š‹‹„|‚z|‚z””‹‹’Š›˘›‹’Š“““‹’Šś¤¦Ś”•|‚z|‚z‹‹„„„|‘Ś…|yle‘…„ekd’ŚŚ‘}||||[[TbVU‹’Š‹„„„„‹‹‹”“›{||‹’Šś››Ś‹“||{{t‹…’|„…™š¤dc\…‹‹\[[mtt›”›lld[[TSKJVTL„„„Š}tts‹„„|„…\[b{{tj]\””‹JHF*)({tt|‚z‹‹„‚|uŠŠ}Š}‚|u{zmdc\‹‹„leklld|„…‘…„{{t››”slellk””‹””‹||‹‹„’ŚŚuzt{||Š}z‚l||||llkš””{u{|‚z†~‘“Ś””š”{{‚v{¦§¨Ś‹“mttlekŚ”•‚u™š¤Ś”•¦§¨ś››‹‹„llk{{ldd|„…{{ekdś§˛{tt„„”“›|‚z…‹‹„„‹’Š|tts“Ś”ldd{u{|‚z‹…’‚|u|‚z›”›tllztldc\‹’Šś¤¦‹„„””‹››”b[U[[TddcVZTtlldc\ekdldduztlri||{ttlek‹„„}„Š„u{{ekd’ŚŚ{||™š¤¤¤ť}zll{{‹„‹ult¦§¨¦§¨ŁśĄ’ŚŚ‹‹„›”›mtt{{¦§¨{{„„{{Ś‹“‹‹‹”››™š¤mttek]lri|„„|‚zś¤¦…„’|‚z‹‹‹”š”{{t„Š„‹‹„lldultttsUUYŚ‹“dc\“““›”›„„Š‹„„Ł››‰v|Ł››··Ä’ŚŚŠ}|‚v{s_qred”“›}VTL‹„„]cd’ŚŚ¦§¨›˘›tzl‹‹„tzlmtt‹’Š{||‹‹‹f]c[[T|„…lksedk‹„‹\[[}‹„‹tt{‚|u{{}b[U{{d\\tt{|„…™š¤mtt{{”››{{…‹’™š¤¦§¨Łť˛‹‹‹ŚŚš‹’Š“““Š}šŤŚ‹„„|ś¤¦”››||‹‹‹redslej]\ultbVUŁśĄr]Z‹„„cbVkd\sle‹„„lddkd\{tt“Ś”tll‹…’\UZ„Š„VZ[dc\edkŚ”•uzt[[TŚ‹“[TT\UZ„„lld[[Tzll‹…’””‹kd\š””‹„„›”›ŚŚšVTLj]\ś¤¦>EC:97ultŚ”•|‚z{{t“““zll ŤŤztl”š”‘Ś…VTL|„Š}Š}|šŤŚŁ››‹‹„„Š„š””Š}|red”“›{tt”“›{tttll”š”“““tts‹uŠult™š¤‹…’…„’“Ś”|™š¤¦§¨|ultdc\{u{“““¦§¨’ŚŚŠ}„Š„‚v‚…‹’edk„„Š{{{|||„…LKRtslmtt‹‹‹u{{‹‹„ttsd\\ttsuztldduztj]\|tt{llklddkk]tt{‚|uldd|„…›˘›™š¤{zm„Š„™š¤„Š„„„Š|‚zlrid\\‹„„||ekdlekś¤¦|‚z|‚z{u{{zm[TT|‚zttsUTS‚|u{{t‹’Š’ŚŚ›”›||Ś”•ś¤¦™š¤ŽŁ{{“““{tt“Ś”fkklks{{Ś”•‹…’ŚŚšŞł·‹‹‹…‹‹Ś”•Ś‹“|„…”››]cd…‹’tt{fkktt{|„…|„…”››mttulttts”“›™š¤…‹’‹„‹“Ś”“Ś”ŁśĄf]c|‚z¦§¨|‚z”››{u{“Ś”‹…’{u{‹’Šult’ŚŚ’…‹“Ś”kd\SKJkd\tllŚ‹“Ś”•’ŚŚ…‹’}Š{{t{{t„Š}‚uttslSKJJHFb[U|tsl‰vldd|]bZ”“›dc\mtt|„…ttsVZTult…‹’|„…{{‹…’ŚŚš}{u{‹„‹}’ŚŚ··Ä‹…’ŁśĄ||bVU“““››”Š~‹ult|‚zŠŠ}dc\ldd|‚ztslUTSSKJ””‹‹‹„lld[TTslej]\\[[MRKŚ”•[[T{{t„„„Š„lksllk{||ś››{||Ś”•mttlrimttddc[TTj]\„Š„Š}kk]lddtsl‹‹„‹‹„Ł››u{{{u{\[bVZ[}|JHF*)(tll|‚z‚|u””‹‹’Šyle‚utkd\sle||j]\{{t“““‰v¤¤ť›˘›””‹ddcŠ}kk]ztl’…‹’ŚŚ‹„‹||}tts‹’ŠŠ}|„„{tt…‹‹„„Štt{Ś‹“ŁśĄ™š¤”“›|‚z”š”””‹„„Štts{tttsl„„{{t{u{tsllriŚŚš‹uŠVTL\[b[[Tedk‚|u¦§¨„„|‚zlektt{{{lddtts||leklddlldtllŠ}‘Ś……‹‹››”tll||„Š„tsl\[[{||ult{{tMSS|‚z|‚zu{{|„„Š„Š„lddu{{|„…”“›{tt|sleSKJfkkVTL{ttztltzl‚|uŠ}“Ś”{{t„„Š{{‹‹‹{zmtll‚v{“Ś”ult›”›{{„„”“›„„¦§¨”››|‚znv‚ultmtt„Š„…‹’ŁśĄś››“““ś¤¦“““”“›ult‹‹‹|‚z…‹‹Şł·˛¬µŁśĄ”“›ś››™š¤ś››¦§¨¦§¨¦§¨‘Ś…ttstt{Ś”•|{{tkd\›”›„„Š”“›dc\”“›{{‹‹„kd\ultŠ}‹„„‹’Š{tt’ŚŚŠ}šŤŚ‘…„“Ś”‹‹„kd\iq]|‚zUTS|””‹{tt‹’Šllk‹‹‹[TTedklksu{{„„Š]bZVZ[lri]cdlek‹„‹|„…lekllk„„Šllkkk]‹‹„‹‹‹{ttś¤¦{{tllk||‚u””‹››”‹‹„‚|ulksllkb[Udc\VTLjcVcbV]bZlddVTL}”“›dc\\[[uzt{{tlksttslddmtt|‚z™š¤]cd“““‹„„‹‹„lld{u{‹’Š[[TVTL{{tlrillk{{t‚uddc[[TedkmttUMR‹‹„>EC74,|||‚z„Š„‘Ś…tsl‚|utllkd\{zmldd|‚z]bZ‹‹„‚|uŠ}Š}¤¤ťś››tt{{zmś¤¦|ztl{u{lks‹„„”››|‚zŠ}|“Ś”}ŁśĄ‹’Šu{{”“›’…‹||‹„‹ś››Ś”•Ś”•{ttf]c[[Tsre{|||‚ztsl‹‹„ldd„„Š“Ś”]cdtt{””‹{{lks|„…™š¤ś››lksfkk||„„tllSKJlddSKJ[[TlekŠ}‹‹„„„‹‹‹ult‹‹„ekdlld\[[|‹„„‚|uMSS\[b\[[lld„Š„Ś”•Ś”•d\\edk„Š„”š”š””f]cś››kd\|‚z„Š„ult|||‚z¤¤ťult‹‹‹„„’ŚŚ“Ś”ultŠ}|„„edkf]c{{ś¤¦…‹’›”›„„Šlks„„|„…{{mttmtt|„…{u{…‹‹›˘›ś¤¦Ś‹“|„…tsl{{{{Ś‹“¨©´™š¤Ś‹“ŁśĄ¦§¨ŁśĄ¦§¨µ¶·»ÂǦ§¨Š}sre‹’Š‚ut“Ś”sreŠŠ}”š”{{t{u{‹‹‹¦§¨Ś”•Ś‹“’ŚŚ‹„„{tt›”››”›¦§¨…‹‹|‚z¦§¨š””‰‰w‰v{{t‚ukd\‚|ulldtslŚ”•›˘›{{tś¤¦…‹‹tt{lek…„’lks‹„‹“Ś”™š¤ultŚ‹“›˘›ŁśĄ‹…’}u{{ulttts{ttŠ~‹ultllk|||ŁśĄllkś¤¦Ś”•u{{™š¤tts|‹„„‘Ś…kd\‹„„||ult|‚zllk’…‹kd\‚usre„Š}VZTŚ”•ekd„Š„lksJHFUMRlri|„…]cd…„’›˘›‹„‹„„bVZ|‚zlldUTS‚|ulld||dc\sleVTLJHFJHFJHFztlJHF3+*{u{››”‚u]bZtsl‚|u{tt‚ut{{tjcVb[Ukd\ttssleŁ›››˘›||{u{’…‹{u{’ŚŚrfk‚ut“““fkk}„„llkś››ult‹„„{||Ś”•}›”››”›„„Š’…‹‹’Š|‚z„„Šf]c{u{‹‹‹‹’Š‹„‹zll\[[tt{”››…‹’lekdc\\[bf]cult{{tllk„Š„‹‹„llk„„ldd}‹„‹‹„„‚u‹„‹f]c‚v{‚|u‹„„“““ultVTL›˘›“““uztttsslef]c||ddc\[[|‚z„Š}ś››u{{Ś”•ldd…‹’…‹‹„Š„||Ś—Ł››”Şł·|„…tllrfktts™š¤””‹lek{||{||„„‹…’tzl„„{{t¦§¨“““|„…{u{|„…Š}lriedkllk}Š{{¦§¨|„…|„…„„“““…‹‹Ś”•|‚z””‹‹’Š›˘›‹’Š|„……‹‹„Š„…‹‹”››”“›{{¦§¨”“›™š¤||š””bVU¦§¨Şł·redtllŁśĄ‹’Š’ŚŚ‹„„ĂÄƨ©´¦§¨Ś”•‹„‹“““’ŚŚ‘Ś…‚|uš””dc\ŠŠ}‚|u””‹””‹‚v‚›˘›‰‘~]bZuztkd\lek‰‘~\UZ‹‹„Ś”•Şł·›”›””‹|„…bVZultf]cf]c}Š}}Š‹’Š™š¤fkk{{{{mttUTStzl‹„‹Ś‹“Š}‹„‹›”›tllultult”š”Ł››‹…’{{tultdc\Ś‹“u{{uztekd[[Tlridc\|‚z„Š„lrisleddctzldc\VZ[lriUTS\[[ddcVZT|„…‹„„fkk}bVU™š¤tt{|tsl‹„„lld{zmlri‚ulldf]c{ttUTS|‚z›˘›JHF*)(lksuztuzt””‹”››zll‚u‚u{tt{ttŁ››uzt””‹šŤŚŠ}””‹’ŚŚ{u{|bVU‚|uŠ}tll}{||Şł·‹„‹Ś”•¦§¨uzt‹‹„›˘›”“›ś¤¦{u{ŁśĄlek‚v‚Ś‹“tts{||’}™‚v{{u{{||{{t{u{SKJlld{{t|„…{u{””‹„„Š…‹šult{u{lld{||{||{tt„Š„}j]\Š}s_qzll}‹„„‹„‹tsl‚|ud\\zllcbVtslŚ”•mtt„Š„tsl\[[tll\UZ{zmuzt›˘›”š”u{{Şł·u{{|„…„„Š{{t}“Ś”ś››š””¦§¨ttslekŠ}uzt{{tult‘}{tt{{Š~‹‹‹„‹’Š””‹„„š””ttstt{{{uzt…‹‹”“›‹‹‹™š¤™š¤…„’tt{ldd„„™š¤|‚zu{{Ś”•Şł·‹‹„|‚z„Š„|„…”š”›˘›tsl„„…‹‹tt{tt{ddcddcSKJ{tttll“Ś”™š¤”“›‚v{…‹‹}‹„„ŁśĄ¦§¨ŁśĄ“Ś”¨©´“Ś”¨©´¦§¨µ¶·||™š¤ztl“Ś”””‹mw‹‹„{||uztfkkMRKlrilrillk”››ddc…‹‹ŠŠ}{||edk{{f]cleku{{”››u{{mtt{{tslŚ”•|‹’Šmtt”››™š¤„„Š|‚z{||Ś”•™š¤”“›¦§¨ś››tsl|dc\Ś”•{u{edk|JHF„Š„VTLVTLŚ”•iq]VTLu{{]bZ„Š„lekllkuzt\UZ‹„‹ttsJHF]bZ‚v‚JHF]cd]bZSKJ‹„„›”›‚ut}Ś‹“‚ub[UlldcbVzll|„…Š}|„…{{t|‚zmttmttšŤŚJHF*)(ldd”š”{zm‰v‚u{zmŠŠ}|{{t‚ut‰|vŚ‹“””‹¤¤ť‚ut‹‹‹‚v{{||tts‘Ś…‚|u’ŚŚ¦§¨™š¤{tttts““““Ś”{zm“Ś”“Ś”}‹’ŠŚ‹“{u{tll‘…„tt{ztl|„…{||}Š‚v‚{||llktlllldlddlri‹’ŠŽŁŚ‹“}{{f]cult||}Ś”•mtt’ŚŚ‹‹„f]c||ultrfkulttll“Ś”Š~‹ŠŠ}{tt{||{ttddctzluzt‹’ŠŚ”•‹‹‹Ł››š””ttsuzt|‹’Š|edkttsŚ”•›˘›{||Ś”•ś››ŚŚš˛¬µ””‹¦§¨{{›”›{{tmtt””‹||’ŚŚ{tt”“›¦§¨¦§¨Š}””‹Ś”•|tts}d\\lekttstt{‹‹‹|„…„„Š}Š›”›‹„„“Ś”}™š¤ŁśĄ‹„‹’ŚŚ„„”“›Ś”•tts{tt¤¤ť™š¤”››“““ekdŚ‹“Š}|b[Uzll„„Š{tt¦§¨ś››ś¤¦Ś”•}lksult{u{“Ś”†~‘™š¤™š¤˛¬µ}™š¤tll“““Ś‹“¨©´‚v{ŁśĄ’ŚŚ“Ś”‚v{tllŁ››‹’Š{{|‚z|‚z„Š„Ś”•‹‹„””‹‹‹„lld„„Š…„’f]c}Š„„Š”“›{{…‹‹]cduzt™š¤Şł·›˘›ś¤¦”››¦§¨„Š„‹’Š}Ł››{{ś¤¦…‹’„Š„””‹‹’Š‘}“Ś”‚v{[[Tuzt{||{{tVTLcbVllk|„…tzl[[TuztUTSuzt\UZVZ[‹„‹Ś”•ekdtll\[[uztUMRlri[[Ttts}’ŚŚŁśĄ|‚z„„‘Ś…kk]ekd{zm„„‹’Š||‚ztzl[[Tedk‚v{:973+*|‚ztts‹‹„lld{zm‘}||ztl”š”„Š„lddś¤¦””‹¤¤ť‚|utsl||‹„„Ś‹“‹‹„‹‹„¦§¨‹„‹”“›Ś”•’…‹™š¤››”‹‹„¦§¨ŁśĄ…‹’¦§¨™š¤“Ś”{tt”›››”›ŚŚšµ¶·™š¤··Ä…‹’‹‹‹{{t“““‹‹‹{u{||lrif]c{{\UZ\[b™š¤f]c{{Ś‹“‹‹‹…‹‹™š¤…‹‹Š}“Ś”||[TT}\UZ{u{sle’‘~””‹”“›“Ś”‚ut|‚z|‹’Š‹’ŠlriuztSKJ{||ult“Ś”ś››‹„„lksMSS|„…„„ŠŚ”•{{”š”‹‹‹}‹‹„|‚zlks¦§¨’ŚŚ{||‹„‹||‹„‹„Š}‹„‹µ¶·ś›››”›|‹„„›”›uzt}Š{ttttsŚ”•‹„„„Š„„„ŠŚ‹“Ś‹“||ult}„vŚ¦§¨„„uzt””‹’…‹„„Şł·tts…‹‹Ś‹““Ś”lddŚ”•lddtsl›˘›‹…’Ł››¦§¨™š¤µ¶·lksŚ‹“Š}“““ultlks™š¤ult‹‹‹™š¤„„ŠlddlddŠ~‹‹„‹||™š¤Š}…‹’Ś”•”››”“›ultś¤¦tllŠ}“““””‹¤¤ť™š¤|‚zlridc\“““|‚zekd„Š„lri|„…tslŚ”•f]c™š¤||{{tŚ”•„„„„{{…‹‹uzt“Ś”„„Šµ¶·¦§¨|‚z„„|lldllduztkk]“““]bZ””‹{tt„„Šllk[[T|„…mttddc‹’Š„„‹’ŠVTL{{”››}Ś‹“f]cUTSlkslkslri{||Ś”•lksttsult››”ultlks‹„„Ł››””‹ŠŠ}|‹‹„{{tdc\]bZ|‚z[[T[[T¦§¨LKR*)({{tll””‹ś››{zm|‚z‘Ś…{{t””‹””‹Ł››™…””‹‘}zŠ}|””‹{tttt{Ś‹“uzt“Ś”Ł››}“Ś”{||}Ś‹“Š}|””‹“Ś”ś››Ś‹“ddc„„“““”“›’ŚŚ…‹‹{u{Ś”•™š¤{{¨©´Ś”•{||ttslek‹„„u{{ttslek\UZlddVZ[ŁśĄ}lkstt{{||tll’ŚŚttsrfkŠ}|‰v|lddrg]‚v{„„Š“““„„Š‘Ś…Ś”•‚utldd‹’Šlldekdtzlekd„Š„tlllldŠ~‹{{Ś‹““““}‡’\[[f]cŚŚš|‚z{||’ŚŚllk‹‹„llk„„”››‹‹‹{tt’ŚŚšŤŚ˛««››”“““ŁśĄ‹…’‹‹„|„…š””lld„„tts{u{‹„‹‹„„{{“Ś”{{™š¤…‹‹Ś”•„„ddc¨©´ttsult™š¤ult{{¦§¨””‹Ś”•|‚z‹‹„{{™š¤Š}d\\„„Š{tt‚v{}Štt{tll”“›ś¤¦…‹‹“Ś”›”›™š¤“Ś”f]c‚ut{{“Ś”\UZ‹„‹rfk™š¤ult|||“““‘Ś…uzt¦§¨llkŠ}‹„‹›”›‹„‹„„sle{u{”“›‹’Šś››d\\]bZtslŚ”•lrillkmtt{ttmtt‹„‹d\\|||„…Ś”•”››™š¤…‹‹„„Š…„’“Ś”“Ś”¨©´‚v{…‹‹ultŚ‹“|„…‹’Štsltzl{|||lriuztlks“Ś”””‹ztl|‘Ś…|‚z{{t{{t[TTlldekd}d\\{u{d\\[TTJHFVZTuzt{||ekdf]c{{lek||‹„‹…‹‹lrizllztl“““tzl|‚z{{t„Š„]bZ‹’Š]cdu{{˛˛¬:97*)(kk][TT‚u|uzt‘Ś…Š}””‹˛˛¬””‹‘}Š}””‹sleŠ}|””‹¦§¨›”›™š¤ś¤¦‘Ś…“Ś”“Ś”ult„„¦§¨¦§¨„„Š}|››”˛««™š¤‹‹‹„„“Ś”ŁśĄś››“““ś››””‹„„Š“Ś””››Ł››{||‹‹„‹’ŠŚ‹“edk|‚zŠ}{{d\\]cd‹’Š|‚zŚ‹“}Š”››Ł››™š¤}›”›Š~‹ylemttkd\ddcf]c{u{sreŠ}ttskd\“Ś”‹’Šzlldc\llktslttsd\\|„…ultu{{tts‹’Šlrilksddc”“›lksddc||lksŠ}¦§¨Š}|„…””‹|‚z{{…‹‹Ś‹“››”{tt‹‹‹Ś‹“‹„„rfk{zmtsl{{tŚ”•“““‹„‹””‹ś››‚v‚{{¨©´™š¤}‹„‹tts|„„…‹‹”“›‹„‹{{t¦§¨|™š¤ttsŚ”•Ś‹“„„ŠŁśĄ”š”¦§¨|‹„„{{t“Ś”‘Ś…™š¤‰v|‹‹„‹‹„¦§¨Š}}ŠŚ‹“’}™„„Š„„Š”“›}‹…š\[bŁť˛}ddc”š”{{ttllf]c‚ulritsl›”›Š}|{zm||}„Š}]cd„„Šu{{u{{[TT{{mtt‚v{”“›|„…ztl…‹‹{{tll{u{¦§¨ś¤¦…‹’…‹‹{{|‚z‹‹‹™š¤…‹’”“›”“›Ś‹“š””|‚z‹’Š|‚z””‹lrikk]|‚z”š”Š}tzl¤¤ť“““tll„„llk“Ś”“Ś”{ttŚ‹“|\[[kk]||tllVZT‹‹‹|„…u{{tt{|‚z‹„‹]bZ}[TTtt{lri{||ultlld|‚zllkekd[TT{||mtttzltll{||˛««F=C7-2‚ut‹‹‹„Š„ztl||‹„‹{zmsrekd\{{t¤¤ťsle›˘›ult””‹‹‹„‘…„‹„‹„„z‚l’ŚŚ‚utš””{u{‹„‹Š}}mttŁ››Š}™š¤{u{‹’ŠŚ‹“‹…’Ś”•“Ś”“Ś”™š¤uztŚ‹“›”›…‹’‹’Š’ŚŚ|„…„Š„lksmttŚŚš{ttu{{{{tuztŚ”•dc\tt{ult{||„„›˘›…„’||tll‹„„[TT{{tddc‚ut{||„Š„\[[Ś‹“{||Ś‹“‹‹„ekdlld|{{t{||tts\[blks|™š¤‹‹„lrilks}‡’Ś”•™š¤‹‹„›”›llklddllk„„Šllkf]c\[[“Ś”””‹›”›‘Ś…ś››tts‹„‹Ś‹“‚|u’ŚŚ„„lldu{{Ł››™š¤ś¤¦…‹‹”“››”›edk‹…’“Ś”™š¤Š}„„„„Š‹…š‹…’””‹Š}‘Ś…‚ut‹„‹‘}‚|u‹’Š{||Š}|tts‹’Šsre„„Š}Š}ŁśĄŁ››Ś‹“‹’Š„Š}™š¤›”›“Ś”‹u…ś››“Ś”Š}{{“Ś”“Ś”‹‹‹„„Šf]c{u{‹„„zllldd‹’ŠŁ››ztl{ttttslksedkFD;kd\””‹z‚l[TTŚ”•“Ś”™š¤}‡’UMR\UZ…‹’|„…„„Šlks…‹šedk…‹‹UTS…„’Ś‹“™š¤u{{u{{™š¤|‚zyl„¦§¨{{tŠ}‹‹‹{{tllkd\\||{{|„…ult{||]bZ{{t”››””‹lddVTL¦§¨„Š„{||”“›||“““{{t|„…mttf]cuztultlks‹„‹llktt{{u{edkrfktll}lri{{{tt‚|u„Š}ztl[[TztlŠ~‹|„…{{tlldlld˛««JHF*)(tsld\\|‚z’ŚŚ„„ztl‚wl[[TŠŠ}‚v{’ŚŚu{{‘Ś…’ŚŚ}‹‹„‘…„{tt}„Š„‹’Š“~zll‹‹‹Ł››„Š}‰‘~„„Š‹‹„„Š„“Ś”™š¤ttstts{u{‹‹‹|‚z¦§¨Ś”•‹’Š™š¤{||™š¤||tll‹’Šlritt{\[b|„…}Šś¤¦ekdldd|„…|‹„„ŚŚšllk{{t|‚z|‚ztsl}‹„‹{{ult…‹‹{{tcbV{ttŠ}“Ś”||cbV‚|u{||”š”›˘›‹’Š„„ŠVTL\UZŚ‹“Ś”•Ś”•|ś¤¦{{Ś‹“„„”š”‹’Š“““|„…||‚|uyle|„…{tt„Š„|„„„„‘…„”“›tllŚ‹“llktts|‚ztts‹‹„„„Š”“›||Š~‹Ś”•„Š„|„…f]c{{Ś‹““Ś”Š~‹|¨©´lld{u{{{›”›“Ś”lri{{’…‹Ś”•‘…„ŁśĄ‹„‹{{Ś”•›”›™š¤‹‹‹ztl‹„„¦§¨‹‹„„„””‹“““Š}‹„‹tlltsl‹‹‹}Šf]c{u{tts{||‹‹„Ś‹“[[T˘Ź“d\\zllj]\‹„‹‚v‚“Ś”‘Ś…››”SKJ‚v{sre\[[ś››””‹Š}|„……‹‹{{mtt„„Šf]cŠ}tts}tzlVZT}Š\[[ultdc\lri|„…{{tu{{ś¤¦ś¤¦””‹…‹‹‹‹‹‹„„””‹„„ult}ddc”“›Š}|VZTVTLuztmttJHF|‚z|‚z”››lld›˘›„Š}›˘›‹‹‹lld‹‹‹}tts|„…ultf]cddc[TTtslf]c”“›‹„‹{{trfkŚ‹“>EC{{tVTLlldllk{ttfkktsl|‚z”š”]bZ›˘›Ł››:97:97Š}||››”tll‚|u¦§¨{{t|„…ztl{{t¦§¨‚|uŠ}“Ś”‚uŠ}¦§¨|„…ult””‹dc\sle“Ś”‹„‹‹…’“Ś”‘…„rfk|‚v{“Ś”„„¦§¨{{t‹„‹‹‹‹“““¨©´„„|„…{||‚v‚tt{¦§¨{{t]cd…‹’tt{uzt…„’{ttś¤¦ddclri]bZrfk“Ś”|„…{{tŚ‹“|„…u{{ultlriredu{{|r]g{{t}ldd||‹„„lddredred›˘›¦§¨ś¤¦„Š„›˘›mttUMRu{{{tt{||srett{}Ś”•{{Şł·””‹ŁśĄ›˘›||””‹rfk{||{||ttslri…‹‹‹‹„ś››”“›{||¦§¨‹‹‹ŠŠ}‹‹‹“““›˘›‹„„”“›Ś”•{tt…‹‹‹‹‹”“›Š~‹f]c‚v‚|ś¤¦\[[‚v‚…‹‹Ś”•tt{„„Š“Ś”llk“Ś”‚|u|‚zś››„„Š‹‹„|„…–˘‹‹…’”››||lld”š”tt{„„‹‹„ztfŠ}¨©´’…‹”“›„Š„‹’Š{||dc\f]c‹„‹}””‹Š}|””‹Š}kd\‹’ŠlekVZTlrisleredzlltllztlsreVTL{{t‹‹„Ł››‹…š‹„‹‹‹‹‚v‚{{lks|‚z’ŚŚ„Š„uztsle…‹‹\[b]cd}Š~‹„„uztmtt”››Ś”•Ś”•ttsmttddc{|||‚z{||sleJHF|\[[‹’Š[TTdc\„Š„„Š}lri”“›|‚z\[[›˘›„„]cd‹’Š„Š„rg]š””ekdtsl||ddcuzttt{|Ś‹“„„Šlld‰|vdc\u{{SKJdc\tslVTLlld[TTsre||lriaWMSKJ|‚zŁ››D;9*)(„„“Ś”Š}tsl‚u’ŚŚ››”‘Ś…’ŚŚ””‹“Ś”Š}Ł››¦§¨Ł››{{t¦§¨|‹’Š“““lek‹’ŠaWMŞł·‹„‹›”›…‹‹‚ut‹’ŠŁ››Ś”•|„…””‹ŠŠ}Ł››Ś‹“ś››˛¬µµ¶·Ś”•›”›}Ś”•|[[T’ŚŚ[[T]bZmttd\\„„{zm’…‹„Š„tsl„„ŠŚ‹“{{t’ŚŚ||„Š„}š””lriztlŠ}{ttldd„Š}{u{Ś‹“”“›‹„„‹„‹Š}ult…‹‹|„…„Š„|‚z‹‹„‹’Š|‚z””‹„Š„ekd””‹u{{f]cztl„„…‹š”››¦§¨tts„„„Š}ztfddc‹„„{{tsre‹„‹„Š„||{tt{||„„ŠŚ”•”š”¦§¨…‹‹›˘›””‹‹‹‹lksult™š¤Ś‹“„„tt{llk{{sle{{Ś‹“‹‹‹|„…¦§¨Ś‹“…‹‹{{t‹„‹ultŠ}‰vś¤¦„„Š’ŚŚ…‹‹llk„„ŠtllcbVŚ‹“’…‹|‚z|ztltt{‹„„¦§¨{||mwsre„„‹’Šsleult{tt…‹‹‹„„ŠŠ}„„‚uzll‚utylelritllŁśĄ‹„‹””‹tlltzlkd\b[UddcŠ}lek™š¤›”›edk›”›‚ut||„Š„|„…u{{‹’Š|‚zllk{{|Ś”•tslŚ”•››”‹‹„™š¤u{{}lld}UTS””‹|‚z[[Tultuzt¦§¨tt{mtt{{t{{tlld]bZbVUultultUMRŠ}{||‘Ś…‹’Šb[Uztlf]c{{…‹‹ultult””‹|„…{||{{{{kd\„„Štt{fkkf]cd\\‹‹‹‚utzll{{tlrilridc\\[[ekduztš””:97*)(tzlsre‹‹„}{tttts””‹¤¤ťŁ››“““’ŚŚ‘…„“Ś”˛««|‘Ś…„„{tttts||‚z«˛«Ś”•{tt¨©´ŁśĄ¤¤ť…‹‹‘Ś…||¦§¨“““›”›¦§¨›”›™š¤‹‹‹¤¤ťś››‹’ŠddclddŚ‹“|„…]bZ\[b||tt{‹’Š‚v‚}b[U‹‹„|‚z‹’ŠŚ‹“|‹‹‹‹„„{||u{{ldd›”›‹‹‹{u{ŠŠ}kd\zllkd\lek”“›‚v{kd\edkŠ}{{“““|„…Ł››tts„„Š„Š„[[T{{‹’Šmttdc\]cdSKJlek…‹‹lkskk]‹‹„{||“““tsllldllkslelld[[T{tt}ŁśĄ‹„‹››”’ŚŚ|„…ŁśĄ””‹ddc|‚zldd}Ś”•‚v{¦§¨‹‹‹Ś‹“’ŚŚult“Ś”ś¤¦ŚŚš“Ś”uztttsŚ”•ldd…„’mw„„{tt“Ś”“““‹‹‹“Ś”’ŚŚultŚ‹“”“›”“›‚v{„„{||™š¤”››|‹„‹tllš””Ś‹“ś››tsl{{tŚ”•””‹{||\UZ{{‹‹„µ¶·‹‹‹ś¤¦|{tt‹‹„”š”‹„‹ŁśĄ’ŚŚ‘Ś…SKJttsjcVldd]bZ|‹„‹„„™š¤Š}|lekf]c‹„‹dc\“““„Š„‹’Šttsś››„Š„“““¨©´„„Š{{Š}lri…‹‹{{}yl„edkbVZj]\›”›[[T‚|uekdd\\{{{ttddcttsf]c[[Tek]sleult“““lksFD;zllztl||‹„‹tt{UMRfkkultu{{‚|uJHF„„red“Ś”}Š}{{{||\UZztl{||||‚z”š”]bZkk]dc\\[[UTS]bZ¦§¨:97*)({{t{ttlddred’ŚŚ}¤¤ť{zm„Š}˛˛¬š…Ž‹’Šztfztl¦§¨|“Ś”„Š„ŁśĄµ¶·“““¦§¨¦§¨“Ś”…‹‹”š”¦§¨ŁśĄ›˘›}¨©´’ŚŚ‹„„””‹{||””‹‹‹‹„Š„{tt||{||››”ddc{{‹‹„||lek”“›Ś”•”“›tlld\\lld‹’Šś¤¦}“Ś”‹„‹sredc\Ś”•“Ś”„Š„u{{{||sleSKJ‹„‹|tlltllzll‹„„r]g“Ś”mtt„„Š“““¤¤ťŚ”•{||„„tsl}Šś¤¦|‚z{{tuztd\\||”››ddc‹’Š–˘‹|ztllritts‹‹‹ztl„„|‚z|||{u{‚ut’ŚŚ‹„„„Š„{{‹’Šlld‹„‹{{t}““““Ś”Š}|lek“Ś””“›ult}™š¤“Ś”tt{tts”š””››ś››{{UTSlksttslriś››‹‹‹“Ś”tts{u{||›˘›}‹„‹„„Š‚|uek]™š¤‚|u˛««{||”“›tsl“““Ś”•{{t””‹||{||tts|‚z‘Ś…“““„„š””{{tŁśĄ‹‹„”“›\UZŁ››ddcztl‹’Šdc\VTLVTLek]tllŚ”•Şł·{ttyfltt{\[[}Š[TTtt{leku{{VTL]cduzt…‹‹„„Š„„Šu{{lksd\\|‚z››”f]c¦§¨lri{u{j]\edkttsllk]bZllk„„{{\[[SKJek]tll‰|v””‹VZT“Ś”[TT{||dc\ldd[[T‚v‚lksf]c}ttsf]cJHF]cd{{lek“Ś”‹‹„tt{Ś”•fkk}‚v{|‚zsle\[b‰‘~lrisre]bZ[[TFD;||“Ś”:97:97rfkkd\‹‹„{ttŁśĄ””‹‹’Š›˘›{{tŁ››|””‹›˘›‹„„˛¬µ‹’Š™š¤ŁśĄš””‹‹„¤¤ť”“›˛¬µ“““ś››™š¤””‹”š”››”|„…µ¶·‹’Š¦§¨¦§¨ś¤¦›”›ś››„„š””‹‹‹‹„‹¦§¨|‚zult}‹‹‹”š”¤¤ť¦§¨{{lektts{{tllkŚ”•{u{‹‹‹‹‹„…‹‹¤¤ť™š¤‹‹‹{{”“›‹„‹{ttb[UbVZtsl|ultŁ››ztf”››‚v{ś››{u{llkztl„Š„„„UTS‹‹„{{sre™š¤|mtt‹„„||”š”…‹‹mttŠ}‹„„‹„„ek]Š}{{’ŚŚ\[[lrisle{u{}rfkš””}‹’ŠŁśĄ‹‹„lri‹„‹||„…|„…™š¤””‹““““Ś”}Š™š¤‹‹‹“““tslultmtt…‹‹„Š„||…‹‹llk‚|u}{u{‹„‹Š}”“›ttsllkŠ}¦§¨{||š””dc\{||ult|‚z{{ttslultš””||Ł›››˘›uzt‹‹„›˘›Ś”•„„ŠŁśĄ¬¶Ă“Ś”ŁśĄ›”›‹’Š˛¬µ|{||{||‹‹„Ś‹“‘Ś…lld‹’Š‰vŠ}‹‹‹ŠŠ}Ś”•„„ultbVUf]cldd}edk[[Tlriult›”›”››™š¤‹„„ultlri”“›ek]{{tdkVmtt}Šztlult’ŚŚ„„Štt{llkUMRLKR}“Ś”{tttts{{\[[ttsttsŠ}|kk]llk|„…||ŁśĄuztlek™š¤Š}{{f]cJHF‹‹‹{||VTLlri}|„…Ś”•mttllk\[b{u{ultllkttssre{{trg]|‚zuztMRK\[[dc\¦§¨:97*)(dc\ztl’ŚŚ‹‹„„Š}””‹‹‹„||››”¤¤ť{u{‚uŠ}|’ŚŚ¨©´ś¤¦{||¦§¨”››‹’Š«˛«µ¶·ś¤¦ś¤¦”“›“Ś”ś››„„Š¦§¨„„Š}™š¤“““”››‹‹‹‹’Š‹‹‹‚u‹’Š¦§¨ŁśĄ˛¬µ”››uzt‹‹‹˛««{{tś¤¦‹’ŠŚ”•{{{u{SKJ[TT|‚z“Ś”kd\‹‹„„Š„‹„„u{{‘Ś…UTS||j]\{zmldd}rfk{{tll’ŚŚ{tt‹„‹{tt“Ś””››™š¤Ł››{||„Š„JHFtsl‚v{{{tu{{”››„Š„uzt‹„„ttsŚ”•|‚z””‹lldd\\“““¤¤ť‹‹‹‚v{|‚z„Š}‚|ullkf]cultult‚|u”š”{tt|‚z{||Ś”•ś¤¦”››Ś”•”“›„vŚ|„…yl„“““Ś”•’ŚŚ””‹ult{u{|„…{u{{||ztl‹…’‹‹„ult[TT{tt’ŚŚ‹„‹{{‹„‹[TT‹‹‹‹„‹‹‹‹tlltsl{u{tlltslred‘}’ŚŚ›”››”›{||Ś‹“¦§¨”š”ttsś¤¦¨©´…‹‹‹‹‹“““›”›“Ś”{tt‹„„|„…uzt{u{||¨©´››”‹’Š‹…’|‹‹‹|‚z“““‹‹‹“““„„“Ś”Ś‹“{tt{{[TT]bZb[UlriŚ‹“uztdc\{tt{{tredult|‚z{||{{t{zm{{t{{t“““‹’ŠVTLŚ”•‹…š\UZtts‹„‹d\\„„ś››}ddc||\UZek]SKJ{{ttt{UMRŚ‹“{{t‹„‹‹„‹„„Šd\\VZTUMRlri{ttddc…‹‹||„Š}‹…’d\\tsltts[TT|„…„Š„Š}|u{{z‚llriŠ}ddcUTS[TTlektslFD;,55‹‹‹››”Š}yleŠ}‹‹„’ŚŚ‚ut””‹||‹‹„Š}{{|}‹‹„„„Š…‹‹›˘›¤¤ť¤¤ť‹’ŠŠ~‹¤¤ť‹…’‘Ś…ŽŁ|‹„‹sre›”›|‚zś››„„‚|ulri|„…‹‹„“Ś”tll‹„‹™š¤…‹’u{{|‚z‹„‹‹‹‹…‹’ŠŠ}ult‰|v{||dc\ŁśĄfkkleklks’ŚŚ†~‘Ł››|ś››Ś”•{||””‹j]\tllŠ~‹{u{‚ut‚ut“Ś”tts{u{}„„Š{||”“›‹‹„uztuztllklld\UZ„Š„Ś”•VTL{{|‚z|„…›˘›ś¤¦lrikk]‹„„‹„„{{t™š¤}tllrr]””‹{{ttt{lddf]c’…‹‚v{‹‹‹¦§¨lri™š¤‹‹‹”››¦§¨Ś”•Ś‹“Ś‹“¦§¨Łť˛|”“›Š~‹”››{{…„’|„…]bZŠ}Š~‹“““fkkŠ}|llkb[U‘…„{u{ŁśĄ||d\\‹’Š||’…‹tzldc\cbV{{dc\””‹‘Ś…j]\ddc‹…’Š}ś››Ś”•ś§˛|‚z”“›u{{tslŠŠ}¦§¨‹„‹{||…‹‹™š¤‹’ŠleklekŠ}‹„„zll|‚z‹„‹‰v˛˛¬…‹’sle…‹‹“Ś”}‚v{VZ[ultultbVZ‘…„}Š|tll…‹‹SKJVZ[uztUUYUTS|„…‹‹„ddctslllkŚ‹“™š¤‹„‹‹’Š¦§¨‹‹„{{}ŠŚ‹“{tt‹„‹lekŚ‹““Ś”u{{lri{{{{tztltll[TT™š¤{{{tt‚ut}‹„‹ddcUUYllkś››lri‹„„tt{ztl‹„‹VTL|{{tldd“Ś”tslmtt‹‹„„„lriztl‹’ŠtslUTSJHF’…‹:97*)(Ś‹“„Š}“““{||””‹Šut„Š}tll¦§¨{{t‹‹„››””š”””‹“““ś¤¦¦§¨ztlµ¶·‹‹„µ¶·””‹Ś‹“”š”ult“““’ŚŚuzt™š¤‹‹‹ŁśĄ„„{{t‹‹‹›˘›|„…‹‹‹{||‚|u|}|‚zŚ”•lks„„{tt‹‹‹…‹‹Ś‹“…‹’|tslś¤¦{ttŚ”•›”›¦§¨“Ś”‹„„||‹’Š‚v{””‹ddc‚utJHF}tts„„ŠŠ}bVU{u{{{t{u{‹„‹{{…„’slerfk{{|„…{{tult\[[]cd[[TmttlriVTLlri|„…ś››ztl||lld””‹|{ttd\\{{””‹Š}{{tllŠ~‹’…‹“Ś”™š¤||›”›„Š}‹‹‹’ŚŚŁśĄ„„‹‹„™š¤}…‹’‹„„ś¤¦lri{tt{||„„llkzll|„…sle‹’Šllk{u{‹„„sletll‚|u||Š}lkstzl“Ś”||”“›„Š„‚uŚ‹“lld’ŚŚ””‹‰|v“~‹„‹™š¤™š¤“““„„{tt{u{\[[„Š}ś››“““{||uzt[[Trfk‹‹„d\\{u{š…ŽŚ‹“¦§¨ś››„„“““tsl|‚z‚|u„„ult{u{UUY\[[ldd{{t{u{‚utult{{t}…‹‹Ś”•ult‹’Šj]\lek„„Štt{ztllriddcŚ”•‹„„{ttb[ULKRVZ[lks…‹šf]cttslddult‹’Š||{u{ult‚ut{{tbVU{||VZT\[[Ś‹“{{t’ŚŚtll¦§¨‹‹„VZ[mtt{ttmtt{{tf]cSKJ{u{|„„Š\UZztldc\SKJ‚v{tsl{{tuztuzt|„…\[[VZTUTS¤¤ť:97*)(||kd\›˘›{{t››”¤¤ť‹‹‹›”›ztl‘Ś…¤¤ť™‹†||srettsŁ››‹‹‹¦§¨”š”’ŚŚtslś¤¦Şł·µ¶·¦§¨™š¤‹‹‹”š”‹„‹”“›”“›””‹¦§¨Şł·¦§¨¦§¨tt{Š}|‚z”“›{u{ŁśĄUTSztl|‚z{||…‹‹„„‹’Štts„„{||ś¤¦ekd‹„„“““™š¤bVZekd‚u›”›‚|uVTL\UZ{||“Ś”f]cŚŚšult{u{‹‹„“Ś”Š}|„…lek‚v{{u{›”›leklksf]clldUMR{{cbV…‹‹””‹‹„‹ddcSKJuztddc‚|u‹‹„“Ś”sleś››{u{››”Š}„„„Š„kd\ult‹„‹Ś”•Š}”“››˘›™š¤“Ś”¦§¨¦§¨ś¤¦„„Š«˛«Ł››™š¤‹„„„„“““}‹’Š‹„‹“Ś”ŁśĄŚ”•{{t{{‹„‹¨©´{ttdc\‹‹„…„’zllztl‚ut||‚z››”‹„‹‚v{{tt„Š„tslŚ‹“|‘…„kd\}’ŚŚj]\Š~‹Ł››‹’Š‘Ś…ś››”“›…‹‹ś¤¦‹’Š”“›{{{tttts[TT”š”mttu{{kk]lek‚u””‹„„–˘‹‘…„…‹‹{ttuztlekedklrimttd\\\[[||{{ult‚wl{u{Ś”•Ś”•‹’ŠUTSedkd\\|UUYtllf]ctts‹„‹ŠŠ}|‚z||UTS\[[llkś¤¦UMRrededk{{‹‹„|lek|„…sre||‚utddclrimtttt{{u{|””‹lri\[b\[b[[Tlri{||lldf]c‹…’™š¤¨©´mtt›”›tll„Š„lekdc\‚u‹‹‹‚uttsmtt‚v{[[TekdŁśĄ:97*)(ztl‚u›˘›tsl››”‹’Š‹‹‹”››„Š}Ł›››˘›””‹”“›||¸Áą¨©´Ł››{ttŁ››|‹‹„„„Š“““™š¤““““Ś”Ś”•¨©´Ś‹“”“›|{{›˘›ŠŠ}tsl”››}‹‹‹‹„„“Ś”{tt|‚zUTS]cdlritllŚŚš‹„‹|„…lkslldtsl…„’mttŚ”•Ś‹“”“›Ś”•|‚|uult””‹‚wltslrfk}j]\\[[uztleksresre{||{u{‹‹‹Ł››’…‹“““||‹‹‹“Ś”{||d\\}{tttt{|‚z‚|ulks”“›”››“““››”Š}››”˛¬µ›˘››”›‚|u‹…’lld„Š„Š}Şł·¨©´“Ś”š””‹„‹|‚z™š¤’…‹|„…Ś‹“„„tllu{{’…‹””‹|||¦§¨ś››u{{”“›”“›…‹‹„„Š|sle}ŁśĄ{u{‹‹„Š}ś››ldd””‹Ś‹“›”›ś››››”™š¤…‹‹“““¦§¨‹‹„ŁśĄ›˘›‚v{‚|u“Ś”‹„„‹„‹mwtll{{tŠ}Š}ttsfkklri{{t’ŚŚ“Ś”{||‹’Š‹’Š|‚z‹„„„„tts{u{b[U{||i\V‰v¤¤ťllkŠ}‹‹‹tt{‹‹‹lriSKJb[U]bZ{u{llk{tt‹„‹dc\uztfkk„Š„ddc{u{||””‹Š}tzl{zmtsl{ttztllldllktt{„„Š||lri{u{slef]c|„…{{t›”›MRK…„’sretzlsretslUUYUTSŠ~‹ttsldd¦§¨{||{u{\[b[TTf]ctslcbVtlltt{„„b[UUUY{{kd\ultJHFleklld{ttfkk}UTSJHFVTL|‚zŠ}JHF*)(„Š}‹‹„‹’Š‚ut„Š„›”›|‚z“““¦§¨‘…„¤¤ť||‘}‹‹‹Ł››”“›””‹‹’Š››”{ttµ¶·Ł››Š}{||‚v{ś¤¦”“›¨©´Ś”•‹‹‹||›˘›uzt|‚zttsŚ”•|„…lri‚|u”š”‹‹‹edk]cd]cdf]ctsl{u{|‚z{{tt{ult‹’Šś¤¦‹’Š‹’ŠŚ‹“‹„„‹„„”“›››”’ŚŚ|„Š„bVUlriŚ‹“f]cJHFbVZlek|ult‚v‚sle„„zll‹„„“““‹„„tt{}Šfkk„Š„j]\}‹„‹{ttultŚ”•‹‹„{zm{|||‹„„|¦§¨„„Š}|’…‹Š~‹‚n|‚z””‹™š¤‹„„…‹‹tll’ŚŚ””‹{u{‹„„…‹‹“Ś”‹‹„Ś‹“{{t|‚zś››Ś‹“ddctll„Š„¨©´“Ś”Ś”•ś››’…‹”š”ztl{{|‚z’ŚŚ‹’Š‹‹„|Š}‹…’Ś”•Š}Ś‹“Š}¤¤ť’…‹’ŚŚ‹„‹Š}{||‹„‹||||||Š~‹ult…‹‹‹‹‹zll‹‹‹„Š„{||llkkd\lekŁ››Š}sle‹„‹„„{tt”š”‹’Š‹„„‚|ullkllkzll””‹Š~‹[[Ttlltt{[TT\[[ddcSKJ‚utredu{{tt{‹„„|‚z‹’Š|‚zlridc\tt{‹‹‹„Š„Ś”•””‹lrif]c{u{{||{u{Ś‹“lkslektllylezlltsl„„ŠmttsleultJHF{{ek]lld…‹‹zlllldekdztl‹’Š‹‹‹‹‹„|‚zŚ”•]cd|„…ekd’ŚŚś¤¦UTSultJHFVTLkd\Ś‹“‚v{sle|tt{tll{{ttts}lek{{tlks]bZ¤¤ťF=C*)(lld|‚z‹’Š‹‹„Ł››“Ś”ŁśĄš””µ¶·š””””‹’ŚŚ¦§¨‘…„¦§¨|„…tsl””‹””‹’ŚŚ‰vŁ››tllŚ‹“Š~‹rfk„„Š’ŚŚ{{tts{||”“›ttstll||„„”š”Ś‹“‹‹„sre‹„‹mttu{{fkk|„…uzt{ttuztmtt}{||‹„‹|„…|‚z‹’ŠŚ‹“{||uzt||‘…„š””tts“Ś”}tt{f]cJHFfkk{||ddc{ttš””}ult‹„‹¨©´‘Ś…ult“Ś”|‚zddcsle„„„„Š„„…‹’Š}„„ŠlrillkŚ”•”››|Ł››’…‹Ł››‹’Š›”›sle||tll|‹’Š“Ś”{{||‹„‹šŤŚlrilks“““¦§¨“Ś”‚|u{||…‹’„„||{u{tll‹„‹|‚ztt{”š”¨©´„„Ś‹“¦§¨š””Ś”•“Ś”ś››‚v‚””‹[[T‚|uš””™š¤‹‹‹™š¤›˘›’ŚŚ|„…ztl‚|u‚wl‹„‹‹’ŠzllsleuztŠut{u{yfdllklld‹‹‹¦§¨{||‹…’{u{cbV}„„”››¤¤ť||Ś”•‹’Š‹‹‹””‹‹‹‹’ŚŚttszllb[U‹’ŠŠ}’ŚŚtts“Ś”rg]ult“Ś”UMRrfk[TT{||ttslldllkJHFedk{zm]bZred||„Š„cbVlkslksŠ}|ultrfk…‹’ulttts|„…ult„„¦§¨››”ŚŚš[TTztlVTL{{|ult[[T‹‹„{zmfkklrilekJHFdc\tsl‰‘~Ś”•lddlldlri|{{t‹‹‹“Ś”ztlSKJ||mttiWUd\\lritzl„Š}ldd{||„„“Ś”tzl‹’Šfkk˛««LKR*)(u{{”›››˘›Ł››||‹„„“Ś””“›˛˛¬¦§¨˛««‹„„‘…„|‹‹„””‹›˘›””‹Ł››¤¤ť¦§¨“Ś”‚v{Ł››ŁśĄ‹„‹Ś‹“”››‹’Š‹„‹™š¤¦§¨””‹|‚z{|||‚z…‹‹}{||˛««‹‹‹¨©´™š¤…‹‹››”‹‹„{||‹’Šlks„„ŠlddlrilriŚ”•„Š„{{‹„„|‚|u||ztlŚ‹““““{||„„Š„„Š‚|uJHF|rfk{tt“Ś”{{kd\‹„‹lek’…‹š””lks”››f]cmtt‹‹‹bVU„„ult[TTtts]bZdc\tsl”“›››”‹„„‚v{ztlttsekd||‹„„”š”‚u‹‹„‹„‹ddc\UZsle‹„„‹‹„”š”{ttu{{‹’Štts„„Š…‹‹‘Ś…š””|‚z{tt˛««|‚z{u{„„™š¤™š¤ttsś››‹‹‹…‹‹||‹‹„™š¤‹„„\UZztl‚wl|‹‹‹„„Š¦§¨™š¤mw””‹|‚|urfkś››‘Ś…š…Ž””‹Š}|“Ś”f]cult‹‹„slešŤŚ‚u{{„„””‹}Š{{Ł››¦§¨uzt\[[„„{||››”‹…’‚ut}Š}zllztfVTL‹‹„”››lekddcŠ}‹„„lddultkd\mtt…„’š””ekd]bZ||SKJuzt\UZ„Š„„„dc\kk]{||zll‹‹‹‚v{Ś‹“‹…’ŁśĄ|„…tts{{t{{t““““Ś”UTSdc\tt{JHF]cdddcjcVlriyflu{{›˘›Ś‹“{{[[Tmtt|‚z™š¤lri“Ś”|‚zlks{{tmttVTLredcbV“Ś”lksdc\tts„„uzt‹’Š||tsl{||ddcfkk]bZ‹’Š››”JHF*)(|„…‹’Š|‚z‚|u””‹Š}|‹‹‹“““š””˛˛¬›˘›Ś”•Š~‹Š}“““””‹››”“Ś”š””sre›”›˛««›”›“Ś”¨©´ŁśĄ›”›Ł››¨©´¦§¨Ś‹“Ś”•„Š}„„Š„„Š…‹’|‚z|„…tsl„„||tt{™š¤ś¤¦¨©´‹’Š|„…u{{mttlekulttsl„Š„tts{||Ś‹“Ś‹“lldslelldultŚ‹“™š¤f]c‹’Š}fkktt{…‹‹f]c‹„‹{{tlritll|„…ldd‹’Šult“““…‹‹ultttslld}{u{{zmtllultekd›”›|’ŚŚŚ‹“ŁśĄ‘Ś…{zm„„‚|uultult‹‹„‹‹„Ł››|„…ttsddc‘Ś…’…‹{{tedkred¦§¨{{„„}…‹‹tts}¦§¨ś¤¦ŁśĄ‹‹„“Ś”|„…llkŚ‹“{{…‹‹Ł››}‹„„‹„„{||ult‹‹‹‹„„“Ś”„„››”‹„‹Şł·Łť˛š””™š¤‚|u‚|usle„Š„¤¤ťŠ}‹„„sleŁśĄyfl[TT{||‘Ś…ddc{||”››„Š„lri“Ś”¤¤ť””‹’ŚŚ{tttslŚ‹“‹‹„ś››“““lks“Ś”Ł››i\V‚|u{u{{tttll{u{‰Šˇ{{‹„‹rg]tll}‚v{ttsred“““tslztltslVZT\[[ekdu{{ek]ultbVZf]clek|ldduzt}Ś‹“rfk‹„‹¤¤ť‹‹‹lksu{{ult|‚z|„…›˘›{||lld[TTf]clri|{||]bZddcllduzt”››|„…lld‹’Šuzt}bVUtlltlltll‹‹‹‚u‰v|‚zfkktzltslllkllklek\[b|‚zVTLsle¤¤ť\[b:97]bZrr]ś››””‹ś››‚utŁśĄ˛««¦§¨˛˛¬¦§¨¦§¨«˛«¦§¨‹’Šµ¶·“Ś”ś››«˛«‘Ś…˛¬µ¨©´„„Š}Š“Ś”Ś”•‹„„ś¤¦Ś”•ś¤¦ŁśĄ“““ztl|\[[{tt|„…kd\lld{{t’…‹ultu{{tt{ultu{{lksmttedk{{||{||„„Štll|‚zf]c„„||kd\”š”tlllldlld}“““llk||{{|‚zultedkekd{u{||JHFtll”››„Š„UTSmttultuzt\UZŚ‹“Š}|‚zd\\ultŚ”•]bZ”š”d\\””‹tts{zm’ŚŚtts¤¤ťš””š””|””‹||[TT…‹‹|””‹’…‹|„„lld|||‚z|‚z{{|‚z||“““ś¤¦“Ś”™š¤“Ś”u{{dc\{u{‹„‹llk}}™š¤|›”›¦§¨šŤŚ||‚v{›”›||||||lks}””‹{tt‹„„’ŚŚ”š”‹’Š‘Ś…šŤŚ‚|uult‹‹‹ultleklek„„ŠŠ}””‹‹‹„‹‹„¦§¨Ś”•’ŚŚ||‚ut‹‹‹‚ut””‹fkk‹‹„ddcŠŠ}‚wlj]\{yfj]\f]c‚|uekdllk‚v{ultd\\i\V[TT‚v{‚v{tts‚ut™š¤ek]ldd||\[[ult{{ttllfkk|„…f]c‹„„‹„„”š”™š¤„Š„””‹uztldd{u{uztŠ}Ś”•u{{””‹|„…UTS…‹‹„Š„‹„„„„ult{{t”š”„„Š]cd“““VZ[„Š}›˘›uztJHFMRK{{t|‚zSKJ\UZlld„„Š}Š{{llduzt„„„Š„llk“““tll|JHFJHFVTLllk¦§¨\[[&&ek]{||Ś”•¤¤ťŠ}|™š¤¦§¨˛««ŁśĄ‹‹‹Ł››‹‹‹¦§¨›˘›¤¤ť””‹“““””‹‹’Š||¦§¨¨©´›”›‹„‹¨©´{{››”“““’ŚŚ‹’Š™š¤“““”š”Ś”•ldd„Š„„„|„…|‚zŠŠ}{||}|„…lriultlksmtt„Š„lriUMR{{sle{{Ś”•lriultŠ}››”bVZtslfkk}‹‹‹{u{ddc{tt]cdUTS|„…mw’ŚŚ{||d\\|dc\“Ś”llkŁśĄ{||lri||{ttu{{ultlddŠŠ}{ttUTS…‹‹VTL…‹‹rfk„Š„{u{sle››”lritll››”ztllld”š”š””{||}ddc”››{tt|tts‰v|b[U„„ŠŚ”•uzt‹‹„|„……‹‹”“›’ŚŚ“Ś”„„Š…‹‹…‹’“Ś”{||…„’ś››‹‹‹“““sle’ŚŚ{{tttsult¨©´™š¤tsl’ŚŚtllultred‚|ulddVTLcbVś›››˘›Š}||’…‹’…‹Ś”•ldd‹„‹||Š}‚v‚‹‹„Š}||””‹‹‹„¦§¨¤¤ť››”ttsttsś››ddctsl‹‹‹‘Ś…lek‹‹„””‹SKJd\\{{t\[[dc\}Š‹„‹ult”š”…‹’{||¦§¨llk||‹’Šś¤¦‚v{‹„„{u{mttlld„„f]cbVZ‹„‹f]cŠ}ddcttslekŠ}\UZ‚v‚›”›‚|uultredUUY{zmmtt«˛«|‚z›”›{{tult||||„Š„~’“lrilriŚ”•™š¤tsltsl|‚z|‚zf]cu{{{tttll„„ŁśĄllklddekd|‚ztzl|ztl}\UZlek\[[VTLslemtt¤¤ťMRK%&‹‹‹tsl–˘‹››”lld„„{tt’ŚŚ‹’Š¦§¨¦§¨“““””‹šŤŚ¦§¨””‹µ¶·ś››””‹¤¤ťś¤¦›”›¨©´”“›„„Š¦§¨||„„Ś‹“ult‹’Š””‹¦§¨ś¤¦š””‹„„uztuzt|‚z|›”›‹‹‹UTS|„…{{|„…[[T\[[]cdlekd\\{ttlek“Ś”lrif]cldd{{Š}sle}’ŚŚ‹’Š‹„‹mttSKJllklldsle„„{ttddc{ttj]\llk‹„„lritlluzt|„…‹‹‹lld™š¤|™š¤Š}{ttbVU]cdVZTlld’ŚŚ‹‹„ult””‹””‹’ŚŚŁ››slef]cdc\ztl‹„„ŚŚšŚ”•||ś››‹‹„”š”{||||‹’Šmtt››”…‹‹„„›”›Ś”•„Š„„„tsl”››ś¤¦mtt{{tlltt{|tll{{sleztl„„Š¤¤ť{u{||›”›‚|ukk]‚v{dc\™š¤¦§¨‰v|f]cŚ‹“™š¤ŠŠ}‰|v””‹”“›’ŚŚŚ”•}f]c‹…’“Ś”Š}||‚|u„„Š‹‹‹¦§¨kd\||kd\””‹}\[[ztlsre“““{tt{{t{||sre[[Tlddkk]””‹{||bVZ{{t{{tzll”š”f]c’ŚŚlek‹„„¦§¨¦§¨“““{tttsltt{ztl‹‹‹‹„„lek“Ś”ultŠ}{{tf]c’…‹‚|uddc›”›{{j]\{u{f]c\[b™š¤Ś—Ł…‹‹|‚zlek|mttlek„Š„„„ś¤¦]cdtts|‚z}[[T{tt„Š„lddlld„Š„lld}‹‹„ekd\[[dc\lri”››‹‹„„„u{{{u{}llkmttf]clddddc››”MRK*)(VZTmttztl””‹™š¤™š¤””‹’ŚŚ””‹‚|uŠ}|‹’Š””‹””‹‹‹„¦§¨š””¦§¨›˘›Š}‹…’¨©´›”›„„Š“““›˘›“““™š¤{{t‹’Š”››¦§¨¦§¨ś››ŁśĄ›˘›“““‹’Š|‚z“““„„lek‹’Š…‹‹llk„„tsl|‚z…‹‹}Š[TTd\\{{{u{„„}Šf]cttstsl‹„„Ś‹“’ŚŚ‹‹„{tttslmttJHFlld‹„‹„„[[T{{llkj]\VTL||“Ś”“Ś”ldd|‚z{ttllkult¤¤ť’…‹|‚z‹„„{||„„MRK‚utll””‹‹„„››”‰|v|j]\‹„„}lldsle‘Ś…ulttts}””‹|ś¤¦”š”Š}|‚zš””„„›”›‹‹‹„„Ś‹“…‹‹‹‹„}}tt{“Ś”™š¤|‚z‹„‹‹‹„ś››}{tt}‚ut‹‹‹rfkb[Utll“Ś”[[TlksbVZ“Ś”Š}|{tt‘Ś…”š”rg]””‹Š}¤¤ť›˘›ŠŠ}ult‹„‹tt{tts‹„‹‹„‹‘}ŠŠ}Ł››‘…„lksrfk|j]\{{tllkllk‹‹„‹‹‹}‚ut{u{lri„Š„Š}ddckk]|{u{ttstll|„…lek‹‹‹b[U{tttts{zmuzt“Ś”‹„‹{tt“““uztztl”››ldd}Š{{}ŁśĄ¦§¨}|tsl[[T||}tll“Ś”‹’Šyl„\UZ|„…ś§˛„„Š}[TT„„ŠVZTtlllri|„……„’‹’Štllztlrfkultd\\ult|‚zŚ”•‚u{tt{{t{{tlldŚ‹“{||]bZtzl‹‹‹‹’Š””‹{{lekmttlldztl‹‹‹¦§¨dc\>EC‹’Š„Š„››”“““’ŚŚ“Ś”ttsś››“““¤¤ť“““{u{Š}|‘Ś…Ł›››”›š””„„›˘›››”™š¤¦§¨“Ś”¦§¨Ś‹“|¦§¨¦§¨‹‹‹|‚z“Ś”{{|‚z‹’Š””‹‹„‹”››‹’Šuzt“Ś”}SKJ|„…]bZVTLkd\lld]cd\[blek{u{{tt{{‹‹‹ekdlldult‘…„‘Ś…””‹{||Ś‹“›”›{tt{{t{ttSKJlld|„…™š¤‹‹„‹„‹„Š„Ł››lri‹„‹uzt|„…‹‹„‹‹‹{tt||u{{u{{{{|„…“Ś”ulttt{lri›˘›‹„„››”‹‹‹˛««‘Ś…”“›|zllttstts„Š„ś¤¦tt{…‹‹kk]‹‹‹¤¤ťŁśĄ‹’Š‚utŚ”•Š}„Š„”››Ś”•”“›{u{…‹‹tlltts}…‹‹™š¤™š¤„Š„tts„Š}ś¤¦‚v{‚|u…‹‹mtt“Ś”ldd[[Tlldsleztlult¨©´“Ś”’ŚŚŁśĄllk|lddš””ztlŚ‹“{{tś››““““““mtt{tt{u{›”›‹‹„zll‚utš””„Š}››”{{t||››”‘}||tsl››”{||‹‹‹sle‹‹‹“““[[T‹„„lldlriŚ”•{{‹‹‹{{tt{{u{lks‹„„uzt{||sled\\SKJ„„[[Tuzt””‹{|||}š”””“›{u{„„‹„„‹‹„‹’Š|„…’ŚŚ“Ś”tsl‹„‹|‚z{|||||„…lks]bZmttslemttedktsl¦§¨mttldd{{t”“›{||ultttsj]\„„Šllk‹‹‹lld{tt}Šlek{{Ś‹“tts‹‹„tll[[TmttŠ}lek„Š„{||{{tlldlld˛¬µ]cd-1+tsl‹„„››”|{||··Ä¤¤ťŁ››‹‹‹”š”¦§¨ult˛¬µŁśĄ|¤¤ť¦§¨¤¤ť|Ś”•š””Ś‹“¨©´’ŚŚŞł·ś››µ¶·ś››š””¤¤ť”“›››””š”|‚z…‹’}}‹‹„ś¤¦|‹„„lddu{{uztllkŚ‹“”››tt{Ś—Ł‹‹‹lek{u{…‹š‹„‹‹‹‹|ztl››”‚u‹‹„{||{||}„Š}Š}kd\‹„‹lld‹‹‹…‹‹„Š„{||u{{Ł››…‹’zll¦§¨lkstzlmtt‘…„‹„„š””tts“Ś”{||ldd{||…‹‹mtt|‚z|ś››”“›ŠŠ}ŠŠ}ddcś››‹‹„’…‹{zm|‚z“““{ttlriddcŠ}‹‹„Ś”•™š¤Š}‹’Š›”›‹‹‹„„tt{{{Ś‹“„„Š“Ś”{{¦§¨{{’ŚŚ‹„‹”š”tllttsfkktsl‹‹„…‹‹{||“““{tt„„{u{d\\SKJu{{rfk‚v{™š¤Ś‹“‹‹„””‹zll{{t||{{t‚u{||Ś‹“tts‹„„‹…’kd\tsl‹‹‹¦§¨||lek‚ut|„„‹‹‹””‹u{{„„ztl”š”””‹’ŚŚ‹’Š‹‹„sre{||]bZtsl{||tlluztuztsle{ttedkzll|‚ztsltllj]\zllslelld‹‹„Ś”•|’ŚŚ{tt||tsldc\tsltt{lrikd\slered{u{lddddc‚|u\[bllk…‹‹mtt¦§¨SKJtsl„„Š…‹’lrib[Uedk{{ś››„„ultedk}|‚ztll”š”Š}‹‹‹zll\UZllktt{ttslksmtttt{[[T„„Šultlri{{t„„Šlrisle\[b¦§¨LKR%&Ł››Ś”•ŁśĄŁśĄ™š¤Łť˛Ł››¦§¨””‹„Š„‹‹‹}Ł››››”¦§¨››”¤¤ť{||„„‹’Šś¤¦¤¤ť··Ä¦§¨¦§¨‹’ŠŁ››…‹’|{{{tt„Š}{{{{tŚ”•”š”|„…Ś‹“Ś‹“‚|u››”tll…‹’|‚zVTLlddmttmtt…‹‹lks¦§¨ttsultŚ”•|‚z‹‹‹\[[¦§¨ztl‹‹‹d\\””‹tll‹‹„’ŚŚlld™š¤“““™š¤{{tsl{{sleŚ”•ś››™š¤“Ś”‹…’|„…lld||{tt„„ŠUTSlek„Š„{zm{{LKRekd„Š„‚|ukk]‹‹‹¤¤ť””‹Ś”•|‚zś››{tttts‚u’ŚŚ‹„‹uzt}||””‹{{t{||‚|u|šŤŚfkk””‹„„tts{||„„Š{||Ś‹“„Š„|‚zŁ››{||ttsu{{Ś”•lddlddd\\‘Ś…ttsŠ~‹™š¤[[T„Š„tsl‹„‹||’ŚŚŠ}}Š‹’ŠŠ}‚|u’ŚŚ{{t\[[¦§¨j]\lriSKJŁśĄ„„Š“““Š}„„||Š}||‚ztzl„„Š}’ŚŚ‹‹„{ttŠ}ldd|{{t„„”››tll{||¤¤ťlddrg]{u{”››lrilri\[[|„…„„Š‹„‹mtt{{t|‚z{{tVTLbVZztl“Ś”{{ttsldc\]bZllk‹„‹|ttsldd‹‹„™š¤{u{|tt{‹u…‹…’‚|u„„Š{||Ś”•[[TŚ”•ś§˛{{\[b¦§¨Ś”•tt{‹’Šb[Umtt{{{ttrfk’…‹{u{UTSlritlltts”››}ult‹‹„{||ddclri‹„‹{||…‹’tsl|„…b[Utts‹„‹llk‹„‹[TT\[[¦§¨ek]FD;Ś”•””‹¦§¨ś¤¦}¨©´‹„„¦§¨µ¶·¦§¨¤¤ť’‘~ŁśĄ¦§¨¦§¨˛˛¬‹’Š“““Şł·ś¤¦™š¤‘…„ś¤¦Ś”•|„…‹‹„š””„Š„™š¤¨©´‹„‹”“›¦§¨““““Ś”››”{{t”“›‹„„||{tt’ŚŚ|„…lri{u{llklri“““\[[{{{||{u{dc\›”›‹’Š“Ś”””‹Ł››{tttsl„„zll||{ttŁśĄŠ}}‹‹‹Ś”•‹„‹||‘…„sre‚ut„„›”›{||ddc}Š…‹‹tts“Ś”›”›‹’Š„„Š„„’ŚŚ‹„„Ś”•lrikk]š””llkllkš””‹„„lld{{t‘…„UMRttstslŚ”•ultŚ”•››”››”››”uzt„„Š¤¤ť„Š}”š”{tt„„ult‹‹‹”“›‹‹„lekekdlriddcu{{}lldtt{uzttts{{t|„…}ldd‹„„ult›˘›Š~‹|‚zŠ}SKJ{u{‚v{sre‹„„|ztlŠ}””‹||||mttllk„„Š„Š}{tt‚v{„„Š}ldd‹…’\[[’ŚŚ’ŚŚ¨©´””‹”š”‹‹„lldjcV‘}]bZkk]bVZ{tt„„„Š}‚u{zm‹’ŠVTL‹‹„\[[|„…\[[f]clddekd|sle{tt’ŚŚ‚utf]cVTL|UTS“““ś¤¦‹‹‹’ŚŚ]bZztluztlri””‹dc\Ś”•’ŚŚ}rfk\UZ“““|‚z„„ŠŚ”•|„…u{{{{tts}¦§¨¦§¨‹‹„u{{„Š„“Ś”Ś‹“¦§¨tt{u{{|‚zŠ}|lri”“›lddf]cVZT”“›{||UTS“Ś”ttsVTLtslŠ~‹‹„‹dc\ultu{{ultŚ‹“llk¨©´UTS)+2››”||„„„„š””¨©´¦§¨«˛«›˘›™‹†››”‹„‹’ŚŚ””‹“““‹‹„™š¤››”|”›››”›”š”ś›››˘›“““™š¤”“›¦§¨Ś”•¨©´”››Ś‹““““”››””‹z‚l¦§¨ś››…„’{{t|||‚z{{“““„„ddc{||lks}Š‹…’„„“Ś”‹’Šuzt{{t„Š}ś››“Ś”‹„„{u{{u{‚utlddf]ctllztl‚uVTLult|d\\Ś‹“ultVTL}{{llkllk{tt‘…„ŁśĄŚ”•‹‹„{u{u{{Ś”•‹‹‹‹‹‹‹‹„„Š„ztlŚ”•tts¦§¨š””“““‹’Škd\‹„‹JHFlri|tll‹’Š¦§¨›”›””‹¤¤ťŚ”•|||¦§¨ś››lld|tll‹’Šsle“““Ś‹“|„…“““…‹’‹„‹ztl\[[””‹}Šš””{||Ś‹“‹‹„tt{|”š”‹…’|„…zll{{tŚ‹“}llk„„‹„‹„„dc\‹‹„yle‚u’ŚŚ‹„‹tlltts}{tt„Š}uzt¤¤ťŠ}{tt{u{“Ś”ttsdc\{||””‹{{tllk‹‹„ztlztflddś››lrillkddc‹’Šek]|‚zdc\|‚zdc\lddUTSf]clekred…‹‹¤¤ť[[T{{“Ś”‚|u{{t„Š}”››„Š„edkŠ}|’ŚŚ„Š„Ś‹“››”ś¤¦‹…šsre”››tt{{u{‹’Šlrimttuztddcekd”“›uzt””‹]bZ™š¤edk|‚ziq]lks{||sletll‚utultµ¶·{||uztu{{„„dc\tts‹„‹{{Ś”•dc\‹…’tts\[[|‚zddc{ttuzt‹„‹}{u{”š”tll¦§¨\[bLKR|‚z…‹‹Şł·Ś‹“’ŚŚ“Ś”››”‚u–˘‹„Š}¦§¨‰v’ŚŚ‹‹„¤¤ť|„…¦§¨››”||‹‹‹”››’ŚŚŁ››‹’Š¨©´ŁśĄ··Äś¤¦‹…’¨©´¦§¨¦§¨„„ŠŞł·š””¤¤ť¤¤ťś¤¦„„||š””||fkk„„{{‹„‹{||””‹{{ŁśĄ“Ś”}ult{u{tslŚ‹“tt{””‹Š}››”‹„‹tslldd‘Ś…¦§¨’ŚŚdc\rg]llk{ttlldsle‚ut‘…„”››ultŠŠ}llk{||d\\“Ś”‚|u‹‹„›˘›™š¤Ś”•|„…{{llkdc\]bZ‹„„ttslek‚|u‘Ś…ldd«˛«Ś‹“{u{}cbV”š”„„{||””‹’ŚŚ¤¤ť‹‹‹š””{tt‚u¦§¨„Š„‹’Š¨©´{ttŚ”•‹‹‹‹„„ŁśĄ”“›‹‹‹{||{{‹‹‹…‹‹|‹‹‹|‚z{u{…‹‹ttsult{||fkk\[[Ś‹“u{{‹‹„Ś”•{u{{tt|“Ś”{tt{zm{tt‹‹„‚|u””‹|ldd\UZ‹’Š“Ś”‹’Š“““sle’ŚŚd\\kd\{tt{{tlldmtt]bZekdtts„„šŤŚ}bVZŠ}…‹‹llklldkd\SKJddc{u{ztlllktzlb[U{u{{tt{{tu{{lri||r]g¦§¨||¦§¨”š”…‹‹‚u‹‹‹›”›cbV””‹‹„‹|‚z„„Š‹’Š›˘›ś¤¦‹„„}””‹„Š„‹’Š|„…|‚zekdś§˛|‚z|‚z‹‹‹mttuzt||d\\UMR›˘›‹’Š||lksf]c››””››{{t›˘›]bZŚ”•‚|u“Ś”uztmtt[[Tttslri|‚zdc\JHF}tll}[TT{ttultd\\¦§¨MSSLKRś¤¦›”›”“›ŁśĄ‚v{||’…‹””‹¦§¨¦§¨¤¤ť˛¬µ“Ś”¦§¨|“““tzlŞł·‹’Š¨©´‹’ŠŁśĄź±Ż¦§¨¦§¨”“›…‹‹¦§¨ŁśĄ””‹™š¤…‹‹„„“““‹‹‹™š¤””‹’ŚŚ…‹‹‹…’edk‘Ś…\[bŚ”•}Šµ¶·lks™š¤ś¤¦„„Š‹„‹‹…’||ś¤¦||Ś‹“llkztl’ŚŚ|‚z„Š„{{t“Ś”||’…‹lld‚|u’ŚŚtsl{||…‹‹Š}‹„„sleu{{’ŚŚ‹‹„|‚z\[[tts‚u“Ś”}ekd‹‹‹llkś¤¦tt{ddctzltsljcV||¤¤ťś››‘Ś……„’‹‹„‘…„‹‹‹{||›˘›|‚z“““‹’Š‹„„zllŠ}||{tt’…‹‹’ŠŚ‹“u{{“““‹‹‹zll’ŚŚ„„{{tŚ‹“„Š„‹„„”“›||{tt”“›|tt{tsltts›˘›tllŚ‹“tt{tt{\[[“““ultllk}lks¤¤ť„Š„‹u…{{t|››”Ś‹““Ś”}tts{u{||ttsś››””‹”“›‘Ś…||Š}|{ttsle{tt[TTkd\tsl{u{„„{{tŚ‹“kd\””‹{u{‚v{JHFŠ}|ztllri‹‹„{ttultbVUdc\{u{lekŠ}ttstts‚ut||{{‚ut«˛«›˘›„Š„{||„„Š‹„„‹‹‹ztl„„|‚zŁśĄ‹’Š¦§¨Ś”•sle„„š””|„…tzlŚ—Ł…‹‹Ś”•|„…]bZ|„…]bZu{{\[buztJHF\[b{tt]bZyle\UZŚ‹“{||tllredVZTek]fkklddlekedk|„…ttsu{{]bZ]bZ|‚z‚v{ult„„‹‹‹|||sle\[b¦§¨MRKUTS|„…cbV„„ŁśĄ“~‹„„””‹Š}|‚z‚n’ŚŚš””sle|„…{||“““¦§¨›˘›¦§¨¨©´Ł›››˘›«˛«lld‹‹‹«˛«ś¤¦”“›“““ś››Ś”•Źˇˇ’ŚŚŞł·”“›llk‹‹„lri‹’Š‚|u{||‚|u{{Ś”•ult‹‹‹{{}Š{{lkslldd\\‚ut}}ztl‹‹„‚ut‚v{‹‹„lek‚|ured’…‹{u{{u{{ttŠ}lddldddc\sle‘…„›”›‹„„|¦§¨|‚z\[[{||‹„„ult‹‹‹{u{\UZllk„„f]cf]ctzlsreSKJ|tzl[TT‚ut‹…’sle‚|u“Ś”[[T‚u””‹”“›™š¤››”›”›¦§¨¦§¨{||‘…„tsltsltsluzttts’…‹}Šš””š””„„ŠŚ”•‚|u}›”›uzt™š¤š””„„ldd‹’Š{{tlddŚ”•||ztl}f]cuztultś›››”›Ś‹“””‹‚|u|‚ztslś¤¦„„ŠŠ}¦§¨ult“Ś”””‹”››„„”››’ŚŚ‘…„}Š}|ult{||d\\“Ś”Š}ult|{{t|‚|u‘…„yle{||‚|usle{{t¤¤ť||tsllldFD;uztllktzllld\[[lld}Šdc\bVZSKJtzlztl‹’Šlriultztl“““kd\””‹¦§¨›”›Şł·{{tkk]ztlŚ”•tsl…‹‹uzt„Š„u{{mtt‚v{u{{{||lksddcllkMSSlldult‹…š„Š}{{tUMRf]clektll”š”{{tlld{||u{{„„Štll\[[dc\]cd]bZlri‹’Š‹„‹„„Š‚utultŠ}Š~‹UMRf]cŁ››JHF?;C„Š„„„Š“Ś”Ł››‹„‹|‹‹„’ŚŚŠŠ}””‹Š}Ś”•¸Áą¦§¨¦§¨›˘›”š”¦§¨ś¤¦ś¤¦¦§¨‹„„ś¤¦‹’Š‹uŠ„„…‹‹“““¨©´¦§¨Ś”•…‹’Ś‹““Ś”ŠŠ}’ŚŚś››|‚ztsl‹„‹ŁśĄ‹„„uztUUY¦§¨Š}lksultlksmtt…‹’|||ś¤¦{u{}{{t||“Ś”|‚z”››“““‹„‹‹„‹‹‹‹Š}ldd†~‘{u{™š¤‹‹‹“Ś”””‹cbV{{t‚u‚u{zm‹„„j]\‹’Š||¦§¨ttstts|‚ztllf]c}|lrilri‚ulri„Š„{tt{||zll‚ut‹„‹““““““|›”›™š¤’ŚŚ‘…„¦§¨||””‹|||‚z{u{{{”š”ult‹„„’ŚŚ„„tll„„Š‹’Š’ŚŚ{u{’ŚŚu{{“Ś”„„tsl{{t…‹‹|„„tllf]c„„”“›“““{{||{tt{{zll\[[||‹„„{||‚uu{{b[Usle‘…„jV[‚|u‹‹‹„„””‹„„ztlŠ}ś¤¦š””tts““““Ś”Ś”•‚v{}j]\‰|v‘…„””‹¤¤ť‘…„{tt{tt‹‹‹[TT‚|uŁśĄŠ}|ylett{sre||tll‹‹‹‘Ś…lddiq]{u{‹…’|„…||kd\{{ttsl„„Šf]ctll{u{b[Ulksztl|„…™š¤uzt{{t‹„‹mtt{||\[b|„…lks…‹‹UTS“Ś”{||\[[|„…lkssle\[bllk\[bUMRttsuzt\[b{{lekdc\tt{‚u‹‹„\[[{{t|[[T”š”{{t|„…{{tultldd}tll™š¤”“›››”lddbVZldd¦§¨\UZJHFlks|„…‹„‹ŁśĄ™š¤‚|uŠ}”š”””‹””‹””‹«˛«¤¤ť¤¤ť””‹ś¤¦¦§¨‹’Š¨©´«˛«µ¶·›˘›{{t””‹¨©´ś¤¦Ś”•”››Ś”•’ŚŚ‹‹‹Ś‹“™š¤¦§¨|‚zś¤¦‚|u‹’Š„Š„yleult¦§¨]cd{{tlekultŚ‹“edklksu{{|„…”š”dc\„„Šlek”“›{||¤¤ť‹„‹{{tlri{ttŚ‹“’ŚŚ¨©´ultlddUTS¦§¨|„„||”››sleddc\[[lri|lek[[T{tttll‚|u„Š„„„|„…uztJHFlkscbV|‚zllk””‹|‚z„Š}””‹””‹Š}|kd\„„Ś”•|‚z‹‹„tll„Š}‹„‹›”›˛««“Ś”¤¤ťtll„Š}Ś‹“š””‹’Š{{‹‹„||{tt“““’ŚŚ|“Ś”’…‹‹„‹ddcult“““‹„„””‹‹’Š„„Štll[TT“Ś”„Š„{u{„„}ś››}˛˛¬’ŚŚ|‚z„Š„‚n„„Š”š”{||{{t‹‹„lddmwŠ}|‹‹‹|„…“Ś”„„Š}ylebVZŠ}|ś››ekd}{ttkd\zll{ttš””‹„„’ŚŚ‹„„‘…„››”’ŚŚ{u{ult“Ś”‘…„[TT}[TT„Š„lri{u{{ttŠ}mtttt{‹‹‹ultllkztlUTSŁ››tll…‹‹›”›‹„„“Ś”{tt{tt[[Tllkš””\[[››”‹„„ttsLKR[TTtzl\[[SKJmtt|„…mttś¤¦ddcu{{lekś¤¦dc\ult’ŚŚ“““‹„„lks{u{ult[[Tś›››˘›‹’Štzl{{t}fkkfkk|{||uzt„„uzt{tt{{tŠ}ultŁ›››”›kd\tllŁ››JHF*)(”››“““‹„„‘…„‹‹„”“››”›””‹|‚zz‚lŁ››ś››ś››“““›˘›··Ä«˛«Şł·¦§¨µ¶·«˛«ś››˛˛¬Ś”•‹’Šś¤¦ŁśĄś¤¦‹’Š”š”ś¤¦”“›Š}|¦§¨ś¤¦ś¤¦Š}Ś”•‹‹„lld}Šult„„Š””‹Ś‹““Ś”{u{„„Šllk|„…›˘›‘…„“““lri{tt“Ś”””‹‹„„š””””‹“Ś”||‚utŁ››ś››””‹‹„‹ddc„Š„||„„Š’ŚŚ‹„‹{u{f]c[TTlldcbVŠ}UTSšŤŚ‹„„’ŚŚ‚n[[Tlrikd\{{lri{{t‹‹„lri{zm{tt›˘›|“““zll{{t‹‹‹‹‹‹“““Š}|‚z||„„‘…„¦§¨’ŚŚ{{t‹…’|ś¤¦Š}””‹”“›‹„„‹„„fkk‚ut“““tslult‹‹‹ś››u{{}”š”‹’Š}ddcŚ‹“tt{||lddldd„„{{d\\ult‹‹„‚v{{tt››”lri‚ut|‚z„Š}uztztlzll||tllttsš””¦§¨‹’Šuzt‚|u›”››”›lddztl„„Štts||lek‚|uttsek]||Š}“Ś”‘}Ł››š””ŠŠ}“““lek||ztlsle‚wl‹„„dc\uztztl{ttuzt„Š„‹’Š„„Š“““‹‹„|‚z¤¤ťŚ‹“„„llkldd„„Š“““‹‹„ś››u{{|{{t]bZ{u{SKJUMRmttSKJ]cd]bZ|‚zŚ”•mtt‹’ŠŚ”•lri„„ŠMRK}f]clldJHFdc\UTSd\\mtt|„…tll‹„„‹‹„lriekdlri|\[[tlltt{dc\lridc\{u{{{lddlektll}d\\ldd¦§¨JHF$›˘›|”“›’ŚŚ”š”ŁśĄ™š¤‘Ś…””‹¦§¨””‹¦§¨¦§¨š””¦§¨ś¤¦Şł·¨©´¦§¨µ¶·‹’Šś››Ł››‹’ŠŚ”•”››Ś‹“”››ś››lek‹’Š™š¤‹‹‹¦§¨Şł·…‹‹’ŚŚ„Š„tsl{{tŁśĄ‹…’\UZUTS|{ttlri|„…lri|„…z‚l’ŚŚ””‹„Š„„„Š‹‹‹tll“Ś”‹„„›”›‚utŚ‹“‰vŁ››Ś”•””‹„„{||tts‹„‹sle¦§¨„„bVU‹’Šldd|‚zdc\|j]\dc\redzlluzt”š”ttsJHFlek{{sretsl{||Ś”•ś››››”{zm{||Š}sleult|uztŠŠ}tts”››||ult¤¤ťś››tzl{||‹’Š”š”„Š„”š””š”‹‹‹››”tt{|lri…‹‹‚v{{u{|||‚zmtt‹„„ult‹…’ek]š””{u{tts‹‹„“Ś”zll’ŚŚ“Ś”‚v{‹‹‹lek‚utslcbV|‚zuztkd\„„„Š}zll’ŚŚŁśĄŠ}tsl|‚z„Š„“““‚|u‚v{’ŚŚ‘…„red„„Š{{“““r]glrilld{u{{u{Š}|[[Tkd\‘}‚|u‹‹„|‚zj]\lddf]ckd\{u{Ś‹“Š}[TT‹‹„dc\|„…‹‹‹ek][TTlld{{t{||¦§¨“““{u{ult¦§¨¦§¨›”›{||›˘›|„…mtt{{tUTSddc|‚zŚ‹“\[blri””‹‹’Šmtt™š¤uztŚŚšlriu{{leku{{lksŚ‹“mttlri{{{||{{t{{|„…zllddcttsuztllk„„Šuzt|‚zlekdc\ztl{u{ult„„}Š}{tt“Ś”{||ttsult¦§¨VZT*)(”››“Ś”””‹‚|utsl’ŚŚ‚wlŠŠ}””‹¤¤ťµ¶·””‹Ł››››”Ł››„„””‹¦§¨Ł››¤¤ť»ÂǤ¤ť¤¤ťś¤¦|‚z‹’Š··Äś¤¦„„Š||Ś”•ś¤¦…‹‹››””››tzl””‹ś¤¦“““|‚z“Ś”‹„‹|„…|‚z™š¤[TTVTL[TTlriu{{‚ut‚v{tllŚ”•”“›””‹’…‹||‚v{Š}Š}zllŁ››Š}„„lld{{tlld”“›lekyfd†~‘}kd\tsl{tt’…‹””‹{{t{tt||‰v|uztllklddŚ”•cbV{u{SKJlri|‚z‹‹‹tzldc\””‹‹‹„“Ś”‘Ś…‘…„{u{{zm‹’Š{tt„„Š””‹{ttŠ}tsltsl|‚z›”›|‚z””‹‹’Š‚uŚ‹“tsl‚|utts||‹‹‹ŠŠ}ultult|„…ttsuzt{{t}‚|utsl‹’Š{{tlltts{{t™š¤˛««‹„‹ult|‚zdc\tsl„„‚v{||{{t”š”ś¤¦‚|uŁ››“Ś”‹„„‚ut{{tuzttzl{zmŠ}|‚|u‚|u’ŚŚš””„Š„uzt||“Ś”‹„‹Š}|‚ztllztfb[Uekdttsj]\‚u|‚zllkŚ‹“{u{Š~‹{u{{||||[[T”š”|]cdUTS‚|uf]cbVU‘Ś…b[U{{tj]\Ś”•llk{||Š}‹‹‹‹‹„{tt[[T[[Td\\llk“Ś”|‚z{tt{{|„…Ś”•lksŚ”•Şł·ś¤¦{{‹’ŠMSSlriVTLbVUf]cUMR>B9||Şł·“Ś”|„…]cdtts]cd|„…ek]™š¤„Š„Š}…‹‹{{t|‚z{tt’ŚŚb[U‹„‹{u{ult{tt’ŚŚr]Z‹„‹{ttś››MRK*)(””‹˛¬µŁśĄ””‹ultmw””‹ÄÂż¤¤ť””‹›˘›Ł››˛««””‹ŁśĄ¦§¨¦§¨Ł››Ł››¦§¨˛˛¬‚wl‹‹„””‹›˘›{||ŁśĄś¤¦‹„„¦§¨‹„‹{ttllk¦§¨“““Ś‹“‚u„Š„’ŚŚ|‚z¤¤ť‹‹‹…‹’FD;„Š„ultu{{u{{fkkUTS{ttzll‹„‹…‹‹}‹‹„š””d\\{u{lld‹„„Š}|||‹‹„}uzt{ttkk]„„UMRrfk‚utttsSKJztlrfk””‹tsl\UZ“““‹’Š‘Ś…‚wlllkttsb[Uldd{||{||¦§¨kk]}ek]|„…””‹‹„„‹‹„š””ult“““‹‹‹lld”š”llk{tt}slesle{tttsl{u{”š”«˛«¤¤ť”š”„„Š}Š}|‚ut‹‹„“““|’ŚŚuzt„„u{{{{{{t}lri‹’Š“““||ttslri„„”“›Ś‹“ult{tt{{tkk]{{tultttsllddc\{{t{zm{{tj]\zll‚v{‹„„{u{tll|tzlb[U{{tŠ}|š””tllŠ}|ś¤¦}ult“Ś”Ł››Š}lrilri“Ś”VTL{zm‚|u‚|u“““›˘›ultlddzll‘…„ztlf]ctts|‚z{tt{||uztlldtsl{||fkkek]tts{zmddctllš””VTLultuztbVUlriuztekdŚ”•””‹¦§¨Ś‹“f]c‹’Š…‹‹…‹’”››ś¤¦ttstt{u{{UUYJHF]bZ}Š{{[[Ttsl{{Ś”•‹’ŠmttŚ”•‰v{{tldduztttslriuztuzt{zm„„llkf]ctllkd\ldd‚v{rfkztl‚v{leklek«˛«JHF,55llklks}””‹š””Ł››¤¤ť››”|‚z¤¤ť’‘~µ¶·˛˛¬˛««š””¦§¨¤¤ť‚v{uzt„Š}¤¤ťŁ››¦§¨‹‹„|‚zś››ś¤¦”“›{ttś››||ztl‹‹„‰|v\[[lritlllld{{t{{t„„Š~‹…„’tyguzttll‹‹„|‚zŠ}{||rg]‹‹‹kk]‹‹‹‹‹‹}|ult‹„‹|›”›‘Ś…“““ś››Ś‹“tsllekŠ}‚v{zll[[Tb[Uultrfk|‚|u{u{„Š}Ł››”“›{{Š}|{u{…‹‹}‹‹„‹„„„„tt{jcVi\V‚u|||›˘›¦§¨“““””‹‹‹‹{u{|sreztf{u{‚|u|‚z‘…„{zm|„…tsl‹‹‹‹’Š|‚z…‹‹›”›|‚z“Ś”|}”“›ś¤¦|tll{{tŚ”•Ś”•Š}Ś”•Š~‹{u{‹’Š’…‹}fkku{{tll’…‹ult{ttš””\[b{{t|sle|lektll|‚z‚u{u{‚|uŁ››ŁśĄ‹‹‹}‹’Š”››{||tsltslrg]|sle’ŚŚ“““{{t|“Ś”tsl’…‹››”kk]ult‹„„|||lld‹‹‹}‚ut{||bVUrg]kd\lekŁ››||tsl„„uzttts{u{z‚lmtt{zmztlj]\tts{{‘…„ŚŚšz‚lekdtll|„…„Š„„Š„yl„]bZ‹’Š‚|u{||‹’Š‹‹‹Ś‹“Ś‹“‹‹„¨©´fkk|„…\[b„„ŠUTSD;9lksmtt‚|u{{lks”š”mtt{{Š}’ŚŚ“Ś”‹’Š‹‹‹{||tts‚uttsltt{|‚ztlllekredf]cf]c}{ttŠ}tlltll¦§¨MRK*)(„„||¦§¨¦§¨Ł››˛˛¬¦§¨‰v¦§¨µ¶·ĂÄƤ¤ťµ¶·“Ś”””‹”š”ŁśĄ¦§¨µ¶·››”””‹‹„„‹‹‹ś››“Ś”tts¦§¨™š¤˛˛¬””‹¤¤ť‹’Š”››Š}ttsVTLtts”š”‹‹‹uzt{tttts„„]bZ|¦§¨uztllk„Š„{{tztl|‹‹‹Ś”•uztd\\ldd||‚|uztlŠ}””‹‚utedk„Š„tts“Ś”lld’ŚŚldd™š¤Š}„Š}‹‹„Š}f]c‹‹‹{{tldd„„Š‹‹„™š¤‚uttts[TTSKJŚ‹“lriekd‚uŠ}tts‰v|“Ś”˛¬µ¤¤ť¤¤ťŁ››‹‹‹}™š¤‚ukk]‹„‹””‹||‹‹‹››”‹’Šztlult|‹’Š””‹‹„„“Ś”}Š}{|||Ś”•{ttlrikk]{u{…‹‹¨©´|tll{||Ś”•‹‹„}{||u{{‹„„{{tult‚|u}”š”””‹tsl””‹ś¤¦‚v{›”›{{trg]{{t‘Ś…||›”›‚ut“Ś”“Ś”››”{{t’ŚŚ’…‹d\\ttskk]’ŚŚ”“›‰‘~¦§¨ttsŚ”•ś››‰|vsre››”‚|u{{tdc\kk]|||d\\{u{slered{tt{tttll\[[{u{lld{||VTL{tt|„…ttslldztl’ŚŚŚ”•lks{||‹„‹lritts‹„‹Ś”•uzt™š¤lddtll|‚z”››llk{||„„‹’Š’ŚŚ‹’ŠVZT\UZlrislef]cu{{{{‹…štlldc\UTSlri‹’Šlks…‹‹|‹„‹{|||„…ś¤¦{|||‚zddctsl}ekd{tt[TT|{tt{u{Š}{tt››”Š}dc\µ¶·JHF*)(„Š}“Ś”ś¤¦‘}””‹ŁśĄ‘Ś…Ł››””‹»ÂǦ§¨˛˛¬˛««˛««¦§¨¦§¨ś››¨©´›”›Ł››“““|||tzl™š¤…‹‹}‹’Š¤¤ť¦§¨ŁśĄŠŠ}‚u¦§¨uztuzt“Ś”››”}‹‹‹tslttsŠ}ddc‹’Š|‚z„Š}|‚zlridc\||ttsuzt„Š„||ldd{u{d\\zllŁ››š””ś¤¦¦§¨¦§¨¦§¨|‹‹‹”š”{{˛¬µ’ŚŚŁ››‘Ś…‹‹„tll}tts…‹‹„Š„‹„‹yleš””tll|mttVTL’ŚŚtt{”“›|kd\„„‚uVTL’ŚŚ‚|u‚wlš””tt{‚|ullkdc\tslult‹„„||‘Ś…‘Ś…‹‹‹jcVmw{zm¦§¨ŁśĄ‹…’™š¤‹’Š›”›{u{{||‹‹„“““{u{‹‹‹Ś”•Ś‹“{||‹‹‹„„{{t‹‹‹tsl|||„……‹‹{||‹„„›”›}‹„‹tts‹‹„|‚z{zm¤¤ťtll{u{|{{t›˘›{{t””‹||||{{t‹’Š|„…‚|uŠ}yle||red„Š„””‹||’ŚŚ‘Ś…””‹„„dc\uzt””‹‹’Š||slekd\mtttzl\[[ult||’…‹‘…„sle“Ś”||‹‹‹„„|‚z„„Š{{tb[UtllŚ”•„Š„lld…‹‹”“›||””‹„„Šś››|„…ztlś››„Š„Ś”•’…‹lddŚ”•tts„Š}|‚zmtt™š¤”“››˘›{tt{{mtt””‹|„…Ś”•tt{}red‚v{lksŚ”•ekdleklksztllek„„Šuzt„Š„dc\[[Tekdlek}lld{||[TTtlllddlek{tt‚ut„Š}Š}|]bZ··ÄJHFF=C‹„„Š~‹””‹˛««˛««ŁśĄ””‹|‰‘~˘—ŤŁ››|šŤŚ‘…„‘Ś…š””˛««››”˛¬µ··Ä“Ś”ś››Ś”•›˘›llk“““‹‹‹{tt››”Ł››Š}‹„„¦§¨ŠŠ}‹‹‹„„Š…‹‹lritts‘Ś…‹‹„tsldc\tts|\[[[[Tkd\VTL[[Tr]g‹‹‹‹’Šek]“Ś”{ttlldllk‚ut”š”‹„„|‹’Štts„Š„‹‹‹zlldc\{||“Ś”rfk¤¤ť”“›››”„„Štsl‹’Š|‹’Š“““‹‹„||tllllktzl||‚wlŚ‹“{||redsleSKJ{{t|zllsletsl{zmlekf]c„Š„rg]„‰vttsŠ}{||š””””‹¦§¨‹‹„””‹sle|‚z””‹“Ś”“Ś”‹’Š}Šu{{{tt¤¤ť‹„„‚ut}Štt{}llkllk|“Ś”lld‹‹‹{tt”“›”››‹‹„{ttult‹‹„‹„„f]c›˘›|‚u‹‹„„„‹„‹›”›‹„„¤¤ťŠŠ}sreŁśĄ{||‹‹„„Š„‚|u{tt‹„„llk{tt””‹JHFtts{zmrg]{{tŚ”•„„{{t‹„„¦§¨Ł››jcVdc\sre]cd{{t¤¤ť¦§¨“Ś”š””‚uttts‚utś››Ś‹“‹’Š[TTddcsref]clldult‹’Š„Š„™š¤u{{›”›kk]“Ś””“›Şł·ztl„Š}‹’Šult“Ś”Ś‹“u{{š””„„Š‹‹„|„…‹’Š“““lri]bZlldfkkVZT]cdllk{ttŚ‹“‚|u‹„„VZ[mttŠ}‹…’llkŚ”•{ttmtt]bZedkdc\{||fkk{u{lddzll{{tllultyfdred››”ldd‹’Š|||¤¤ťJHF*)(tsl’ŚŚ”š”˛˛¬˘—Ťš””””‹’‘~‚wl””‹¦§¨‘Ś…Ł››¤¤ť“Ś”˛¬µ¨©´˛¬µ“““ś¤¦¦§¨ŁśĄ«˛«‹‹„“““™š¤‹‹‹„Š„¦§¨‘Ś…ŁśĄ¦§¨‰|v¤¤ť™š¤u{{‹‹‹››”Š}¦§¨{||dc\uzt„Š„]bZ{|||‹’Štzllri}Ś”•‹‹„Ś‹“‚|u{tt{tt|‘Ś…Š}kd\r]gztl¦§¨tsl{||llkVTLtt{‹„„‹„„Š}uzt’ŚŚ„Š„‹„„{||sre{{t„„‹‹‹sle’ŚŚtsl|“““lddtt{{{kd\sre‹„‹|‚z‹‹‹tll||{zm„Š}f]cVTLztl‰|v’ŚŚŚ‹“sle„„Šś¤¦‚u‹’Š|Ł››‹’ŠŠŠ}“““Ś‹“”“›…‹‹’ŚŚmtttsl››”›”›‹„‹Ś”•ultd\\lks‹„‹“““ldd|‚z‹„„™š¤™š¤tts‹‹„‹„„Š}tsl[TT|{zmdc\ztl‹‹„‹„‹{tt‚|u¦§¨ŠŠ}””‹{{tult{ttlri„Š}”“›zllult‹‹‹tll‚|u””‹f]cultŠŠ}Ś”•sreŚ”•””‹«˛«’…‹“““|lddredSKJtslcbVtll||||sleŁśĄ‹„‹VTLb[Uddc‹‹‹|„…tll‹„‹{{tllkuzt|‚zSKJlri{||‹„„ŁśĄ“““‹‹„¦§¨{tt›˘››”›‹„‹’ŚŚlriŚ”•{{kd\¨©´Ś”•™š¤uzt„Š„ŠŠ}JHF|„…lri}f]c\UZ]bZult|„…}}’…‹lkslrimtt|‚zttsSKJlriuztedklks|||tts‹‹‹ttsrfkd\\{u{Š}‹‹„Š}{||Ł››:97*)(ś¤¦’ŚŚŠ}˛««˛««˛««š””¦§¨””‹‘}µ¶·˛««“Ś”˛««˛¬µ˛¬µ¦§¨™š¤‹‹‹¤¤ť}¦§¨“Ś”“““ś¤¦”“›Ś‹“››”¦§¨””‹Ł››“Ś”llk˛˛¬{{tuztŁśĄ„„tllŁśĄ¦§¨Ś”•|„…‹’Š|‚ztzl‹’Š‹…’lri””‹„„”“›{zmŚ”•””‹{tt{tt|Šutztltsl››”Š}“““‘Ś…{||{zm{||„„Š{{{u{|uzt{{tVTLf]c|‚z‹‹‹{||„„d\\Ł››Ł››{zmdkV[[Tddc‹’Š}Š‚|u[[T„„{{„„Š{ttsle||f]c{u{„„”››š””Š}’ŚŚ{ttŚ”•‘Ś…””‹Ł››¤¤ť¤¤ť‹‹‹’ŚŚ“Ś”|‹‹„ś››tsl“““‹„„‹‹‹tt{ult‹…’zllddc’ŚŚ{tt||{{tu{{‹’Š”“›‚ut‚|u“Ś”Ś‹“tll{zm„Š„|||‚wl“““‚v{šŤŚyl„›”›””‹‘Ś…Š}{ttsleŠ}{{t{tt›”›„„{ttlddekd‹‹‹‚ut„Š}””‹””‹{{tµ¶·“““¦§¨’ŚŚ”››„Š„redkd\VTLsleldd{||‚|u{ttŠŠ}|‚z{tt‘…„„„lldlriztl››”‹„„{{tVZ[‹’Štts]bZ{||Š}‹„‹tllŠ}{zm{tt{||””‹‹‹‹‹„„‹„„ztlfkk“Ś”rg]Ś”•™š¤tt{mtttsl”“›ddc…‹‹MRKlkslri}tlltts{{“Ś”{{Š}|Ś”•{||ekduztttsedk””‹lrilksŚ‹“|lri[TT{{{u{||kd\{tttlltts{{t‹’Š””‹:97*)(Ł››¦§¨””‹’…‹Ł››||Ł››ŠŠ}‘}››”””‹Ł››˛¬µ˛¬µ˛««ŁśĄ˛¬µ™š¤Ł››”››||““““““µ¶·„„Š”š”¦§¨››”››”Š}š””}”š”„Š}¦§¨}Ł››‹‹„Š}‚|u‹‹‹|‚z‹’Š[[Tkk]|‚z¦§¨“Ś”|‚z„Š}¨©´”š”{zm|„…›˘›Ł››‹„‹‚|uztl‹‹„‹„„””‹””‹Ś‹“‚u|‚z‹‹‹{||f]cttstll{{t‹’Škd\„„“Ś”’ŚŚtzl„„Šf]c\UZ‘Ś…{{t‚ut{tt|‚zekd}ttsz‚lrg]‹…’’…‹‚u||››”‹’Š””‹}‹„„‹„„{||‚utf]c‹„„{||lddkd\tll¦§¨sle‹’Š|‚z||{||„„Š„„{ttttsŠŠ}š””||„„Š‹‹‹Łť˛’ŚŚŚ”•ś››|{u{|‚z|‚z]cdtts{{‹„„„„Š|„„||tts’ŚŚ‹„„””‹‹’Štts”“›ult{||””‹ztl‚wl””‹zll„Š}{{t‹‹„ś¤¦Ł››„„\UZ””‹‹’Š{{t{{tš””››”‚n{||…‹‹‚wl“Ś”ldd‘Ś…{zm{u{mwzllbVUkd\lddslef]c[[Tredtlluzt{zm\[b‹„‹””‹j]\„„VTL|‚z{{tVTLlri{tt‘…„\UZek]…‹‹lld{{‹’Štt{ddclddUMRlld…„’ztl“““tt{ddcleklddf]c‚v{lksVZTf]ccbV{{lldddc{{ult‚v‚‹‹‹lksfkk…‹‹|‚zuztś¤¦lld\[[mtt{||ldd|‚ztt{}llklddztf‹„„tts|lriVTL’ŚŚ:97*)(›”›¨©´«˛«˛««’…‹Š}|˛˛¬˛¬µ‹‹„‘Ś…””‹¦§¨ŁśĄ˛««˛««ŁśĄµ¶·¨©´‹‹‹Š}„Š„‹‹„’…‹™š¤„Š„”››“Ś”››”ŠŠ}µ¶·›”›Š~‹‹’Š¦§¨¨©´‹„‹‹„‹ŠŠ}””‹‚u||dc\llk||{{tiq]…„’|‚zuzt‹‹„tzlŚ‹“{{t‹‹‹‚|u‹„‹„Š}‘…„’…‹sleŠ}¤¤ť˛˛¬““““Ś”“““‹’Šttstlltsluzttzl”››d\\{ttlddrfkkd\{{tdc\{tt‚ut‹„„u{{tllrg]UTStll„Š„sleš””ult„„Šred‚|uš””‹’Š‹’Š{{tś››|„…[[Trg]j]\tllldd{{ttsl{ttzll‚|u›˘›„Š„“Ś”‹‹‹ddclld‘Ś…“““’ŚŚ„„¦§¨{{Ś‹“…„’{||{||””‹lekŚ”•‹’Š{{lldultmtt{ttdc\„Š„‘Ś…{ttŠ}{ttuzt””‹ś¤¦Ł››‘…„‘Ś…{u{}ztl’ŚŚ””‹Ł››“““ŠŠ}“Ś”tsl„Š„ulttts|‚z„Š„ult‚utrg]{{t‚|uVTLSKJkd\|„…||{{tztlttsd\\ztltll””‹zllkd\f]clld[TT\UZultVTLsrelri]bZ{ttd\\:97{ttekd‚ntt{ztljV[{u{VTL[[Tdc\‹‹‹|lek|„…”››{ttultŚ‹“lddŚ‹“{||lldŠ}|UMRbVU}mttFD;llkuztf]clri{{ult{tt[[TVZ[nv‚\[b]cd‹’Štsllkstsluztf]clddd\\lkstsllek}bVUzll||tll|ddcb[U‘Ś…:97*)(Ł››¦§¨‹‹„Ł››ŁśĄ¤¤ť»ÂÇś¤¦–˘‹¤¤ť¤¤ť¤¤ť˛««‘Ś…šŤŚ“““ś¤¦¦§¨”š”‚u{zmzll}‹„‹|{||VZTś›››˘›¨©´ŚŚš“““””‹Ł››‹‹‹|“Ś”‘Ś…sle‹‹„ult”š”tzl‚ut|u{{‹‹‹|„…]bZ[TT{{‚ukd\Ś”•””‹sletsl‘…„“““{zmŠŠ}”š”””‹‹‹„””‹„Š„{{ttts}ś››Ś”•{|||ddc{||SKJzllslesreUUY‹„‹‚|u|UTS{ttVTLJHF|{u{{{taWMmtttsl{u{Š}|ś››””‹‹‹‹…„’tzldc\uzt‚ut{||}“Ś”‘Ś…š””‹‹‹‹„‹{tt“““¦§¨}Šult‚ut„Š„}|„…‹„„™š¤””‹|„…lek”“›‹„‹Ś”•||’ŚŚ“““{{llk‹‹„\[[uzttlllldlks‚|u’ŚŚ‹’Š””‹|‚z‹’Š||“““”“›}Š}|‚|u””‹‹‹„tll}‚u””‹||‚z}VTL‹‹„„‰vek]tll{zmaWMlldVTLkk]rg]\[[‹’Š‹‹‹‹„„{tttts{u{‚|u{{tult||[TTultbVUSKJŠ}dc\dc\‹„‹{||ldd[TTlrildddc\‚|u‹‹„||‚v{™š¤‹‹‹tzl{{t{{t‚utll„„{{t¦§¨{ttŚ‹“Š}‚v{„Š„™š¤‹’Š‹„„Š~‹}edkVZ[\UZVZTfkklldUUY{|||‚z]cdekd|„…|„…mttlekVZTlksuzt|„…u{{lek‹‹„„„f]clddultsleult||ztl‹‹„{ttsre‹„„JHF74,}Ł››””‹Ł››Ł››Ł››››”››”››”Ł››‘}™‹†››”‘Ś…˛««š””›”›‹’Š‹‹‹””‹””‹‹‹„||”››„„¦§¨„„Šµ¶·¦§¨‚v{ś¤¦{{™š¤””‹¨©´{{t¨©´‹‹‹tsl¦§¨||‹‹„™š¤|{tttslddcMRKuztsre\UZ‹’Š‹„„‹’Š||‹„„|‘…„‘…„Š}””‹‘Ś…ztl”“›‚u„„lldVTL||{u{}Š‹‹„lddf]c{{rfkŠ~‹rr]››”}‚v{||Š}||Ł››tzl‹’Š‹‹‹’ŚŚ”“›‹„„…‹‹…‹‹“Ś”””‹’ŚŚ|‚z{||“Ś”lks|{{‚|u„„||”“›‘}z‘Ś…š””|””‹{{t|“Ś”tt{›”›‹‹„‚ut“““{tt’ŚŚ¦§¨›”›{{…„’|‚z…‹‹“Ś”’ŚŚ‹„‹|‚z||‹‹„tt{mtt|””‹Ś‹“‚|u‹‹„{{tztl|””‹‹’Š|“Ś”lek}lri”š”rg]|‚z{ttddc‹„„‚wl|‚z”“›ś¤¦{ttŠŠ}dc\‚|uŠŠ}‚wlcbVkd\ztld\\tzl{{t‹‹„lldkd\tllllk››”ŁśĄ‹„„{ttsred\\””‹llklekŠ}redkd\SKJekd\[[dc\\[[UTSsre\[b{{dc\rfkult›˘›„Š„›˘›Ś”•””‹ult}llk}UMR\[[lldddc{||{u{|{{t{ttulttll›”›}Š|„…ŁśĄ|‚z|„…tt{}™š¤„Š„MRK{{mtt{||tsl{||mtt|„…tts}Ś‹“{{UMRSKJred‹„„‹‹‹|lddd\\tts‚u””‹>B9:97‹„„Š}|‘}‘}Š}|ŁśĄ¤¤ť‚|u–˘‹Ł››˛˛¬ŁśĄ‹’ŠŁ››Ł››“““ś¤¦„„‹‹‹”š”‹’Š’ŚŚ””‹”š”””‹¦§¨ŁśĄŁśĄ”“›””‹||“““‚u””‹“““sre¦§¨‚|u{||Š}tlllri‹‹„‘…„lritslult„„Šmtt|‚z„„Š‚|u‹„‹tsltslrfk„„””‹{tt„Š}‹„‹|„Š}¦§¨kd\[[T|‚zkk]””‹„„ŠŠŠ}‹‹„redUMRbVUrfk||VTL‹‹‹ldd{tt‹„‹‹„„‚ut‚|u‚ut[[TVTLb[UztlŁ››f]clks‹„„‚utŠ}“““|‚z„„Šred‚|ulri””‹tsllek„„Ś‹“zll”“›‹’Š‹„„||‚z{tt}…‹‹‹„„||Ś‹“‹„„‹„„‹’Š™š¤|„…Ś”•›˘›ekd“““Š}|tts|„…”š”|„…tslŠ~‹Ś‹“ś¤¦{u{sle{{yle’ŚŚ„„‚utŠ}|f]ctts‹„‹‹„‹lri››”‹„„–˘‹š””‹‹„‹‹„‹„„›˘›UTSd\\lldtsltzl””‹llk˘—Ť{yfsle‚wltsltll|„„lek‚|u‹uŠiWUsletts„„sle„„lek||ult‹…’ult|„…VTLztlkk]Š}{||]bZ‚ulddtt{tts{zmbVU}f]c„„Šś››|„…””‹Ś”•ttstsl„„{u{‹’Š„„ŠŠ}lektll|‚zaWMŁ››lks{{{||‹…’¦§¨Ś‹“š””…‹‹}fkk|„…\[[VZ[ult\[bttsekdf]c“““{{{||‹„‹„Š„„„srett{j]\‚|uj]\lddlddddc‹‹‹lri””‹JHF-1+“Ś”™‹†sleŁ››››”‘…„‰v‚|u˘—Ť‘}¤¤ť¤¤ť””‹{zm¨©´˛¬µŁśĄ””‹¦§¨|””‹ztf„Š}{tt”›››˘›„Š„Ł››‹’Šš””¨©´“Ś”””‹Ś‹“[TT“~“Ś”‹’Š‹„„‚|utll[[Tr]Zrfkult{||ś¤¦„„Šllk”š”¦§¨||UMR“Ś”}Š}ŠŠ}tllbVZ›”›{zm„Š}šŤŚtsl‹‹„kk]uzttslš””UTSmw¤¤ť\UZ{{SKJ’ŚŚkd\ztfdc\‹‹‹{u{‚|u‚ut||Š}“Ś”lld{tt|‚zŠ}|’ŚŚzll{{t||’ŚŚ‘…„‘Ś…ekd\UZ{{rg]{zmjcVlldult||ś››››”|‹‹„‹‹‹„Š„lri“““›”›‹‹‹ŁśĄ‹„‹||{zmu{{tsltt{llkmttUUY…‹‹“Ś”redu{{llk|‚z…‹‹“““uzt›”›‹’Š“Ś”{||Š}|dc\}’…‹Ł››||lksf]credult””‹{{tsle¦§¨{ttś¤¦“““’ŚŚrr]tt{‹…’„„‘Ś…|””‹|||{zm{{t‘Ś…‚wltllztl|j]\VTL|Š}‰vd\\ult‹‹„‹‹„„„tllultf]cuztlri{||[[Tztlf]c‹„‹‚utek]ekduzt{{ztltllult„„Š¦§¨|lri””‹›˘›tt{ztl”“›lek{{t|‚z‹„„”››{tt“““Š}“Ś”{{Ś‹“”“›{{\[[|„…“Ś”|lks…‹’|„……‹‹u{{{{VZTllkztlult{{t{{„„{{tts|tsl}lddbVUbVU‹„„tts{{tuzttsl‰vMRK*)(‚wl‘…„{ttŁ››››”””‹¤¤ťš””˘—Ť’ŚŚ‹‹‹Š}µ¶·¦§¨¦§¨˛««˛««“““ś››‘Ś…””‹””‹Š}Ś”•‹‹„„„‹„„||||{{””‹››”“Ś”¦§¨}ŁśĄ|‹’Šlj¦§¨“Ś”sle‚utyfl||…‹’‹„‹{{„Š„¦§¨…‹‹‹„‹ŠŠ}Š}‹„„Š}|„…Š}‹‹‹˛««››”¤¤ťultuztztl\[[‚v‚””‹“Ś”””‹¦§¨„Š„‹„„lldddc{tt‚ut}Štts„„b[UŁ››lksttsŁ››bVUUMRj]\zllztfiWU}d\\Š}|‚utult››”|„„ldd‹’ŠtslSKJlddred||„„ś››””‹i\VŠ}|‚z‹‹‹‚v{‹‹‹„„}“Ś”ś¤¦‹„„“““„„„„lldedktsl„„‚|uzllddclksztl‹…’›˘›‹’Š|Š}{u{“Ś”llk„Š„¦§¨kd\“~llktsltts}d\\{{tlld‘Ś…llk||‹‹‹||‚v{‚|u¦§¨”š”Ł››Ł››{{‹„‹¤¤ť‹’Š|‹‹‹sre””‹ś¤¦kd\‹’Š{u{¦§¨”“›lek||uzt‹’Š{{tddcttsfkk‚v{}„„UTS{{t||‘Ś…Š~‹”“›…‹‹„Š„‹‹„uzt{||‘}kd\“Ś”kd\›”›rg]lritzl“““„Š„uztŚ‹“›”›”“›z‚l””‹›˘›tts”“›‹„„{tttllŚ”•|„…{{||f]cddc‚utŚ‹“„„…‹’|„…lrif]cŚ”•}„„Šddcuztu{{tts[TTllk“Ś”{tt{u{bVU’ŚŚlek{ttldd””‹‹‹„{{t¦§¨JHF*)(zll‚wl‹„„’ŚŚ’ŚŚĂĽż¤¤ť””‹ÄÂż’ŚŚ‚wlŠ}|‘…„¦§¨Ł››‹„‹Ł››¦§¨””‹””‹‹‹„‘Ś…Š}‹‹‹››”‹’Š„Š„“Ś”ś››¦§¨¨©´ŁśĄ¨©´¦§¨‹…’}›”›““““Ś”””‹‘…„i\Vtslzll””‹llk||tllekdlri‹’Š}ś››”››“Ś”‚u‹„„‹„„‹„„«˛«¦§¨{{tslelldlrilldaWM[[Tj]\›”›ŠŠ}|‚z„„dc\ult“Ś”‚utSKJ\[[VTLtllztl‚v{‹‹‹lekUMR{||\UZzll‚usledc\{{{u{‚ut{tt‚|u„„llkd\\|{ttŠ}{tt‹„„||’ŚŚ|‘…„””‹‹„„””‹tts‹„„‹„‹„„fkk‚v{„„›”›tll‹„‹leklks„„Š|‚z|„…||’ŚŚult{{ult{||„„Ś”•{ttlld}ŠlddUTStsl‹„„Š}}{ttztff]cUTSd\\lri|tsllldVTL[[Tsre{u{lldtslddc{ttŠ}slekd\llk‚u‹’Š””‹„Š}{ttś¤¦{{t“““}tsl„Š}‰|vkk]‹‹‹llkuztult}ultldd“Ś”{ttttstts{zmtsl||’ŚŚś¤¦„„|lkstzllks‹‹‹lekdc\‚utsleVTLlek|{||b[U{u{}|„…‹’Šsle{||tll{{|‰|vtll{{†~‘“““tslldd{tt‹‹‹{{\[[mtt|„…lks“Ś”„Š„›”›™š¤„„Š|‚z{{\[[‹„‹…‹‹‘Ś…“Ś”š””slered{u{‹‹„„„„Š„„Š„|Ł››:97*)(’ŚŚšŤŚšŤŚš””Ł››¤¤ť‹‹„ĽŔŻ¤¤ť˛˛¬ś››Ł››˛««Ł››˛¬µ¨©´˛˛¬µ¶·›˘›””‹š””Š}ŠŠ}“““¦§¨¦§¨}Ł››Ł››ŁśĄŠ}Ł››‹„‹””‹ult{tt}{{tzll‹‹„›”›‘}slezllUTSVTLtsltts{||‹‹„‹’Šś››{u{„„¦§¨‘Ś…Ś”•{tt¦§¨¦§¨„Š}””‹‚uttsl{||‚|u‚|uUTSredrfkuztdc\VTL}{ttŁśĄ””‹VTL}d\\›”›uztyfd‚|udc\Šut||Š}|f]c{tt|ttsUTS’ŚŚ‚u{||kd\Ś‹“|„„‹„„sleŠ}‹‹‹{tt‹„‹ś››Š}šŤŚ’ŚŚ||‹‹„‹’Š||’ŚŚ…‹‹Š}}lektsldc\{zmtt{{{tt{|{{||“““™š¤bVZ„„”››{||‹‹‹{tttts”“›d\\[TT[[T‹„„‹‹„ulttllŠ~‹tll{u{||Š}VTL|››”ztl…‹‹{||aWMbVUVTLSKJcbVlek[[TaWMMRKrg]››”{||””‹ŠŠ}‹„„d\\‚v{Š}‹„„{tt{{tVTL‚u„Š„¦§¨b[U{tt\UZ{{tUTSkd\{||ult{{ttslb[Uult‹„‹{{t™š¤|„…{{tbVUŠ}lek\UZ‹„‹zll›˘›ŁśĄ|tll]bZ‹„‹‹‹‹{{tŚ”•š””Ś‹“„„Ś‹“””‹„„¦§¨„„Š{u{tts|‚z}ttsf]c{{\[[\[b]cd]cd\[b…‹‹{u{{{{{uzt|„…tslu{{‹‹‹{{’ŚŚ“Ś”‚utztlkd\ztllld‹‹„‹‹„[[T¦§¨D;9:97””‹Ł››‚wl™…‹„„””‹¦§¨””‹¤¤ť“““¦§¨¤¤ť˛««Ł››˛««Ł››¦§¨¦§¨””‹””‹™‹†’ŚŚ„„Š|””‹¦§¨Ś”•ŁśĄ˛««¨©´Ł››¦§¨Ł››’ŚŚ‚utult{tt‹’ŠŁ››‘}›”›‚|u››”››”Ś”•lld‚|ubVZuzt„Š}{yfŠ}lriŁ››}Š}„„tts‚uš””|‘Ś…|ztl¦§¨‹‹„‚|usre“Ś”lddkk]kd\[[T[[T{tt‚|ub[Ured}ult‚v{|„…Š}|||Ś”•f]cr]Zult’ŚŚcbVjcV{||‹‹„ultred‹‹‹{{tlldrfklrillk|‚z‹„„‹‹‹“Ś”rfk„„„Š}Š}|¦§¨|||„Š}tll‹‹‹u{{’ŚŚ‹„„edkś››|‚zlld|„…‚utddcmtt…‹‹||Š~‹jV[edkzll“Ś”lri…‹‹‹’Šu{{tt{‹‹„sleuzt¤¤ť‚|uultš””{u{‹‹‹’ŚŚrg]¤¤ťmtt|‚z‚u{tt[TTbVUb[U[TT3+*kd\kd\ek]cbVlld‘}ztl‹„„‘}{tt|‚utŚ‹“tsl””‹“Ś”VTLtsl‚|u|‚zŚ”•{tt‚v{“““\[[‹„‹dc\b[Uddcb[Ub[U””‹lld\[[{u{Ł››lldultllddc\tsllekllkŠ~‹sleuztlritsl””‹u{{ultldd„„„‰vŠ}Š}|Š}|Ś”•››”ŁśĄ{u{‹„‹f]cllk›˘›}lddlekmttmttdc\tt{mttedktll“Ś”|„…}lri\[[{{tuztŚ‹“‚utslezll‹„„’ŚŚkd\red{ttdc\uztlldµ¶·UMR:97‘}ljljŠ}Š}sle‹„„‘}›˘›‘Ś…””‹Ł››Ł››˛¬µµ¶·šŤŚ¦§¨¦§¨””‹””‹›˘›d\\|‚ztsltzl‹‹‹”“›““““““‹„„ŁśĄŁ››””‹‚|u‰v|””‹¦§¨|”š”‘Ś…„„Šztl‹‹„tts‚v{“““””‹{{”“›„„uzt{{lld{tt˛¬µ””‹dc\{{t˛««“Ś”””‹|”š”››”lldrfk{||||Š}|„„‚|ulldlldbVU{tt‚v{yleek]{ttddc||]bZtsl‹‹„‹„‹“Ś”{zmldd‚utdc\aWMddcttsredš””tll››”{{tzll{{tldd‚ut‘Ś…‹‹„Ł››b[U„Š}„„‹‹„‹‹‹uzt‘}„Š„{ttsle\[[||llktts‹„„{||‹’Šlri…„’„„fkk|„…rg]ult‚|ullk{||llk„„|„…‹‹‹|‚ztll„Š„kd\llk¤¤ť””‹ŁśĄ’ŚŚuzt‘…„Ś”•f]c{{ttsl‹’Šsle|‚ztllultVTLj]\{ttrfk‚|u“““‹’Šb[U‰v“““šŤŚVTL‚|ulld{{t‹„„dc\‹‹‹|uzttslsledkV‹‹„‚u|llk{tt‚v{tsl’ŚŚrg]lldVTLlri‚v‚tts¦§¨””‹‹‹„llkb[Ullkttsrfk{u{›”›Ł››llk‹‹„”››|‚z|{{d\\ldd”š”‚|u’ŚŚ‘…„”“›lri‚u‹‹‹ultf]cldd|„…tt{ddctt{{{edklri\[bu{{ultd\\lksek]lkslri\[[{tt„„}‹„‹Š}|tlllddi\Vlri‚wlj]\||tzl¤¤ťVTLJHF‚wl‰v“~Š}|‘…„””‹µ¶·ŁśĄš””¦§¨˛˛¬˛««›”›ŁśĄÂľĆ˛««˛««˛¬µ‘…„‹„„””‹tts„Š}›˘›‹‹„›˘›‹‹‹¦§¨¦§¨ŁśĄ¦§¨Ł››””‹ś¤¦˘—ŤŠ}’ŚŚ›˘›››”‹„„ttsldd‘Ś…„Š„tll{{‚ut“““ult…‹‹„Š„‹„„lrilek‚uŁ››{{t||’ŚŚš””””‹ttslriultttsŠ}ŁśĄ””‹’ŚŚ‹„„‚u›˘›kk]SKJ“““j]\‘Ś…ldd„„Š[TT}|‚ztt{||zllbVUVTLbVZ{tt{tt“““{{t]bZyleš””“Ś”||„„Šd\\|„…{{t‹‹‹‚|u‘Ś…Š}””‹‹’Š‹„„sletsl‹„„„Š„tll””‹tll|„…ztllek{u{{tt{{tś¤¦Ś‹“ttsttsu{{ult›”›ttstllulttt{ddc…‹‹llkulttlltt{|””‹ulttsl[TTtllś››tsl||›”›š””‹‹„ultztlkd\‚|ullk‘Ś…‘Ś…kk]”››‘…„UMR„Š„„Š}”š”srezll‚|uyleŠ}SKJllk{ttsreVTL‚uuzt{{tŁ››ztl”š”„„„Š„‹‹‹\[[{tt{ttŠ}|j]\{tt|sletllzll}‹„„„Š}LKRuzt‚utŚ‹“ljedk‚v{‚|uttslridc\””‹‚|u”“›{tt‚|utsl‹’Š”“›¦§¨‹„‹tslŠ~‹lksttsf]cztl]cd[TTtzl{||mtt{{u{{‹’ŠUUY]cdkd\uzt|””‹lriUTS{||d\\{tt{u{‹„„yleyleyleJHFkd\red{{t{{tŠ}¤¤ťJHF*)( ŤŤ””‹Ł››‚wl’ŚŚ“““¦§¨›˘›˘—Ť˛««ĂĽż˛¬µ˛««ŁśĄŁśĄĂĽż˛¬µ””‹||“Ś””š”””‹¦§¨¤¤ť””‹›˘›“Ś”””‹›˘›|Ś”•Š}|¤¤ťult“Ś”š””””‹‹‹„ś››|rfk””‹˛««‹„„jcV{{t“Ś”‹‹‹ldd””‹”š”„„{||„„|‚z’ŚŚ„„ult‹‹‹j]\””‹lldldd{{tcbV{tt„„Š„Š„‚wl‹„„””‹{{tcbVSKJš””‚|ukd\j]\lld’ŚŚ{ttś››tll}™…kd\tsl‚ut¤¤ťtyg””‹|‚zdc\‚uttll}šŤŚtll{{t‹’Šś¤¦„„’ŚŚŠ}f]csle‹„„uztŠ}||rg]b[U{u{{u{lld{tt{tttts{|||„Š„„Š„}Š‹‹‹|“““ldd›”›{u{u{{””‹“““„Š„Ś”•tlllekŚ”•ś››””‹{{„Š„”“›{tt‘…„|š””‚v{Š}|||ztl{{tsleVTL[[Tzll””‹ŠŠ}¦§¨ŁśĄ‘}z“Ś”›˘›¦§¨|’ŚŚŠ}|’ŚŚredtsldc\‹‹„]bZldd¤¤ť„„{||”››ek]mtt“““|„…rfkzllult}“Ś”‹„„kd\tslcbV„Š}edktll’ŚŚš””{ttuzt{{d\\VTLbVUlrib[Uldddc\dc\„Š}ŠŠ}¨©´¨©´‚|uztl””‹“Ś”¤¤ť”“›„„{tt{{tf]ctsl{tt|‚zmttVTLdc\|„…{{{{ś¤¦tt{ekdddc„„{{t{|||d\\uztlldtlltll||tllztlllkr]Z}Š}Š}kk]{{t˛˛¬FD;74,¤¤ť“~’‘~‘}Ł››¦§¨š””Ł››Ł››¤¤ťŁ››¤¤ť¦§¨˛¬µš””››”›”›ś››¦§¨ŁśĄ‹’ŠŁśĄ‹‹‹ś¤¦µ¶·””‹||‹‹„‚|u‹„„“““ś››{{t‹‹„›”›tsl‘}sre‹’Š‹‹„tts“Ś”‘}Ś‹“bVUddc™š¤Š}lek„„Š‘Ś…‹‹‹|„…||””‹‚|u„„Š„„››”™š¤””‹“Ś”‹„„{{ttslŁ››}|‚z‚|u‹…’˘Ź“‹‹‹[[Tj]\\[[tts‚|u|¦§¨mtt“Ś”ult‹’ŠbVUŠ}VTLcbV[TTŠ}rfkekd\[[uzt‹‹‹j]\MRKultrg]sle{{t‹’Š„„{tt{||’ŚŚtll||tts‹„„||‹‹„|‚zj]\yle“Ś”“““‹„‹||Ś”•“““„„|‚z¨©´™š¤|„…llk”›››”›“““|‚z{u{””‹¦§¨d\\“““|ult{||„„|‚z…‹‹„Š„}Š}|‹‹„[TT||‹‹„››”„„ztl{zmrg]d\\ekdztl‚wltsl}Ś‹“||’ŚŚ‹‹„™‹†Š}‚ut‹„‹™‹†Š}”“›‚utdc\Ł››kk]¤¤ť„Š}””‹{{t|||ultlekkk]{ttsleŠ}|yle||[[Tek]tzltllultult‚utb[UŚ‹“lri\[[bVZ‚wld\\””‹sleult„„ztl‹’Š’ŚŚ™š¤{u{}{zm‚uttll‘}¦§¨”“›™š¤„Š„„„‚|u|tsl{{tMRK‹‹‹„„‹‹„{||{||lri{||””‹lddekd“Ś”d\\f]cddc‹‹„{tt‘…„‘}{ttcbV‹‹‹‚|u{{tšŤŚ‚|u‚|u‹’Š¦§¨VTL-1+””‹‹„„‘}’…‹ŁśĄ¦§¨›˘›Ł››ś››Š}˘—ŤŁ››Ł››˛««ŁśĄ˛««””‹ŁśĄ¦§¨˘—Ť‹„‹„„uzt{{t››”µ¶·Ś”•‘}“Ś”Ś‹“”››“Ś”¦§¨„Š}‹‹‹‘Ś…llkdc\‚uztfsre’ŚŚrg]Ś‹“lddttsult‚urfkŠ}{{t{tt„„‘Ś…‹„„››”{||‹„„‚u¨©´š””{{šŤŚ‹‹„tzllddultsleŠ}‹„‹Š}ttsVTLrfkf]c‚v{|lri“Ś”{||{||lld‚|u’ŚŚztlkd\„„ztl‚|u[TTdc\‚|utsltllbVZ||Š}|tslsre|‚z¦§¨|cbVkk]{||{tt›˘›{||tsl„„‹‹„¤¤ť‚|u“““ŚŚštts{||{ttuzt\[[ŚŚš›˘›‹’Š|Ś”•lks™š¤ŁśĄ“Ś”ztl“Ś”“““‚|uekd‹„„{tt||f]cŠ}dc\{||lldmttrfkldd{ttŠ}‹‹„|zllŠ}|ztltll||‹„„{{t{tt{{t|“““‚|uš””kd\kk]™š¤™š¤tsl‰v|red””‹}‚|u””‹tll¦§¨ztlddclri|‚zŚŚš{||uztŠ}{ttzll“““‹‹„ztlddcllduzt{{ttll{ttŠ}|zllultldd{u{lldr]g{{sleztl{{uztŁ››tsl‚|uś¤¦™š¤{||‰|v|¨©´˛««{u{”“›“Ś”{u{{u{rfklri|‚zult‹’Š››”Ś”•“““tts}VZ[„„‹„‹|‚zlritts{|||‚z]bZtslsleš””ztlŠ}|‰|vdc\llkŠ}|‚ut››”{tt|‚z¦§¨[[T*)(tll‚wl‘…„}’ŚŚ››”“Ś”›”›¦§¨Ł››Ł››Ł››“Ś”ĂĽż˛««¦§¨ŁśĄŁ››ŁśĄ”››Ł››Š}ŠŠ}š””‹’ŠŚ‹“Š}Şł·’…‹‹„„””‹|””‹„„{ttŠ}ztf„Š„””‹¤¤ť{zm“““‚uultb[UlldVTLrg]ultzlltsltllultŁ››””‹slef]c}|‚z‹„„””‹ś››llk„„‘…„{{tŁśĄztlbVUŠ}tll\UZJHF[TTtllllk[TTldd{u{f]c{tt{||sleulti\VVTLVTLkd\ztlekdcbVcbV„„Ś‹“ttstlllddtll’ŚŚ‚ut‹’Š‹’ŠŠ}lddŠ}}‹„‹tts””‹š””šŤŚ‘Ś…ult||{tt|f]c{{t{{Š}{{|‚znv‚{u{‹‹‹‹’Š…„’›”›”“›„„ŠŚ‹“››”„Š„…‹‹||ult¨©´Ś”•{u{‹‹„|„Š}tts‹„‹|rg]{tt|jcVSKJjcV{{tf]cŁ››{zmtsl„„tzltll\UZzll||‘Ś…ŠŠ}ult‚v{‚|ušŤŚŠ}|‹‹„“““||}{||zllf]cdc\tsl{{‚|u|[[T‹‹„Š}’…‹…‹‹{||Š}|ek]‰‘~|„…slef]cmttzlltllbVZSKJ{||||{{“Ś”{{t‹„„{||„Š„”š”›˘›‹„„\UZ‚v{{tt¨©´””‹‹„„””‹lek‚utztl„„„„Š{ttŠ}VTLŠ}‹’Š„Š„‘…„{{t„„Šu{{ultult{ttŚ‹“„Š„“Ś”„Š„‹’Šuzt|‚z}‘…„{ttb[U‚|utllyle{tt‚ut‰vŠŠ}sre¦§¨D;9*)(Š}|š””“Ś”‰|v¦§¨ŠŠ}˛¬µ¤¤ť˛˛¬Ł››””‹¤¤ť›”›¦§¨šŤŚšŤŚ“~Ł››ś››…‹‹sre‹‹„Š}‘…„¦§¨›˘›šŤŚ”š”Š}|||‹‹„‹„„}”“›„Š„‹‹‹|z‚ltslŠ}‹„„””‹tt{‚v{‹‹„Š}VTLultult‘Ś…‹„„”››“““›”›‹„„tt{“““|›˘›‹’Šf]c‹‹„{||‹‹„kd\}srebVUbVUult{u{\[[sleultlld||b[U”“›“““Ś‹“„„tslbVUSKJFD;]bZSKJsrekd\[[Tlddd\\‹„„ztltzl„„”š”ttskk]sle‚ut‚|u{tt™š¤”››ś››“Ś”‘…„¦§¨‚v‚„„Ł››‹„‹‹„‹ztl‹„‹Ś”•™š¤|||‚z|‚zlksf]ctt{fkklksUMRŚ”•‹‹„Š}”››tslś››ś¤¦Ł››“Ś”{{‹‹‹”“›lldŚ”•›”›lek‚u||||lldsletslb[Uztfldd{tt‘Ś…Ś”•{{t{{tlldultcbV‚ut‚|u‚|ušŤŚŁ››ultŠ}j]\{tttts‰|vrg]tll{ttd\\„Š„uzt””‹{{tuztrg]bVZlddlddtts‚|u’…‹}MRK|„…tsl„„rfk‚v{UMRbVZ„„‹‹„}ŠŠ}|{{tll{tt„Š}ś››sre‹„„tts‹‹‹Ś‹““““Š}f]cŠutŠ}|{{tš””™š¤“““dc\‹‹‹dc\}||||„„Šddcf]cf]c‹‹‹{||“Ś”‘Ś…{{Ś”•‚ut„„ŠŠ}‹‹‹zlltllredj]\‚|utslj]\red||‹‹„ztl›˘›JHF*)(™š¤’‘~˛««‚ut‹„‹Ł››˛˛¬Ł››””‹””‹Ł››ĂĽż””‹“““ĂĽż””‹˛««›”›‹‹‹”“››˘›Ł››¦§¨š””””‹¤¤ťtslšŤŚ‹‹„“““||ztl‘Ś…uztš””Ś‹“””‹“““ztl‚utkd\rfk””‹ldd‹‹‹‹„‹’ŚŚ‹‹‹’ŚŚŁ››‚utJHFuzt{||””‹Ł››‹„„›”›””‹{||uztŚ‹“”››tzlŁśĄ{{t{{lrizllrg]{||lddlrijcVtts‚v{””‹ultf]cSKJ”“›tll{||Š}|{{t{tt[[TUTSVTLj]\llklddlkstts‚v‚š””Š}„„{||r]Zekdddc‹‹„””‹„„|‹„‹||ztl’…‹{||||Š}j]\{tt™š¤llkuzt{{’ŚŚ„„Š|„…u{{{||{{lksedk{u{”š”„„ŚŚštsl|‚z|‚ztts“Ś”¦§¨“Ś”lks{{tkd\lksttsedk{tt{u{{{tultllddc\redred‚ut{tt””‹tts¦§¨||ttstllkd\yfd””‹zllŁ››‚|uŚ‹“ultdc\d\\””‹‹„„‹„„{tt{u{Š}„Š„ldd{{ttts‹„‹”››‰v|lddllk{ttŠ}‹‹„‚|usre{||tsllddlek‚|uUMRultbVZtts[[T{u{||tsl|tll„„“Ś”‹‹„’ŚŚ‹„„ult„„||š””ultbVU™š¤{{t‹„‹Ś”•d\\[TT|„…tzlšŤŚ”š”fkkŠ}sre™š¤Ś‹“{||““““““lri‚|uldd…‹‹{||‹‹‹{||||Š}|{u{‚wl{zmtlld\\‚ut‚wl‰v|rg]rg]¤¤ťFD;74,””‹‘}zŁ››j]\’ŚŚ¤¤ťĂĽżŁśĄ˛««™‹†˛¬µ‹„„ŁśĄś››””‹Ł››šŤŚ|‚z‹„„””‹‰vŠ}””‹¤¤ť¦§¨µ¶·››”’ŚŚ||{{tsle””‹››”š””’ŚŚllk‹‹„{{t›˘›||{tt‹‹„tt{{tttts{zmztl||ŁśĄtll||‹„„”“›ś››‹’Š}||‹‹‹’ŚŚ|‚zlddtts[[T‹‹‹{{t„„tzlkd\{tt{u{[TTd\\[TT‹„‹}Š{tt{{tŚ‹“ddc™š¤„„[TTd\\ekdrg]kk]bVZllkldd[TTtzllritllš””‹‹„“Ś”[[Td\\b[U{{t{tt›˘›{{t‹‹„‹„‹ttsŠ}|Š}}‹„„|‹„„{u{‹’Š||“Ś”„„u{{{{t„„llk„„tt{{{…‹‹|„…“Ś””››„Š„}tts„Š„„Š}|„„‚v‚””‹tt{Š}|{u{tll{u{{u{}||›”›››”llkdc\red‘}zf]c}’ŚŚ{||‹’Š‚ut{{tUTS‚|utllsre‹‹‹‘Ś…ylettsŠ}‘Ś…|yfd{{t||sleyfl}Ś‹“{{tŚ”•‚ut‹‹„}{{||‚v{{u{Š}“Ś”‚v{„Š„‹‹‹VTL‚v‚{{””‹edktllf]c‹‹„[[T‹„‹››”slelddllk””‹››”{zm‹„„“Ś”””‹u{{¦§¨””‹ultztlrg]{zm{{t|„…„„Štll{{t|„…˛««…‹‹]bZ‹‹‹…‹‹tt{”“›|‚zlek|„…Ś”•ŠŠ}ddclekd\\kd\llkddc{tt‹„„Š}|uztldd\UZf]cŠ}|‘Ś…‰v‹„„””‹>B93+*||‘…„Ł››Ł››”“›µ¶·ĂĽżš””””‹‘}¤¤ť¦§¨Ł››”“›˛««š””Şł·Š}||‚z¤¤ť›˘›Ł››¦§¨‹‹„”“›””‹¦§¨¦§¨ś¤¦tt{‚u‹„„‰‘~’ŚŚ‘…„’ŚŚ‘Ś…‹‹‹››”””‹lld{ttkd\tts‘…„{ttlldj]\tll’ŚŚŁ››„„‚v{f]c‹„„tsl{tt‹„„„„{ttrg]ddctll|šŤŚ”“›„„”š”Š}|’ŚŚ›”›llkiWU]bZtlluztś¤¦tsl{{t{||ultlekdc\Š}|JHF{|||tts„„rfktllJHF{||‹‹‹‚v{srellkddckd\b[Utslslekk]d\\{|||lekyleztl’…‹Š}ddctts›”›„Š}Ś”•‹‹‹‹„„u{{uzt|‚z„„Ś”•‹„‹ś¤¦…„’…‹’™š¤uztddc\[[|‚z|„Š„‹„„}\[bf]clks“Ś”ldd||}ś¤¦}ŠŚ‹“…‹‹ś¤¦“Ś”‘Ś…„Š}ś››|j]\‹‹‹lld””‹i\V{{tzllkd\ldd„Š}|i\V||llktlllld{||llkŠ}|b[UbVU‚utbVZ‹„‹{ttsre‹’Šttszll}ult‹„‹||{ttŠŠ}lek{{t}[[Tddcttstlledktll{{|¦§¨Ś‹“Š}srecbV{{tsre™š¤u{{kk]‘Ś…„„Ś”•Ł››ŁśĄtll‰|vzll‚|u||||ult{tt|‹‹‹‹’Š„Š„‹’Šµ¶·{||{||Ś‹“Ś”•“““‚n{u{Š}ult|tsld\\rfk„Š„Š}|{zm‹„„tll{zmŠ}|zllyleztlkd\kd\””‹:97*)(„„‹„„Š}¦§¨¤¤ť˛¬µŁ››ŁśĄš””˛¬µ ŤŤ¦§¨¦§¨ŁśĄŁ››’…‹šŤŚ›˘›‚u|””‹››”””‹Ł››«˛«¦§¨Ł››„„’ŚŚ‹‹„||’ŚŚztf{u{yfd‚ut”š”„„Š‹‹„Ł››{zm‹„„‚ulddšŤŚ‹‹‹tsl‚v{}ś››Š}…‹‹Š}’ŚŚllksle{{…‹‹„Š„|‚uldd„Š„ŠŠ}››”Ś”•‹‹„tzl‚|uddc„„lri|FD;d\\u{{]bZllkd\\rfklddlddsrezllSKJŠ}tsl|‚zsleVTLtsldc\|lddsleVTLzll‹‹„lld’…‹››”rg]sre‹‹‹ldd‹„„ultd\\{u{||‹„„{ttŚ‹“‚|uztl||‹„‹‹„‹mttllk|„…{{ś¤¦|„……‹’}Ś”•Ś‹“||ś¤¦ddcŚ‹“lriuzt‹‹„{ttlkslekUUY‹„‹}Š||‹„‹‹„„kk]ldddc\‹’Š}‹„„š””‘Ś…š””’…‹tllsrekd\bVZultlld‚v{bVZbVZś››lddlriŠ~‹kd\‚v‚Š}{{|Š}|f]c›”›lddultś››ldd{||llkd\\kk]‹„„{u{‹‹„‚v{|||||{||tsl{u{‹‹‹VTL{zmbVUddctts„„Š™š¤lriztltllUTSš”””“›””‹››”ulttsl…‹‹š…Ž¦§¨Ś‹“‰|vttsrg]||tsl‚v‚||›˘›kd\[[T„„Š‹’Š¦§¨Ł››Ł››ś¤¦Ś”•“Ś”‹‹‹{{’ŚŚtll„„„„|lek||{tt‰|v‚utztfzllsle‹„„||kd\‚wl‹‹„¤¤ť:97*)(ldd‹„‹Šutš””ś›››”›š””Ł››‘}˘Ź“‘}Ł››™š¤¦§¨Ł››µ¶·Ł››¦§¨{{t‚u¦§¨””‹‘Ś…‚ut¤¤ť”š”ś››‚|u||}Š¤¤ť””‹š””tts‚wl‚v{{{t“““‚|u‹‹„›˘›“Ś”‚|u‹„„’ŚŚ„Š„š””””‹“Ś”Š}|sle{||f]crfk“““{{t||}«˛«‹‹‹zll‘Ś…{||‹’Š¦§¨›˘›Ś”•d\\rg]redldd…‹‹ztlllkf]cŠ}rfk[[Ttll‘}tt{j]\VTLkk]lldslettslridc\||tll„Š}dc\‹„‹tyg|„…ztllddj]\mtt{zm‚ut””‹{{t‹’Šš””||f]c‚v{tlllddd\\’ŚŚ‹„„}Ś‹“„„›”›„„}„Š„ekdŚŚš|„……‹‹{{tt{“““„„Š|‚z{u{””‹‹’Š‹‹‹„Š„tlllek{||Š~‹{{“Ś”‹„‹™š¤{{tllkleksle›˘›””‹|‚z‹„„sle‚|u{ttllklriredkk]VZTzllredbVZ[[T{{t{tt}ultddc{tt|””‹Šutredrfk‘…„{u{„„{{{||ŠŠ}lriztl]bZ\[[‚ut‘Ś…“Ś”VTL|lld“Ś”lriddctsl{zm[[Tf]c„„Štsl{tt}š””””‹‹„„‚v{“Ś”„„ŠŁ››‘…„lek{||bVZ‹„‹‘Ś…™š¤Š}{u{ztl‹„„{{tš””kd\‹‹„uztuzt|‚z|š””{{“Ś”|„…|‚z…‹‹ś››tt{‚ut{||{{t{zm‹„‹lldlldd\\sletll‚|u‘…„zllldd‘…„Š}|yle|Š}>B9&&‹‹‹ŁśĄ“Ś”‹‹‹›”››”›››”ŁśĄ˘Ź“¦§¨Š~‹{tt“Ś”¦§¨ŁśĄ˛««Ł›››˘›ŠŠ}‘Ś…š””‚uŁ››ś¤¦«˛«{{tś››|||¦§¨‚ut¤¤ť””‹’ŚŚrr]redtsl{u{tslŁśĄŠŠ}ztl¤¤ťŚ”•’ŚŚ‹’ŠŠ}|’ŚŚ{{tŠ}{{t{||‹‹„zllš””sle“““‹„„Ś”•|tllŠ}‹‹‹Š}ult„„{tttllsle’ŚŚultllksretts‹‹‹„„Škd\\[[tllf]c‹„‹sreztl‹„„d\\tts”š”‹„‹””‹tllŠ}{{tVTLUTS[[Tlldztlkd\b[U{||ŠŠ}kk]ekduzt||kd\lddlkszll||“““{ttkd\‘Ś…‹’Šu{{“Ś”{{””‹ddcek]lks|„…”››…‹’mtt‹„‹Ś‹“|„…edk}‹‹‹|„…|‹‹‹š””{u{„„Š““““Ś”}ŁśĄddc{||‘Ś…||“Ś”””‹“~cbVkk]tllkd\“Ś”f]clrib[U‹‹‹||”››j]\ztf{||{u{{zm||ldd{tt|‹‹‹‚ud\\Š}||rfkŠ}‚|utslttsś››‹’Š{||tslkk]}‚ut‹‹„{ttredsrej]\‹‹„ttsUTS”š”tts’ŚŚ{u{{||ŁśĄ“Ś”‹„„¤¤ť{tt›”›’ŚŚ””‹Š~‹ultŠ}|uzttts™š¤zll{||‚|u“~{zmztl|ŁśĄzll””‹srelri}‹„„Ś”•¨©´¦§¨|‚zekd“““‹’Šekdslellkldd‚|u‚|u|tzl“Ś”‚|u{zm|‘Ś…{tt‘}‰|vredkk]i\V””‹D;9*)(››”ś¤¦””‹{{t“““ś››¦§¨“Ś”‰|vŁśĄ””‹‘…„Ł››ŁśĄŁśĄ“Ś”Ł››|„…‹‹„|¦§¨š””Š}„„‚u››”‹„„ś››‚|u‹„‹‚utztl‘}‹‹„„Š}yleb[U[[Tzllf]czllŠ~‹{ttult‹‹„””‹š””tsl{u{kd\{tt|‚zš””kd\”“›‹„„š””||Ś”•ŁśĄzll|›”›‹‹‹‹‹‹„„ultlldzll‰|vŠ}|sledkV‚v{dc\Ś”•dc\{tt||}“““lridc\kk]mttSKJ‹’Š{{trfk“““FD;sre{{ttll{{t|„…[TTb[UsleŠ}b[U{{tsre||tll{||‹’ŠtllŠ}Š~‹‚v{‹„‹||š”””š”‹‹„“““tt{lldultuztmtt{{{{{{lrilksŚ”•‹’Š|‚zŚ‹“{u{‹’Šuztult||}ś¤¦ttsldd‹„„lks”“›{u{‹‹„Ś‹“{{t‹„„‰vu{{{u{|Š}’…‹Ś”•‹’Šyle{||tsl{{ztlkd\d\\f]cuztŠ}tzl{||””‹›˘›ś¤¦””‹bVUrg]}‹‹„‰|v{tttslkd\ŠŠ}‹‹‹|||“Ś”{u{{ttrg]kd\[[Tlldtsl]bZult””‹››”{tt{{‹’Šsle›”›ztlztfš””„„š””””‹‹„„ztl‚ut}…‹‹||˛˛¬”“›‚|u“Ś”ztlsle“““Š}‹‹„lekś››|‚z‚wlŠŠ}tll‹‹‹„Š}ek]{||™š¤„Š„{||‹‹„„„tsl‘Ś…||{||{tt||JHFŠ}i\V‹„„ŠutztlŠ}|‹„„‚wlred˛˛¬FD;*)(„‰v““““““Ł››Ł››¦§¨Ł››Ł››šŤŚ‘…„˛¬µŁ››¤¤ť››”˛««˛¬µ˛¬µ¦§¨|‘}‚ut˘—Ť’ŚŚ’ŚŚ‹‹‹“~‚v‚”š”Ł››‹„„lddŁ››››”“Ś”‹‹„{tt‚ubVUš””{||tsltll{{t{||‹‹„„Š„‹‹„‹’ŠŚ‹“ult››”uzttts‚u’ŚŚŠ}|{tt’ŚŚ„„{||‹‹„‚|u’ŚŚ„Š}”š”””‹lri‹‹‹Š}sleldd›”›Š}FD;{||ult|‚z}lri{ttttsllkekdu{{lldb[Ulri‚utUTStygtll„Š„sreuztŠ}„Š„ztlsre[TTaWM|‚zztl‹‹„rfklld||ŠŠ}tll}Ł››‹„‹tllš””|||‚z„„‹„‹lks„„Šlrilek]cd|„…”“›|„……‹’lkstt{Ś”•Ś”•Ś‹“}fkkllk{ttultlek“Ś”„„Š„„sleŁ››{{“Ś”›”›ŁśĄ{{t{{t|‚z„Š}{u{‘Ś…ultrfktsltt{rg]lld‹‹‹‚utUTSzllyleslekk]{{t{||ldd„„„„““““““’ŚŚ‚utlekf]c{u{{u{r]g||||{|||Š}‹…’tllredtzlsleVTL|‚z{{ttllŚ”•‹‹„‹‹„„„ttsllk{tt‚v{ś››||””‹‹„„¦§¨‹„„Ł››Ł››¦§¨„„]bZ{{„‰v™š¤¤¤ť™š¤Ł››ulttsl||Š}tsl{{t‹‹„Š}ŠŠ}mttmtt“Ś”Ł››“““u{{‹’Š›”›””‹{{t‹‹‹lddlldtzlllk{ttj]\‹„„lddsle||‚|uztlsletslrg]¦§¨JHF*)(’‘~{{t‘}˛¬µŁśĄ˛««¦§¨“““Ł››šŤŚŁ››ŁśĄ¤¤ť‘…„˛¬µŁ››šŤŚ‹‹‹ŠŠ}‘Ś…‹‹„‚|uzll›”›››”Ł››Š}‘Ś…‹‹„{{t™š¤‹‹„Š}„„‰|v’…‹|‚zŠ}‹„„’ŚŚ„Š„{||srelri‹’Š‹’Š””‹„Š}„Š}}‚|u…‹‹‹‹„’ŚŚ‹‹„|‚z{{Š}{{t™š¤yfl””‹Š}sle„„Š””‹llkŚ‹“””‹r]ZbVZ“““““““Ś”“““„„„„Ś”•llkred{ttddc[[Tlld‹‹„Š}lldlld||tzltll[[Tddc{||rg]dc\b[Usreslesle‚nsreŠŠ}{{ttll|lritzl””‹˛¬µ‹„„zlltll}Ś”•tts{{ult„„Š]cd|‚z{{|„…Ś”•|„…u{{Ś”•…‹‹|„…mttlriultuzt{{ultf]clks\[bmtt›”›’ŚŚultŚŚš‹‹‹„„lddztldc\kk]‹‹‹{tt‚ut}‹„‹llkddc|””‹Ś‹“sre{tt‚utzllztl{{{u{kd\d\\„„¦§¨‚ut{u{¤¤ťš””‚utred{tt{||ztltllkk]\[[¤¤ťlriŠ}ultŠ}uzt‚wl|‚zmttŚ”•Š}tt{’…‹””‹ŁśĄmtt]bZ„Š„Š}ttsŠ}‘…„‘Ś…š””sre™š¤””‹µ¶·tts{u{{||¦§¨ś¤¦š””››”“Ś”“““„Š„‹„‹””‹‚v{ztl››”[[T‹‹‹‹„„‹‹‹‘}z‚l”››„„…‹’‹„„„Š}lldttscbVlldttssrerg]sle{{t‚utztl‚|ui\V‘…„zll‚utll””‹JHF!””‹”š”›”›ś››˛˛¬¦§¨˛¬µŁ››‘Ś…””‹š””‹„„Ł››’…‹ÂľĆŁśĄŁ››“Ś”‚uŁ››ś¤¦’ŚŚŠ}ŁśĄ{{t‘}{tt{{t„„Š‹’Š””‹’ŚŚś››””‹””‹’ŚŚttsztl””‹‚|u„„{||‹„„™š¤|lldŠ}tsldc\dc\kk]tsl›˘›|‚utŁ››|||„Š„‹„‹Š}””‹zllllk‹„‹ś››{u{{tt‹„„b[Uš””}Š{{ttsl{{„„ŠlribVZlritlllriVZTUTStlluztf]c„Š}„„‹‹‹mtttslkd\||‹‹‹‰vuztyle››”‹„„šŤŚ{zm{u{JHF||‹‹„|„…|“““{zm“Ś”¦§¨ś››|„…”››„Š}„Š„{{“““|„…|„…‹‹„…‹’lkslksekd“Ś”}‡’™š¤|„…„„Š„†™‹„‹fkk„Š„dc\ult‹‹‹tt{|lddd\\tsl”“›{u{ś¤¦tts‚|uVTL‚n}‹‹„ultŁ››f]cult|‚z‘Ś…„„lks{{||ztl‚|u{{t„Š„lekttsldd”š”Ś”•{||‹„„‘Ś…lddrfkbVZdc\{{t››”””‹u{{tll{{t{tt|ŠutŠ}||‚zŠ}|‚uŚ‹“{zmkd\u{{ztlrg]||llk›˘›‚u}‘Ś…’ŚŚŠ}|||Š}¤¤ťŁ››š””“Ś”{ttlri’…‹””‹‹„‹””‹{ttŠ}|˛««“““‹‹‹‹„„Š}„Š„{||‘Ś…sre“Ś”{{t‹‹‹|‚z””‹{{t||sletslŠ}{{t{{tztl[[T‚u[TTsleultb[UztlŠ}|{ttŠŠ}‚v{ult>B9*)(””‹¦§¨””‹||‹‹‹˛««˛««Ł››¦§¨¦§¨”š”¦§¨¤¤ť›˘›¤¤ť¦§¨¦§¨¤¤ť””‹””‹”››¤¤ť‚v{‹‹‹‚v{zll‹„„tts’…‹“Ś”“““””‹Ł››“Ś”’‘~‹„„dc\lekyle‚v{’ŚŚ{{‹‹‹{{ldd{||’ŚŚ{{td\\[[Tuztllk‚n””‹Ł››‘Ś…}‚uldd“Ś”ś››˘—Ťsle|‚zŁśĄ„„ztl„„‚u‚|u||tts|‚ztts‹‹‹ś¤¦{tt„Š„‹‹‹‚|u„„{{t[[T””‹\[[||‹‹„|ldd‹‹„Š}|tts|||Š}|slesle””‹jcV||kd\‹‹„tzltts|„„‚uŁ››‰|v’…‹“Ś”}‹’Š{tt{||‹‹„{{„Š„„„{{…‹‹}Ś”•{{tslmttmttŚ”•mttmttuztŚ‹“\[b\[[{||ldd„„lekultult’ŚŚ„„Š|„…rfkś¤¦‹„„{ttldd„„”š”ś››dc\}“Ś”tsllldttsldddc\[[Tlld‘Ś…‹„„lld{{t{{[[TbVUkd\tts„„Šldd‹’Šedkzll\UZd\\tll‹„„{||uzt””‹“““‹’Šlriultzll\UZ{{ttyg[TTMRK\[[llk\UZŚ‹“{ttult‹’Š¦§¨¦§¨‹„„‹‹„}‚wlkk]››”‘…„µ¶·’…‹™š¤‹…’||‹„„‹‹‹Ł››’ŚŚ’ŚŚŁ››™š¤ttsztl‘Ś…‹’Šdc\{{t‚ulld››”||tzl|‚zŚ”•{zmkd\|lriiq]lldtllsrebVU{zmztl‹‹„ztlŠ}‚|u””‹tllyleŠ}“““”š”D;9*)(‘Ś…‹‹„Ł››’ŚŚ›”›“Ś”˛««Ł››Ł››‘Ś…”“›ŠŠ}‚wl¦§¨µ¶·Ł››Ł››|«˛«””‹‹‹„‚wl||””‹kd\„Š„{{t{||{tt{{tŁ››¤¤ť‚u„Š„››”{||{{trfkrg]}””‹Š}{{t{u{‹’Š‹’Š‚wl|{tt{u{„Š„d\\|¤¤ťš””ŽŁµ¶·’ŚŚ‚u‹’Šztl‚u|„„ztl|SKJttssle“Ś”Š}bVU[[Tultllkult„„Šlks|„„llk‚|u[[Td\\tts|„…‚u{{t‚|u‚|u“Ś”„Š„‹‹‹‹’Š‚|u{{tf]c””‹’ŚŚ‘…„sle||{{tsleztl””‹lld‚v{ztl“Ś”””‹tsl”š”tll‹‹‹™š¤edklld{{{{|‚z…„’›˘›tt{…„’|„…mtt{{mttu{{{||‹„‹{{llduztd\\\UZlks[[Tf]clld{u{llkŚŚš{{tldd››”cbV”š”‹„„ultlddult||}dc\{{t{tt[TTUMR{ttb[UmwVTLrfk{u{VTLSKJ{tt{{t‚v{‚v‚red„Š„ldd[TTtsldc\|„…‹‹„„Š„””‹šŤŚ„„‚utsle‘}z„Š}ekdllkllk„„Šldd{||’ŚŚŁ››„„{{uzt””‹‹‹„Š}sre‹„‹Š}˛««˛˛¬Ł››Ł››‰|vlekllk’ŚŚ‹‹‹‹‹‹‹‹„Š}|zll‹„‹}’ŚŚ‹„„||‹„„tts|Ł››Ś”•›˘›{{t„Š}„Š„|„…ztl‹„‹b[U|{tt‘Ś…{||{{tlddtts‹‹‹‚|u‚utztl||’ŚŚ‚ut””‹||‚wlŠ}:97*)(››”¤¤ť˛««ŁśĄµ¶·š””””‹‘Ś…š””µ¶·µ¶·š””«˛«˛˛¬Ł››¦§¨˘Ź“||‚z‚u‹‹„¦§¨Ł›››”›‹‹„tll””‹‹‹„ś¤¦{||˘Ź“’ŚŚ¤¤ťtts‹‹„||‘Ś…f]cultttssleb[U’ŚŚ‚v‚‚u‹’Š“Ś”››”]bZ[TT|‚zddcb[U|‚z›”›‚|u‹„„‹„‹|tslŠ}kd\{zm‹‹‹‚v{Şł·||llk’ŚŚ›”›lddsleŠ}‹„„›˘›ult”“››”›ttsb[U}cbV„Š}‘Ś…Ś”•||‹‹„tlli\VVTLSKJkd\‹‹‹tll{{t‚|uyletll‚|u‘}‚|u‹„„tslsle{||b[U’…‹””‹{tt‘…„‹„„tsltsldc\{u{{ttlks‹‹„{{{||uzt{{›˘›mtt„„Š|„…Ś—Łmtt|‚z|„…|‚z›”›|„…{||llk{ttlek{||{{d\\bVZbVZ{u{Ł››|‚z}””‹‚|u„„„„z‚lult‹‹‹‹‹‹tlluztdc\redUTSztf›”›kk]SKJ|‹„‹lekkd\f]ctllVTLmttd\\tsl|”“›|‚|u\[[””‹“Ś”‹’Š“““Ł››‹‹‹kd\{||‹„„{tt‹„„sle‹„‹}ldd„„Š{{‚v{}ŠlksmtttllsleultztlultUMRldd””‹’…‹“““‚utllkuzt™š¤tts“Ś”ŁśĄ’ŚŚ¤¤ťŁśĄ„„‹„‹šŤŚzllsre‹‹‹|››”””‹Š}‚|uŠ}„Š„ŠŠ}“““lddztfsre‘Ś…||]bZred||‚u{{t‹„„‹„„‚wlztlztlšŤŚ||tsl‚wlJHF*)(Ł››¦§¨ĂÄƵ¶·¦§¨‹„„Ł››šŤŚ‘…„Ł››˛˛¬¸Áą””‹µ¶·ŁśĄš””Š}¦§¨””‹‚u‹‹„‰|v“Ś”“““›”›Ł››’ŚŚ‚|u}›”›‹„„yleŠŠ}„„’ŚŚ“““’…‹“Ś”Ł››„Š„|‚|uuzt‹„‹’ŚŚ””‹””‹››”mtt{{td\\|‚|uŚ‹“Ł››Š}{zm‚|u‹‹‹|‚|uŠ}|„„Š”š”{||f]csresre‘Ś…Š}ultllksle{||ultultuztlldd\\{u{VTL]bZ{{tsre“Ś”‘Ś…{zm}JHFSKJdc\dc\‚|uztf[[Ttllkd\‚|u””‹||Š}Š}lldkd\ztlj]\‹„‹‘…„{tt‘Ś…tsl{{t{ttttstllddclddlekmttu{{mttś¤¦|„…tt{{{ŚŚš{{ttslks“““˛¬µtt{Ś”•|„…”“›Š}‹…’“Ś”||ttsf]c}bVZylelri¤¤ť|‚zsre{||kk]’ŚŚ{||‚|uldd„Š„|‚zkd\rg]‘Ś…ś¤¦‰|vsreztl‹„‹rfk|Š}‹„‹rfk“““ztlkk]b[U‚|u}zlltlltllf]c”š”{{t‹‹‹„„Šrfkrg]rfk””‹uzt|‚z„Š}{u{leklektlllek||ttsmttŁ››‹’Š‚utŠ}|‚v‚zll’ŚŚ‚nllkŠ}|‹„„‹„‹ult™š¤f]c‹‹„””‹Š}|‘Ś…‹„‹lddšŤŚ‹‹‹Ł››tsl{u{‹’ŠŠ}””‹‹‹„Š}tll„Š„{||Š}‹„‹¤¤ť‚wlŠ}{{t[[Tdc\tll””‹tslŠ}‚|u||‚|u‘}{tt“~’ŚŚ‹„„ztlD;9*)(Ł›››˘›˛¬µ¦§¨˛««¦§¨˛««˛««Ł››’…‹µ¶·˛˛¬‹’Š””‹››”ŁśĄšŤŚ‹’Š¤¤ť«˛«››”‚uŁ››‹‹‹‚ut››”‹„„‹’ŠŠŠ}lld’ŚŚ’ŚŚ¦§¨‚wl{tt{u{zll’ŚŚ{{t‹’ŠttsŠ}MRK‹‹‹sre|‚zŠ}‚|udc\‹‹‹¦§¨‹‹„››”‹’Š||{{tlri‚u‹’Š‹’Š‚utŠŠ}‚|utsl‹‹„››”Š}|“““||zll||||ztld\\ddcsre„Š„\UZ{{t|Š}|‹‹‹‚u{{t‘Ś…””‹‹‹„dc\j]\f]cVTLsle„„lddttsuztŠ}ŠŠ}b[Utll‰|vyleztlkd\kd\‚wlf]ctsl‘Ś…Š}Š}d\\||Š}„„{ttllk“““„„„„Štts{{n…{{„„mttŚ”•lkslksultlek„„Š™š¤|„…mtt’ŚŚtt{ult]cd‚v{bVZ{tttt{tsllld{{tz‚l{{t‹‹„‚utsl’…‹f]cj]\llk{{tŚ”•””‹{{t‚ut{{t‹„„‘Ś…‚u{{tlek{zm‚|urfklks…‹‹„Š„||kd\Š}|SKJf]ccbV||sre›˘›ldd}„„slesletsl‘Ś…‚|uzllttsult””‹‹…’“““lriekd”››ś››|„…„„Š{tt“Ś”||Ł››¤¤ť‹‹„š””{tt{||{tt„„rfk||‹„„Š}{u{Š}‹„‹tll‚|ud\\‚|u[[Ttsl‚|usrekd\lldŠ}ś››‹’Š››”lldrg]‚u‹‹„‹’Š‹’Š|‚v{””‹kd\||r]Zš””sle‚|uredredVTLcbVŁ››FD;*)(˘—Ť¦§¨ŁśĄ’ŚŚš””šŤŚŁśĄĽŔŻµ¶·¦§¨¦§¨¦§¨¤¤ť˛˛¬‰|vŁ››¦§¨››”›˘›{zm{{t‘}Š}››”{{t‚u‹„„‚|u{u{¦§¨ŁśĄ››”‹’Š||‹„„{{taWM’ŚŚś››llk|„„{{t‹„„”š”‹‹„redllk{||„„Š‹’Š‚ut¦§¨›˘›{ttŠ}tzlSKJJHFVTLš””{tt››”{zm””‹‹‹‹b[U|„…Ł››ult{tt‚utldd[TT””‹ult{ttd\\slej]\kd\|‚z‚udc\slelddkd\f]ctslb[UJHF|tts{u{””‹dc\{tt‚|u‘}llk‰v‹„„‹‹„””‹tts|ldd„„””‹tts{{ttslcbV‹„‹””‹||{{t}tts…‹‹…‹‹lks|„…|„…{{{{Ś”•VZ[]bZfkklksleklkslrimtt|\[[\UZUUY{ttldd{u{‹‹‹›”›„Š„{{t””‹cbV‘…„‹’Š[[Ttllultldd{||sretsl‹‹„tts‹„‹{zmkk]lld}||{||‚ušŤŚd\\‹„„tll|‚z‚v{kd\b[Utzlu{{tsl|‚ztsl||‹‹„tll„Š}{{tkd\‰|vVTLlldslelri{tt{u{„„‹‹‹lksmtttt{|‚z¨©´ś¤¦”š”|›˘›Š}||{||tsl{tt‘Ś…›”›ult}{||uzt“Ś”kd\||Š}|Š}‹‹‹bVU{ttd\\ttstsl‚uuzttsl|{||{{tuztf]cult{zmzll‘Ś…””‹uztŠ}ztl””‹rg]d\\j]\tllrg]rg]Š}|||{{tztl¦§¨UTS*)(¤¤ť¤¤ťŁ››šŤŚ“Ś”¦§¨˛««¤¤ť¦§¨¤¤ť¤¤ť¸Áą””‹›˘›šŤŚ˛¬µ™š¤””‹›˘›‘}‚|u{ttrfk{{tś››’ŚŚŁ››ztl‹‹‹‘Ś…“Ś”tll{{t‹„„‹‹‹{||rg]{{t{||zll|‚z||„„tts{||š””‹„„{{t\[[llk‚|u”“›š””””‹›”››”›„„Š}||‚ztyg‚v{ttsj]\“Ś”¦§¨‘Ś…Š}|Ś‹“‚|u{u{bVUztlŠ}VTL]bZldd„„Šllk\[[UMRtll[[Ttsl{||›”›dc\{zmlrij]\tll{zmtsltlldc\{{tztlŠ}{ttkd\VTLlldbVUb[U{{tŠ}|Š}rfkŠ}|‹„„”š”‹„„››”‹„‹„„VTLsre{{|„…tt{Ś‹“|„…Ś”•„Š„{{llk…‹’nv‚{||mttd\\{{fkk|„…ttsf]cUTSlks\[[bVZ}‚v‚‚|u’…‹”š”Š}‰‘~sre|llk{{tttsllkd\\ztllri[[T||‚z‹„‹„Š„„Š}sreŠ}}„„dc\tllf]c{ttŠ}|tts‹„‹{{{u{„Š„”“›sle{{t|‚zŠ}{{t{{{{t[TTtllVZT[[T||{|||bVU{u{llk‹„‹…‹‹”››‹’Š‹‹‹ś››¦§¨|‚zu{{||Ł››’ŚŚ‹‹„¦§¨{||\UZ{{lri‹„„”š”zll””‹zll¦§¨““““““sle‹‹„“Ś”tts››”{tt‹‹‹‹‹„‰v|‚z{{tlddj]\ztl{zmslesle|}‹„„’ŚŚztltsl{ttSKJlldek]‰v||sle‚utsle˛««SKJ*)(‘}“Ś”˛««›”›ĂÄƨ©´Ł››™‹†””‹””‹””‹›˘›¤¤ť””‹ŁśĄ¦§¨”››‹‹„Š}{zm{zmtllŠ}|||›”›„Š„‹‹„tll‹‹„‹„„Ś”•’ŚŚ“““{u{„„Šlld[TTlrisle„„‹‹„‹‹„Š}|{{t¤¤ť¦§¨|‚z‹‹‹’…‹ek]{tt››”‹‹„}‚|u„„Š‹„„sle{{tldd‘Ś…¦§¨¦§¨Ł››zllš””‹‹„{tt‹„„||{ttkd\{u{{{tttstts}lldSKJ]bZuztkd\tslŠ}{{ttllVTLd\\[TTD;9{{tlld‚v{sre{||‹„‹kd\ztldkVkd\‹„„|b[U{{t””‹}‹’Š””‹¦§¨‹„„ztl|’ŚŚ{{tlrisle‹‹‹„„Ś”•ś¤¦lksmttmtt{{VZ[{{…‹‹fkkmtt…‹‹{u{ulttsllks„„d\\d\\„„ŠŁ››“Ś”š””llk„„¤¤ť‚|u””‹kk]sreuztttskd\tt{\[[lldredztl{{t””‹Š}llksle‚|utll“““‹„‹\UZ||’…‹ult{u{{tt{||dc\jcVtslult{{t’ŚŚ‚|u{zm{{ttts{tt{u{j]\d\\edkekd|{{{||tts{{ŽŁŚ‹“ŠŠ}u{{…‹‹‹‹„{{tš””‹’ŠŚ‹“tts››”‹‹„””‹“Ś”‹‹„„„}“““uzt|{tt¦§¨Ł››‚v{|{||›”›{{tŠŠ}ttslld‹„„ttsult››”{{t…‹‹›˘›Š}lridc\b[UcbV|‘Ś…llkkk]‚|utsl{tt‚ut‹„„ztlrg]ddc„„||red¤¤ťD;9:97Ł››Ł››¦§¨˛¬µ¤¤ť¦§¨ŁśĄ””‹¤¤ť’ŚŚµ¶·¤¤ť¦§¨«˛«¦§¨“Ś”Ł››”š”””‹‚wlŠ}||“Ś”“““„Š}¦§¨}’ŚŚ{tt¤¤ť||˛««||„„{ttŚ”•‹„„‚|uuzt‹’Š””‹rg]llktts{zmš””ultb[U\[[‹‹‹[TT{||kd\{||{ttsled\\|‹‹‹‹‹„ś››””‹Ł››„„‚|u‘Ś…‚v{tsl”š”j]\‹’Šdc\sled\\||kd\lek{{ddcldd\[[dc\[[Td\\“Ś”f]cslesle{ttb[U[TT]bZrfkldd‚ut|bVZj]\ztlztlŠ}|kd\|‚z{zm‹‹„“““ztf|‚zŠŠ}„Š„ŠŠ}rfktsl{||’ŚŚ|‚zkd\tt{‹‹‹{{lri‹„‹{ttlri\[[|„…„„Š”››…‹‹mtt…‹‹{{…‹‹]cd\[bttsf]c{u{lks{{f]cddc\UZ{|||lld{{t|kk]kk]{{tlri„„Šldd{{ttllddcult]bZŠ~‹uzt{{tb[U}f]cf]c{ttj]\’ŚŚ{tt‹„‹sresle‚|u‹‹‹lddult{{ttts|››”‚|u‹„‹‹’Š{||‚|u|‚zult„Š„UTS{ttttsttsf]c{{{u{’ŚŚ„Š„„Š„ztl”š”‹„‹„Š}Ś”•‚ut{{{||’ŚŚ’ŚŚ}‹„„„„{||…‹‹lrizllŠ}‘Ś…”“›””‹‹„„‚u‹‹„‚u{||‚|uuzttts||{{ttsluzt‹‹„||“““‹‹„|sre{{t‚wl{{ttslztf‹‹‹kd\ztlŠ}|sre’ŚŚ||{{ttsl{||¦§¨FD;*)(‰vŁśĄ¦§¨””‹ŁśĄ˛¬µ¦§¨šŤŚ››”¤¤ť¤¤ť””‹””‹””‹“““µ¶·ŁśĄ‹’Š‰v‚u||redred‚u””‹‹‹‹{u{ś››„„””‹||‹„„Š}‹’Š„„{ttztlŠ}{||Š}””‹š””””‹ś¤¦lld{{tred[TTldd{ttslelekrg]sledc\tsl||“Ś”|‹‹‹š””‘Ś…””‹}‘…„‹„„tll‚v{[[Td\\„„‚|uztltll{||”“›}Š”“›uztf]c]bZlddb[Ulddd\\{u{{{t‚ut‹„„‚uldd„‰vredVTLkk]lddbVZ‚|uslelddŠ}|ldd{ttllk|‚|u‚|u{{tŠ}{||sle‚utztl’ŚŚ||lri„„|„…{{ŚŚš{{tt{]cdult{{mtt{{|„…tt{edkf]clksllkekdmtt{{t‹„‹„„lks{u{lek\[[d\\ek]lldllkkd\|‹„„tslsreldd\[[d\\sle}llkŚ‹“tsl‹„‹“““‹‹„sleŚ‹“ddclddtt{‚ut‚v{{ttultldd‚|u‘Ś…‹‹‹VTLkd\UTS‚uś¤¦|Š}{tt{||uzt‘…„ldd…‹‹]bZtsllksś››{{{u{lksult[[Tlektsl””‹ś¤¦‹’Šllkuzt|‚z‹‹„‹’Štzl“Ś”Š}¦§¨lekŠ}|‚zlld{u{||’ŚŚ‹‹‹‹‹‹„„b[USKJd\\mwFD;[TTllk|tts‚udc\{tt››”{zmŚ”•ek]llkcbV[[TŠ}{{t]bZtllsre{ttjcVyle‹„„’…‹Š}sleŁ››SKJ*)(Š}ś¤¦ŁśĄ“““Ł›››”››”›¤¤ťŁśĄµ¶·“Ś”|„Š}«˛«„„”“›‹’Š””‹””‹‹‹„””‹„„{ttlld„Š„‹’Š{ttlld||‹‹„š””Š}|‚z’ŚŚ›”›{||“Ś”{{t‹‹‹„Š„‘Ś…“Ś”„„|‚z{{ttts{||‹„„„„ult‚|uŠ}‰|v{zmtyg’…‹rfk‘…„{{t„Š}|{tt›”›tsl’ŚŚ||zll||ztl}{ttldd[TT}„Š„{{tddc{||tsltlltsl{u{ek]lektllrfkztl{ttlddkk]kd\ddcf]ckd\b[Uekdd\\zllaWMMRK||{||‹‹„lri{ttj]\{zmŠŠ}{yf|‚zkk]ŠŠ}{tt”“›””‹‹„„‹‹‹¦§¨}‹…’uztddc|„…|‚zlksmtt…‹’uztllkmttf]c\[bultekdlksult||iq]b[U{u{}{u{\[[ldd{{t{{t[TT{{tlldtsl{zmlld}dc\sleddcd\\aWMlri„„|{{tVTLlldtllr]gtt{Š}‘…„lddd\\tsl‚utddcztlddcb[U{||[[Tlld‹„„”››{{t]bZ|||u{{”››{||””‹““““Ś”™š¤\UZ\UZSKJkd\ekdtll{tt|‚zf]c{||lksfkktslttsb[Uf]c{||‚v{{u{{ttllktsltllaWM|‚z{tt{||ztl{tt’ŚŚj]\tsl‹‹„||dc\dc\lri{zm{{[[Tred„„””‹‚|u||lldtslsre{zmtsltllcbV{ttkd\ztl{{t{ttmttldd™…D;9:97|š””¨©´›”›‘Ś…˛««ŁśĄ¦§¨µ¶·‹„„šŤŚ””‹|¤¤ťś››¦§¨uzt›˘››˘›‘Ś…’…‹‘Ś…{tt’ŚŚ‚v{|{u{””‹™š¤‹‹„™š¤‹‹„‚|u„„‹‹‹“““{zm„Š„”š”|‚z||{ttultlri|‚z|¦§¨|‚zŠ}‘Ś…||{zmtsldc\red{{t||{||„Š„|„…sle‹„‹red{u{{ttredlldslelddlekj]\dc\SKJslelritsl„„b[U{||ddc„„uzt{{t{{tldd{{t[TT{tt{zmSKJ|„…‚utsle{{ttll{ttztl‰v[TTsle“““lrilld{ttj]\Š}|kd\tslllkztlbVZtts}‹‹„{{tdc\lkslksddc{{{{„„llkmtt„„u{{ddc\[[UUYUMR{{{{uztmttlddlek‹‹„dc\ddclekllkultŠŠ}lrilddlri‚u””‹{ttd\\lek{{t{||ztlldd|‚z„„kk]VTL{u{j]\b[U\[bd\\[TT‚|ub[Ured{||[TTllkVTLb[Uredb[Uj]\]cd{||„„j]\tlltts”››ekd{u{{||{ttVTLlri{u{||…„’tllŚ”•{||tllkd\‹’Š{||“““]cd|‚zdc\lks||ddcbVUSKJztlVTL[TTlrittscbV{||sletygtts|‚zrg]‹‹‹||||{u{lddztllri„„Š}|‚z„Š}dc\ldd[[T|‚zttskd\[[Td\\tslb[Utzl[[T[TTkd\{||„Š}red|||tslj]\Ł››SKJ*)(‹‹„””‹ŁśĄŁ›››”›ŁśĄ›”›””‹”››’ŚŚ›”›¤¤ť››”›˘›„„‹‹„”››””‹ultŠ}{tt‹„‹‚|u””‹‹‹„ztl||‹„‹Ś‹“{zm|‚wl“Ś”}{{tlksŠŠ}{{t{|||‚zztlsredc\„„Šsre“““ŚŚš{ttšŤŚ’ŚŚŠ}|‚utŠ}{{tzllekd’ŚŚttslddllktll{||kk]{{t‚|uultult‹‹‹“Ś”tll\[b]bZbVU[TTtslf]c{||tsltlltll}lldkk]tlld\\kd\j]\|‚uFD;tll{ttsleVTLb[UlddVTLztl||tts“Ś”ultkd\cbVdc\{zm‚usletts„Š}tll‹„‹…‹‹“““‹‹„[[T]cdslelks{{{{edkddc{||u{{mtt\UZ\[bJHFVZ[lkstt{ddc„„Šlks}Šlks[[Td\\lekllkf]ctts“““‹‹„‘}VTLtslttsbVZ[[T[TTzllkk]||mttz‚ldc\lks‹’Š||VTL\UZSKJd\\lekkd\zlllddlldddcSKJVTL[TTtsl}\[[dc\tslVTLVTLŚ‹“lrildd\UZlldd\\{u{llkllk{tt„„Štts„„ŠtllbVZlkslridc\uztŚ”•mtt}lektlluztlekj]\b[Uu{{d\\{tttts[TTVTLtslVTLkk]ddc‚|uddcŠ}{{t’ŚŚŠ}tll||ekd|[TTdc\lld‚|uultttsf]c„„{||kk]sre‹‹‹dc\kd\lddztlddcb[U‚utlld{tt||sleŁ››JHF*)(Š}‚|u“““š””¨©´“Ś”“Ś”’ŚŚ¦§¨Ł››˛««”››“““›˘›Ś”•‚uŚ‹“„Š„„„|…‹‹‹„„{tttsl{{””‹››”tt{‹‹‹””‹{ttsle‹‹„Ś‹“tsl{{tzllztl‹‹„llk‘Ś…||UTSkk]dc\ekd{ttlddtslulttsltslkd\|‚z|‚zkk]{||d\\{||lddlri‚|uttsŠ}ttsSKJddctll„„Ś‹“ult[[TVTLSKJllkJHFSKJ\UZdc\ldd‹„‹|„…tsllldtslb[UUTS[TT]bZVTLj]\b[UVTL{tttslVTLzllztlztfldd{u{lrilddJHFb[UVTLkd\redtsltts||{ttllk{{tsllldUTSttsekd{{]cdf]cllk„„tts{{…„’\[bfkkVZ[}Šu{{lksddc|„…{u{“Ś”ŚŚš{tttlledkuztlek‚utuzttsltslVTLtt{\[[d\\[TTekdj]\{{tlddkk]„Š„tzl[TT\[[d\\b[Umttllkllkldddc\\UZlekbVZlldtllzllŠ}tslj]\[[Tdc\lldttslldllkuztkd\edk\UZVTLb[UJHFf]cUTS…‹‹u{{Ś‹“ddcb[Ukd\…„’UTSlriuzt]bZttslddMRK„Š„„„Š{ttUMR[TT{tt„„Šllk[[TlddcbV\[[{ttlldj]\[[Ttslsre||kd\ddcb[Uddctll]bZkd\|lldtlltsl||{||ultŠ}d\\dc\ztldc\kd\tsl{u{sle‰|vsleddc{{tlld˛««[TTD;9ztl’…‹¤¤ť‘Ś…‘Ś…||“““‹‹‹{||››””“›…‹‹…‹‹Ś”•„Š„“““|„Š„{{t|‚zllk‹„„””‹|‚z|tts{||llkd\\kd\{u{’ŚŚ}‹„„lrilldlldztlkk]lldtsl””‹tslu{{sleedk[[TVTLrfkf]credkd\kd\]cd|‚zsle}lldtts{||ekdf]ctlllld|‚zslelld‹„„tts{tt{||tllcbVzll[TTdc\d\\{u{]bZbVU{tt\[[VTL[[Tkd\\[bb[U[TTtllslekd\|‚z[TT‚utztl\[[b[Usletsl{||tts[TT[TTlld|‚z‘Ś…d\\tsl{{t{{t{||lldtllttsd\\[[Td\\{{lrif]cfkklkslks|‚z{||mtttt{VZ[LKRVZ[mttmtt]cd\[[\[bd\\d\\lddlekmttedk\[[r]guztekdekdd\\lridc\{{t[TTlldd\\FD;[TTd\\kd\tslUTSlld\[[[TTkk]f]cj]\f]cf]c[TTtllf]cbVZUTSllkkd\ttslksllkd\\SKJmttUTSUMRd\\tllSKJ[TT\[br]gf]cUMRUTSztlddcslelkszlltll\UZtllVTL{||llddc\lldtt{VZTtt{„Š}‹„‹ultd\\d\\tt{mttekdlkssleVTLkd\{{tdc\dc\{{tldd[TTztl\[[dc\d\\b[Uddcd\\f]cb[UcbVlldlld{{ttslcbV[TTztlVTLkd\dc\lldtllb[Urg][TTUTSredkd\””‹[TT:97{||››”’ŚŚ˛˛¬“Ś”“““„„Š}|”››“““ttsllk„Š„|tt{mtt|…‹‹‹„„ŠŠ}{{{u{ztl‹„‹‹„„tts{u{{u{„„llk{{}{tt{ttkd\kd\dc\{u{tsldc\slelld|{{{||{|||tllttstlldc\{ttkd\{||…‹‹{u{|‚zlld|‚zVZTSKJkd\lek|‚ztts\[[JHFf]clrildd{||sledc\ttsttsllddc\\[[JHFd\\UTSdc\ztfkd\\UZsleVTLd\\tslaWM[[Tllk{ttkd\lldlritsl||uzt„„tts{||{{tlld{u{kk]ztf„Š}{{tlridc\lddultekd]bZdc\llkSKJtlllksmttlksVZ[f]cllkUTSlks\[b\[btt{\[bult\[bVTL\[bJHFUUY[TTdc\UMR\[bd\\UTS[[T[[TVTLMRK\[[|‚ztllttsekdd\\b[USKJUTSSKJ\[[dc\lldttsllkj]\d\\leklddUMR[TT{tt\UZleklldtsld\\VTLkd\[TTuzt[[T„„ddcu{{„„{ttd\\JHFmtt[TTldddc\\UZtts{u{u{{SKJ\UZ[TTVTLUTSekdlldedkddc[TTllkddcddclridc\JHFedkttsult\[[[[Tllktslf]ccbV[TTkk][[TlldSKJSKJtlltlld\\fkkd\\sretslllkVTL{||{{t[[TVTLUTSd\\ldd[[Tdc\tllrg]]bZttskd\ldddc\d\\[TTztl˛««JHF*)(‹„„||‹‹„’ŚŚ‹„„‹„„{{t„„Š„„‹„„tzl{||tll|„…llk„„|‚zttstll|tt{ldd}„„Šb[U„„{||ddcllk[[Tultlksultu{{{ttd\\JHFdc\VTLek]lld{{t{{tlddldd…‹’||sre|„…||„„Šlri||ddc{||{{t|„…u{{ddcddcedk{u{{u{tsl[[TJHF[[T\[[ddc{u{lddultkd\f]c[TTddcd\\dc\cbVlddultuztkk]b[U[TT[[TVTL\UZtllVTLb[Udc\kd\redlldVTLb[Ulldtzl{||tllekddc\lldtll{{tlddztltsl]bZlrilldlddttslld{||\[[UUY]cdedktt{mtt\[b]cd\[bUUY\[bmttlkslksUUYfkkUTS]bZUMRJHFUMR:97JHF:97UTSUTSJHFllkllkVTLSKJllk]cdcbVLKRb[Ub[U[[T\[[SKJVTL\[[dc\lriddcVTLdc\llkf]cllklddlldlddUMRUTStts\[bkd\VTLllkJHFtllbVZuztttslddddcbVU[TT[TTUTSJHFJHFddcUUYUMR\[bJHFJHF[TTdc\d\\ekd[TTUTSJHFVTL\[[]cdD;9f]clld]bZd\\VTLSKJVTLJHFllktt{‚|uekdUTS]bZdc\JHFkd\[TT[TTtll[[TVTL]cdb[U[[TSKJVTLdc\lldFD;[TTUTSSKJJHF[TT[TTdc\dc\b[Ulddd\\VTL\[[bVUd\\jcVkd\ŠŠ}JHF-1+{tt‚|u„Š„}{tttts{||{tttts„„Šdc\“Ś”uzt„„Šllkttsu{{tts|‚zJHFedkleksle\[[sleek]llk\UZf]c{{tf]cedkSKJtts{ttlddlrillddc\\[[]bZ{{ttslUTSldd{u{llklksfkkllkultkd\[[TUTS]bZ[[Td\\tllUTSddctts\[[\[[dc\VZTJHFJHFJHFFD;UTSVZTVZTtllredd\\VTLVTLdc\kd\UTSd\\kk]dc\ddcUTS[TTdc\bVUcbVJHF[[T]bZtllb[UJHFd\\tllb[Umtt[TTUTS\[[VTLb[U[TTdc\VTLb[U[[Tddc[TTUTS\[[cbVVTLddcf]cf]cUTSlksllkVZ[]cdultmtt\[[edk\UZJHFLKRUMRJHFLKRUTSJHFJHF)+2:97F=CF=CJHF:97D;9d\\d\\VTLdc\VZTLKRJHFUTSJHFFD;JHFFD;UTSMSStllMRKUTS\[[UTS\[[\[[[TTf]cSKJSKJD;9JHFUTSUMRlddVZTUTSlekdc\lks\[[[TTddcF=CSKJFD;UMR:97JHF:97:97MSS:97\[[UUY\[bllkult{||JHFJHFFD;>B9>ECJHF:97JHFLKRUTS\UZ[TTUMRMRKd\\VTLJHFekdlldlddJHFF=CFD;MRKSKJSKJlldlddSKJllkUTS[[TJHFJHFD;9D;9:97:97>B9:97>EC:97D;9:97JHF[[TSKJSKJlddJHFFD;\UZJHFJHFSKJSKJ¦§¨SKJ*)(ztl{{t||{{t{tt{ttllkdc\lldldddc\[[TJHFedkdc\ddcmttlkstts]bZllklddtllultVTLMRKJHFUTS]bZ[[TUTSJHF\[[UTS\[[tslbVZllktsl[TT]bZ]bZFD;JHF>ECJHFJHFJHFVZ[UTSddc[[Td\\UTSVTLd\\SKJ\[[\[[UTSVZ[JHFJHFD;9dc\JHFJHFUTSSKJUTSJHFJHFd\\JHFJHFJHF:97UTSJHF:97FD;JHFVTLJHFJHFJHFdc\[[Tkd\JHFD;9JHFJHFJHFFD;FD;SKJ[TT[[Tldd\[[JHFddc\[[lldd\\[[Tddcllddc\VTLFD;JHF]cdllkddcldd\[[[TTd\\]cd\[[]cdJHFLKRJHF]cd*)($:97*)(*)(?;C:97:97*)()+2:97:97:97:97UUY3+**)(74,!*)(*)(*)(*)(*)(74,*)(*)(*)(JHF*)(:97*)(:97*)(74,3+**)(*)(3+**)(*)(7-2*)(:97*)(*)(*)(:97*)(,55*)(*)(*)(*)(*)(*)(*)(:97&&%&*)(>EC-1+%&FD;)+2LKRLKRUTS?;CJHF*)($*)(*)(,55*)(*)(F=C*)(*)(*)(*)(*)(74,:97-1+*)(*)(*)(:97:97JHF*)(74,-1+*)(*)(*)(74,3+**)(*)(&&*)(*)(*)(!*)(*)(*)(*)(*)(*)(*)(*)(:97*)(*)(:97*)(*)(D;9:97*)(-1+VTLSKJFD;\UZ[[TJHFSKJJHFLKRJHFSKJSKJ3+*:97:97JHFJHF74,:97LKRUTSMRKMRKJHF:97*)(:97*)(:973+*:97*)(:97:97JHFLKR>ECJHF,55:977-2*)(-1+74,:9774,-1+3+**)(*)()+2*)(*)(*)()+2:97JHF:97,55*)(*)(*)()+2*)(*)(?;C*)(74,:97*)(:977-2*)(JHF*)(&&*)(*)(3+*:97*)(3+**)(*)(*)(*)(74,3+*&&&&3+**)(*)(&&-1+*)(*)(*)(SKJ*)(*)(:97*)(D;9:97:9774,74,*)(*)(>EC*)(:97*)(*)(*)(*)(*)(*)(74,*)(-1+,55,55:97)+2*)(,55:97:97:97LKRJHF?;CUUYf]c\[b\[b\[[[TTSKJUMRJHFllkUTSllkJHFMRKVTLUTSJHFF=CVTLJHFFD;JHFJHFUTSJHFJHF>ECJHF>ECJHFJHFJHF:97LKR:97F=CJHF:97D;9:97:97:97:97FD;:97:97:97JHFF=CLKRJHF\[b\[[MRKMRKdc\]cdLKRek]UTS\[bMSSMRKJHF\UZJHFJHFVZTMRKJHFMRKJHFJHFJHF:97:97:97:97JHF>B9JHFMRKJHF:97D;9UMRVTLJHFFD;VTL[[TD;9JHFFD;>B9:97:97>B9D;9FD;JHFJHF>B9D;9:97JHFD;9FD;UTSSKJD;9FD;SKJD;9SKJJHF[TT[TTJHFJHFVTLVTL:97[[Tdc\VTLllkbVZf]cek]>B9VZ[\UZ>EC\[[VZ[UUY\[[\[bLKRVZTfkk]cd\[[[TTUTS>B9MRKMSSJHFSKJddc[TTVTLVZ[UUY\UZUMR\[[MRKllkVTLJHF:97SKJ[[TVZTJHFJHFVTL\[bJHFMSS[TTLKRJHF:97JHFD;9:97JHF:97JHF\[bf]cJHF:97VTLJHFJHF>EC:97>B9JHFSKJ:97:97SKJJHFJHFJHFJHFFD;SKJD;9MRKJHF74,JHF:97:97JHFFD;UMRD;9SKJbVUFD;MRKb[UJHF:97UMRMRKMSSLKRFD;:97FD;JHFekd:97JHFUMR]bZJHFUTS:97JHF\[[LKR\[bLKRMSSJHFLKRMSSOS`OS`JHF¦§¨¦§¨“Ś”¦§¨¦§¨™š¤¦§¨¨©´…‹‹¦§¨›”›¦§¨›˘›¦§¨«˛«››”˛««¦§¨›˘›µ¶·µ¶·˛««˛««””‹¤¤ť¤¤ťŁśĄ”“›¦§¨˛««””‹””‹ś¤¦|‹‹„ztl›˘›šŤŚ‚v{¦§¨˛˛¬˛««˛««Ł››Ł››š””¦§¨“Ś”¦§¨tsl’…‹¤¤ťŁśĄŠ}¤¤ť˛««››”¤¤ť¦§¨¤¤ť››”¦§¨˛¬µ¦§¨¦§¨¨©´¦§¨¦§¨¦§¨Ł››¦§¨Ł››¦§¨¦§¨ś››«˛«¦§¨µ¶···Ä¤¤ťŁ››””‹’ŚŚ‘Ś…‹„„””‹””‹‰v¦§¨Ł››¦§¨µ¶·¤¤ť¤¤ť˛˛¬¦§¨¦§¨¦§¨›˘›¤¤ť””‹””‹¤¤ťŠ}””‹˛˛¬¦§¨””‹ult”š”Š}‚wlztlŁ››¦§¨˛««¤¤ť¦§¨Ł››™…Ł››Ł››˛««””‹˛««ŠŠ}˛˛¬[[T\UZ˛˛¬˛˛¬¦§¨˘—Ťš””Ł››¤¤ť¦§¨Şł·˛˛¬¦§¨µ¶·Ä¿¾Ƶ¶·µ¶·µ¶·¦§¨¦§¨µ¶·¦§¨¦§¨Ł››‘}µ¶·µ¶·ĂÄƦ§¨µ¶·˛««‹‹‹¤¤ťµ¶·¤¤ť›”›µ¶·˛««˛««˛˛¬µ¶·¦§¨ĂĽż¦§¨¦§¨’ŚŚ«˛«””‹¦§¨¦§¨¦§¨˛¬µ”š”¤¤ť‹‹‹””‹„„ŁśĄŁśĄŁ››¦§¨˛˛¬µ¶·””‹¤¤ť¦§¨›˘›¤¤ť“““‹’Š”š”’ŚŚ‹„„‹‹‹Ł››››”˛««””‹Ł››Ł››˘—Ť””‹””‹””‹||¤¤ť˛««Ł››””‹Ł››˛˛¬¦§¨˛««¦§¨””‹¦§¨¦§¨Ł››‘}¦§¨˛««¤¤ť„„Ł››””‹””‹||””‹š””””‹µ¶·¦§¨˛˛¬¦§¨˛˛¬¦§¨¤¤ť¦§¨¦§¨¦§¨ś¤¦¦§¨¦§¨¦§¨¦§¨µ¶·ś¤¦¨©´lks)+2?;CLKRdc\ultd\\7-2>/Att{\[[f]c]bZ!:97%lrilridc\ddc:97SKJlddlldSKJ|:97*)(JHF[[TLKRJHF\[[JHFSKJVTLldd{u{f]ckd\]cdddcred{zmSKJVTL3+*:97%JHF\UZlld7-274,%&$VZTuzttll[[TUTSMSSVZTVTLVTLtlldc\tll[[Tddc[[TJHFJHFUMRekdddcUTS74,@/7 74,73FD;VTLRP:tslredbVUVTLD;9MRKFD;FD;D;9C8.]bZ&&&&3+*FD;D;93+*3)D;9dc\VTL3)FD;%&&0FD;SKJD;9D;9VTL˛˛¬dc\[[TVTLjcV||SKJ>R.VTLJHFGSu]cd’|‚z|‚zlrityglldsreD;9SKJsre{{t‹‹‹‚|u{tt‹„„lddf]cMRK}{tttllek]f]c[[T]cdUMRD;9UUY"%VTLFD;JHF\[bf]cMRKfkktsllri[[T ,55-1+>B9VTLUMRD;9VTLVTLlldSKJ\[[sre{||VTLd\\{ttSKJfkkJHFD;9SKJsleVTLcbV>B9VTLVTLyledc\3+*"FD;FD;d\\D;9Q?@SKJ >B9*)(:97*)(]bZ7-2SKJ3+*dc\zllUTScbVJHFlldtslJHFlldf]cJHF\[[LKR%&-1+,55{{VZ[llkUMRlks]bZJHFF=CLKRf]clddlek\UZf]cMSSSKJf]c>ECf]c74,[[T]bZVTLttstll|]bZedk{u{[TT{ttUTSLKR\[bUMRJHFVZTUTSJHFJHFVTLdc\lldultVTLtlldc\uzt{ttSKJSKJSKJ74,UTSf]cf]cJHFkk]JHFD;974,*)(>B9*)(JHF3+*fkkultUTSJHF\UZUMRVZ[[TTd\\lrio€wd\\uzt]bZtsl\UZLKRultuzttts\[[lddFD;-1+FD;>B9%)*)("*)(FD;SKJFD;j]\UMR[[TFD;SKJ:97C8.D;9D;9SKJFD;JHFFD;JHFtllUMR:97SKJb[UVTLFD;JHFVTLD;9F=CPF=JHFD;9D;9SKJJHF¦§¨VTLJHF‰v‚u‚|u‰|v‹„„lri’cbVJHFtsl‹’Š\[bSKJ7-2[TTuzt|„…lldllk…‹‹lrib[UJHFb[Uult‹‹‹„„Šult[[Tlek{{tlldSKJ\[b{{{{tj]\tllultekdSKJSKJ\UZD;9ldd\[[[[TekdF=CVZ[JHFdc\uztultlri:97]cdfkkMRKJHFttsddc\[bJHF[[Tdc\]bZlriUTSddcVTLSKJUTSf]clri[TTztlb[UVTLVTLlldVTLVTLlddd\\cbVSKJMRKVTLkd\{ttb[UUMR\UZFD;*)(:97[[TFD;[TT:97>EC:97[[TJHFFD;sle[[TMRKVZTSKJVZT\[[>EC\[[UUYUUY>EC>ECJHFJHFUUY]cdJHF\UZ]cdlksddc>ECedkJHFddcj]\UTS\UZ\[[edkbVZf]c\[b[TT:97D;9[[TMRKb[Uek]VZTUUYJHFUUYVTL]cdd\\f]c\[b\[bD;9lriMSSSKJd\\[[T[TTsle\UZ\[[UTSb[Ullk\[bSKJtll\[[SKJSKJ*)(UMRUMRSKJJHF&&3+*:97JHF74,:97JHFLKRSKJf]c]cdf]c]cdedkVTLb[UVZTmtt[[T[[T]bZ[[TUTSu{{ddc{{t{u{lksf]c]bZ]bZVTLlri&&&&SKJaWM[TT[[TVTL[TTb[UFD;3+*FD;FD;VTL74,D;9VTLSKJ[TTd\\[TTD;9SKJJHFdc\JHFJHF[[T[TTJHFbVUUTSaWM[TTVTLtll˘—ŤllkSKJtsl{{t{zm’…‹{u{kk]]bZ|‚zMRKdc\VTLJHF%UMR{||ttsttsŚ”•\[[|„…tzlrfklddult„Š„{||ekdlddldddc\…‹‹ddcb[Umtttt{ldddc\{ttultlriUMRUUY|„…dc\lekmttVTL\[[F=CMRKVTLfkk{u{{ttMSSMRK\[b:97ekdb[Udc\ult\[[:97dc\JHF[TTMRKddcu{{dc\j]\d\\[TTllkSKJkd\j]\d\\tll[[TlddmttVTLlldVTLJHFFD;D;9SKJJHF[TTddcD;9D;9*)(FD;b[U:97SKJsle:97SKJVTLddcVTLlld{||VZTddc{||llkF=CultlrimttJHF]cd>ECLKR:97MSS\[bMSS]cdVTL\[bddc>ECSKJ\[b\[[{||}„„ŠJHFddcbVUulttts\[[FD;:97VTL3+*JHFVTL:97d\\:97]bZdc\ekdddcUMRLKRD;9[[T[[TJHFf]cbVZkk]tlldc\zllSKJb[Ukk]edkf]c{u{lek]bZUTStt{f]clddUMRUTSSKJJHFVZTFD;VTL:97FD;FD;lddJHF‚v{fkkVZ[VZ[\[[sle„„lldlkslriJHF[[Tkk]\UZdc\VZT„„{ttVTLlks]bZ[[TJHFJHF&& +&&3)[TTSKJbVUkd\f]csleSKJ:97FD;&&FD;PF=FD;VTL[[T[TT[TTb[Ured:97[TT[[TVTLFD;VTLJHF[TTVTLf]cVTLSKJVTLD;9lldš””bVZJHF{zmŠŠ}’ŚŚ{ttlddMRKmttiq]z‚l‹’Š|‚zUMRVZTJHFSKJ|„Š„tt{d\\lkstts[TTJHF„Š„…‹’{{tlrid\\[TT[TT]bZ[TTddclldlddlldSKJJHFedkUUYJHFlekJHFUMR[TT\[[{zmUTS\[bMSSVTL]cd{{…‹‹UTSekdSKJLKRddcSKJllkJHF[[TFD;]bZlek]bZek]\UZVZ[UMRkd\lddztluzt[TTb[Ulekd\\{u{FD;VTLmttmttllkSKJMRK74,D;9VTLVTLb[USKJbVZ[TT&&PF=VTLVTL\UZek]>B9D;9tsl\[[ekdkk]mttdc\llk{ttllkSKJ\UZ{{llk\[b]cd>ECLKR:97LKR{{|‚z\[bf]ctt{MSS\[bVZ[LKRttslldj]\iWUUUYldd[TTf]cf]cJHFJHFJHFFD;JHF[TTtlldc\FD;JHFbVZlldlldddcJHFUMRSKJSKJSKJJHFSKJ{ttSKJkd\ulttll[TTSKJ{zm\[[ult{ttj]\cbV]cd\[bJHFf]c‚v‚\UZkk]jcVVTLMRKVTLsreUMRFD;UTSlek‹„„llkUMRUTS]cd{u{{{tddcu{{]bZuzt[TTsred\\b[UVTLVTL{ttVTLf]cFD;74,VTLVTL>B9 :97*)([[TD;9SKJVTLkd\d\\VTLredb[UPF=FD;sreVTLjcVek]UMRldd[TTUMRlddSKJkd\b[UFD;D;9SKJdc\JHFtll[[TSKJ74,SKJlldŁ››f]cLKR‘Ś…‚usle‚v{JHFVTLsreFD;ZbN‹’Šlldf]cmttUMRŚŚš{{Ś”•‹’Šekd””‹ttsttstll„Š„{||‹‹„|„…{||ultsleek]llkdc\ddctlltllddcd\\\[[mtttt{\UZUTSJHFb[U\[[{{JHFUMRVZ[UTStslu{{{||\UZ\[b[TT]cd>B9FD;f]ctt{:97\[[VTLdc\[[TlritslMRKFD;[TT[[Tredtts{zmdc\UTSd\\SKJSKJD;9VTL]bZrfkttsFD;!D;9VTLJHF\[[SKJUMRVTLJHFSKJj]\d\\D;9i\VJHFD;9ztlUTSlek[[TekdVZTekdlddtsllekd\\]cd{{tbVZJHF\[b>ECLKR]cdlkstsl{{mtt{{f]cJHFUTSultlddVTLUMRf]c\UZf]c‚v{lekUTS]cd>B9MRKVTLVZT{{t‹‹‹lek¦§¨fkktlltts{||]bZF=C74,SKJddc|„…lldlekf]cdc\zlltll‹„„‚|ubVUb[Ulekd\\tllultddcSKJSKJf]cUMRldd\UZSKJD;9JHF[[TVTLSKJVTLVTLJHF}Š}{{llk]cd[TTd\\sleultleku{{ś¤¦|tslf]cVTLFD;[[Td\\UMRD;974,MSSVTLFD;%>B974,MRKJHFj]\kd\FD;UMRcbVjcVkd\ztfcbVC8.VTLFD;VTLek]VTL[TTkd\PF=JHFVTLjcV{zmd\\PF=FD;SKJ[TTSKJbVUVTLcbV]bZtsl¤¤ťek]JHF‘Ś…‘Ś…„„’ŚŚzllf]clri]bZšŤŚztl|g\rq^„¬¶Ă¨©´ś¤¦µ¶·”››|„…¨©´‹‹„”“›Š~‹tllultuztddcf]c{u{{tt„„“““{{tuztś››‚utllultfkk‹‹„f]cSKJ‚v{dc\{u{ddc}ŠJHF{{lrid\\„Š„|‚z\[[UTSUUYlksJHFddcD;9edk…‹’VTL:97lld||{||ttslldldd[TTUTSj]\b[UVTLSKJ:97{u{lddSKJrg]b[Ullkllk{{t{{D;9JHFMRKVTLUTSuzt[TTddcD;9:97sle[TTdc\SKJHR>SKJrfktslmttJHFdc\ttslrilri„„|‚z“Ś”|lek{{t†~‘MSSmtt^fsfkkŚ”•Ś‹“tt{mtt„„Š{{\[b{||[[T\[bultkd\\[bVZTmttlek“~mtt{{mtt{u{JHF[[Tdc\’ŚŚ|llktlltsluzt{u{ultllkJHFUMR]cdcbVVZTddcF=Cb[U||tlltlllddlld{{tdc\mtttll}zlldc\d\\SKJ[TTlekrfkbVZ‚wlaWM74,JHFlriD;9ddctllekdŚ‹“ttszll”“›u{{u{{VTL{zmb[U{{u{{‹’Štll‚utll]bZ]bZztlcbVultUMRF=CSKJiq]MRK3+**)( *)(JHFredsleb[Ub[Ukk]cbVtslVTLFD;ZbNdc\jcVztfFD;]bZbVUtslb[UVTL[TTtslŠ}VTLZbNkd\rg]j]\{tt‰|vcbVFD;tll|‚z¦§¨>B9SKJ‘}›”›‹‹‹Š}]cdjcVmttkk]ekd‹’Šš””ult„Š„‹’Š¨©´”“›»ÂÇś¤¦›˘›¬¶Ă‹’Š”š”{{””‹’ŚŚ{u{{||›”›}ztlŞł·››””š”{{›”›‚|u‹„„ttsllk\[[b[U\[b]cd|‚z“Ś”{u{””‹\UZ]bZlkslld„Š}{||llkVZTMRKF=C>ECrfk[TTMRKttsJHFlddllk|„…“““mtttllj]\redUMRJHFSKJcbVVTLFD;ek]‹„„dc\j]\lldJHFlekttsuzt]bZSKJ]bZ‹„„ult‚|u[TTUTS]cdVTL[[TsleVTLD;9aWMVTLtll{{tuzttsl›˘›{||lriŚ”•“““ś¤¦™š¤‹„„¨©´|‚zzlllksOS`]bZlks]cdtts…‹‹\[b‹‹‹†~‘\[bddcUTS{||‹’Š||{ttddcedkzllf]c{{fkkUMRttsJHFllkVTLlddztl{ttttsdc\lri]bZddcttsVZ[JHFrfkf]cllk[[TSKJ‹„„””‹}lddrfkjcVslekk]lld‹…’||‹„„|„…SKJ{{UTS‚v{\[b[TTb[Uuzt[[T\UZkjVJHFD;9VTLllk‹‹‹bVZ{{ddc\[[\[[|›˘›lldddcrfktzl{||”š”…‹‹b[UFD;d\\VTL{ttd\\UTSFD;\[[FD;&&%74,>B9uzt{tt{yfztl{zmb[UaWMSKJVTLJHFVTLVTLVTL|‚zkk]VTLkd\lldbVUSKJ[TTkk]sleaWMVTLkd\SKJj]\tll‚utd\\‚ulektslŞł·VZ[SKJzllŁ››„‰v’ŚŚŠ}aWMtts]bZUTS|Š}Š}]bZdc\›”›Şł·¦§¨Ś”•|„…™š¤d\\‹‹„ztl|tts{zm“““j]\f]c“““¦§¨””‹«˛«¦§¨‹„‹{tt}\[[‹‹‹Ś‹“\[bf]cf]cŠŠ}|ŚŚš||™š¤mtt“Ś”„Š„tyg””‹{||UUYtt{ttsllkUMRUMRnv‚„„Š\[[ŠŠ}ddctt{{{t„„{{t\[[lddUMRredkd\lldaWMb[Urfklddsletllldddc\lld‚v‚„„UTSJHFuzt‚v{tllkd\||LKRJHF]bZb[U‚uMRKUTSkk]JHFbVU””‹dc\{{sleult|‚ztts{{t{{tult…‹‹…‹‹„Š„tts]cdMSS>ECMSSldd„†™mttf]c}‡’ult{{t]bZdc\f]cSKJf]c[TTleklrif]c’ŚŚ‹„‹tts]cdD;9MRKFD;[[TSKJbVU[[T{ttlld|\[bekd„„ŠlritslUMRlld™š¤ttsbVUttsŠ}›”›||‹„„‚|ulldiq]…‹‹„„{tt‹‹„‹‹‹||lkslek“Ś”tll™š¤‰|v„„FD;JHF\[[dc\ultlri„„}llk{||tts{{{{b[UztflldddcUUYiq]zll‚uddctsl]bZf]cultf]ckk]\[bC8.D;9]bZJHF!FD; 74,VZTtllš””‚wlldd‚wl[TTSKJrg]C8.dc\sreaWMaWMPF=JHFFD;{ttSKJSKJ[TTVTLek]i\VSKJVTLVTLSKJ‚|ukd\VTLsrellktsl˛˛¬\UZ3+*Š}||‚zrr]‘Ś…tzlrg]ekd|‚zlld‹’Š‰v‚ut!VTL{yf¦§¨Şł·›˘›u{{¦§¨|„…rfk[TTlri™š¤„„™š¤¦§¨””‹””‹›˘›¦§¨„Š„„„‹„„‚|uj]\”“›|‚zLKR‹‹„{||tt{|„…FD;}Š||…‹‹lks}ultlri{||lrif]cuztedklksf]ctllttsllkUUY„Š„VTLdc\dc\…‹‹SKJ[TTd\\llk{||||„„SKJsle\UZf]cylemwrg]”“›ekdddc}VZ[JHFVTL{{tslekk]tll\[[ekdd\\VTLb[U{ttSKJkk]kd\{u{‚|uldd{zm’ŚŚ{tt‚uŚ”•|‚z{ttlldultyl„tzlddcMSS\[bMSSUUYddc\[bMSSlks{{„„mtt\UZlld{{tsl{tt||f]c]bZŚ‹““~ultfkkztfMRKMRKtt{SKJr]ZVTLj]\sle‹‹„{{tlkskk]ttsdc\JHF]cdlri‹„‹Ś”•tll{tt””‹“Ś”||’…‹””‹ztllldttsŠŠ}’ŚŚś››”“›|„…f]cf]cult„„‹„„i\Vfkk]bZultkk]SKJ>B9VTL|tsl‹„‹{{…‹’Ś”•mtt]bZdc\{zm…‹‹\[b|‚ztll|tt{f]clri‹„„Š}|tllek]JHFsleJHFaWMJHF*)(:97!JHFbVZd\\j]\sle‚|ubVUVTLsleaWMztfztfHI/VTLFD;jcVVTLVTLSKJSKJJHFkjVŠ}VTLd\\d\\bVUSKJztl[TTkd\VTLult{tt¦§¨>EC:97{||„‰v„‰v˛««™š¤‚u|››”‚v{{||’ŚŚ}*)(&&‚n¨©´‹’Šddc|„…Š}||VTLD;9‹„„‹‹‹tll“““…‹‹‹„„””‹‚|u””‹”š”{{||””‹SKJ…‹‹tzl{zm„Š„™š¤“““\[[ztf}{||„„VTL[TTb[U{{t‹‹‹ztl[TTSKJUTSMRKf]cUMRllklddultlekddcztld\\VTL‚wl\[[rfkkd\Š}|{||b[Ukd\red‹„‹{u{iq]‚|u[TT|„…tslekd[TTJHFD;9[[Td\\‚|u’ŚŚsle{||JHFVZTdc\kk]VTLVTLVTLjcVd\\{{t]bZ{{t{zm||‚z”š”›˘›Š}||lek{{tsl{u{{u{>EC>EC]cd\[[\[bmtt\[b{{”“›ultFD;d\\lkslld[TTlekUMR|„…¦§¨{u{ultŠ~‹mtt[[TVTLllkSKJztlredlld[[TtsluztVZTJHFFD;lri}f]cbVZztftzlš””’ŚŚ’…‹red„„Š~‹{zmsleFD;sletsl“Ś”š””{u{ddcJHFUTSSKJf]c„Š„rfk\[[‹’Šd\\JHFJHFlldMRK|ult{{tll{u{{{ekdsletsl›˘›mttŠ}|‹’Š||ŠŠ}„„Š|‚z|‚zz‚l||lks}UMR\UZlekb[U\UZJHFVZT?;C3+*:97SKJ‚|uŠ}ztl‹‹‹rg]r]ZcbVd\\SKJi\VjcVcbVcbVVTLVTLaWMztl[TT[TTsre‘Ś…jcVredb[Utllred{ttredrg]cbV[[T|µ¶·\[[:97ś››””‹Ł››Ł››{u{š””ĂÄĆ””‹…‹’]bZŁ››{{|„…lks’ŚŚ””‹…‹‹…‹‹‹‹‹“Ś”Š}|dc\iWUred||tsl‹„‹“Ś”red””‹‹‹„’…‹cbV‹‹‹Ł››‹„‹f]cŚ”•fkklri››”Ś‹“Š}|lri]bZldd‹„‹…‹‹\UZj]\lddlld‚uttslekSKJUTS\[[{u{rfkŚ”•bVZJHF[[TŚ‹“llduzt‹„„‚wld\\[[T\[[tll‚|u||{{tlld„Š„f]c‚utb[UUMRztlŚ‹“bVZ„Š}JHF[TT\[[uztdc\‚|uŠ}…‹‹\[[“““‹‹„srelddkjV‚nVTLaWMj]\VZTllk››”‹„‹d\\ekd‹’Š„Š}{u{{u{[[T„Š}{u{“““f]cMSSn…{{~’“…‹štts”š”tt{\UZJHF\[[|‚z|‚zś››ultlekf]cŚ‹“‚v‚›”›ddcekdJHFmtt…‹’{ttŠ}|{tt{||SKJkd\››”|‚ztzluztkd\j]\F=C\UZSKJ{||{u{kd\‚uttlltllult{u{ztl‚wl\[[{zm‹u…ztl”“›[TT\[b\[[\[[llklri}UTS\[[tllŠ}|mttiq]FD;]bZ‚ut}ddcVTLddcŚ‹“kd\{tt\UZ‹‹‹„„tslš””||›˘›‹’Štyg|„…‹„„f]cUMR\[bd\\|VTLUTS>B9JHFUUY3)JHF‹„‹j]\‚|u‘Ś…‚|uslecbVdc\jcVŠ}aWMSKJb[Udc\rg]‚nrg]d\\rg]lldb[U‹„„ztfaWMSKJlldd\\‘…„||VTLdc\j]\“““ÄÂżVZ[JHFŁśĄ˛¬µ””‹››”‘…„˘—Ť””‹tslu{{]bZ}†~‘^~Y3+*’ŚŚś¤¦Ś”•¦§¨™š¤}|‚zVTLiWUyle¦§¨Ł››‹„„|‚zŠ}|slesle‹‹„”š”|„…Š}“““\UZ]bZ›˘›|‚z„Š„¦§¨‹’Štzl{{llkš””„Š„mttj]\dc\{{t›”›tsltts‹„‹\UZttsJHFSKJd\\lriult{u{{tt‹’Š””‹||Ś‹“UMRd\\‚ut{ttŠ}lddldd[TT””‹‚utš””Š}ultkd\lddttstllUTSSKJUTSddc›”›’ŚŚb[Ulri|‚z}lriś››””‹sresreJHFldd|“““„„ŁśĄ”“›„Š„›˘›”š”ś››‹„‹{zm\[b{u{f]clrilri{||uzt{{…„’{{uzt}‡’„„\[bJHFVTLfkk|‚z…‹‹{{tult}Šlri‚wl{u{tsltyg›˘›mttlriVTLmw“~sle|‚zŚ”•bVU{zmVTLf]cŚ”•bVZlddŠ}|‚v{zllf]cSKJ‚utultŠ}zllllkcbVkd\{||b[U}Š}SKJSKJ“Ś”llkŚ‹“…‹‹…‹‹‹„‹]bZekdd\\f]cFD;VTLaWMcbVj]\ddc{u{\[b„„Ś”•‰‘~d\\ekd„Š„„Š„‹‹„‹„„ś››„„ŠŚŚšFD;|‚zŠ}|}Š}tt{D;9lksJHF:C+MSSJHF MRK’ŚŚttsi\Vlld{{tkd\f]crr]‹’Šrr]ultzllkd\VTLrg]VTLrg]j]\‚|uj]\FD;sletll‚u\[[{yf[TTUMRaWMŠ}|VTL‚|u‹’Š‚|uÂľĆUUYJHFŁśĄŁśĄŁ››“Ś”‚nŁ››¤¤ťVTL}JHF‹‹‹{{LKRr]gšŤŚ‹‹„|‚zŞł·”š”ś››‹„„kk]Ś‹“›˘››”››˘›Ś‹“”š”‹„„‹„„š””kk]…‹‹Ś”•|{||d\\lld”š”™š¤¦§¨{||{tttsl“Ś””“›}{||]bZ{{red‹’Štts|ldd{{lek]bZbVZlks„„|{{tllkŁ››””‹¦§¨¦§¨”“›|||‚z‚|u{tt‹‹„i\Vredd\\|‹„„’ŚŚj]\\[[tslŚ”•ŠŠ}[[T||lks\UZtt{sle‚v‚}|‚z‚|uf]cuztek]ztlkk]tslSKJ\[[{zm…‹‹ztl””‹Š}{zmuzt››””››fkktt{{{‹„‹tts[TTUTSlld[TTtts”››|„…„Š„mtt]bZtt{ekdtslllk‹‹‹ŠŠ}mttd\\UMRekdtlltllleku{{MRK]bZ|„…kd\|‚zkd\‚wlcbV|‚ztslekdlddttslldyleultzll…‹‹{tt‚utSKJzllŁ››“Ś”‹„„¦§¨‘Ś…‹‹„ttssle{tttslldd|„…{ttultlriuzt…‹‹VTLJHF[[TUTS‹„„FD;JHFkk]rg]|‚zś››‹„‹tsl|‚z|‚z›˘›{tt{{t”š”„„Š‹‹„ŁśĄ‹‹‹d\\tt{fkkVTLredtts[TT\UZ:97SKJVTLFD;:97%:97\[[dc\llk””‹ztlb[UjcV‘Ś…d\\kjVd\\aWMdc\VTLPF=SKJylelddVTLSKJVTLdc\{zmrg]{yfrg]bVZjV[zll‚wl{{t‚|u||‹‹„µ¶·\[[74,¦§¨Ł››””‹ŁśĄldd‘}rr]b[U}j]\lj}Š:97SKJztl”“››˘›»ÂÇŚ”•‚wl||llk‹„„ŁśĄ“~{||¦§¨¤¤ť‚v{‘…„kk]””‹›”›{{||ś¤¦’ŚŚ‹‹„””‹’ŚŚ{zm‘…„ŁśĄ“Ś”‹„„}{ttmtt[[Tf]cldd}‹„„{u{tllmttllkŠ}tts{{tsl‹’Š|„…VTL¦§¨››””››‚ut|‚z{||”š”rg]}{||sleVZTFD;red‰|vztfsle\[btslŚ‹“‹’Štts{ttldd‹…’[[Ttll””‹||ś¤¦‚u\UZultlldkd\cbVztlj]\bVU¤¤ť‹‹„lri‹„‹„„uzttsl|”››}‹…’{tt…‹‹‹„‹{{JHFiq]llk[[T{u{{{|„…mtt{{ttsekdVTLddc‹‹„|ttsj]\Š~‹ddc{ttf]c{||]bZMRKmttu{{|‚zŠ}{||tsl”š”llk‚|u…‹‹tsltts{tt\UZŚ”•{tt|„…bVUllkredrg]}ŁśĄ‚ut„„‰|v¦§¨””‹{tt‚utbVUd\\VTLtllttslks}}¾Ɯ¤¦ś¤¦|„…f]c{ttdkVkk]jV[‹’Šllkf]c{zmfkkVTLz‚ldkVś››ś¤¦”š”„„ŠŠ}|„…UTSekd:97r]gUTS:97ultedkJHFD;9dc\,553+*[[TD;9JHF[TTUTS‚|uŠŠ}{{t||zll{zm‚utrg]rg]kd\SKJVTLVTL[[TVTLVTLldd[TTVTLsre‚usreiq]VTLsle‚utred||lld‚wlztl|µ¶·\[b:97“““ŁśĄ‘Ś…‚wl{ttŠ}|‘}z‚lJHFś¤¦š””jcV.1SKJ“Ś”µ¶·‹’ŠŞÁŲ¬µ’…‹ultf]clld‚v{||‚v{™š¤|tll‚|u¤¤ť|‚z¦§¨Ś”•“““™š¤››”|‚wl‘…„›˘›{ttrfk}‡’ult“““ś››lritsl}””‹‹’Štzllrilks‹’ŠŚ‹“SKJf]c{tt””‹ŠŠ}UTS‹‹„‹„‹|‚zred{||‚v{‹„„tsl‚utb[Uztl{||[[Tzllkd\i\VlddŠŠ}ultuzt||”š”tllb[USKJ[[Tllk‚v{‹‹„yleldd’‘~[[TMRKkk]d\\SKJkk]j]\ŠŠ}””‹„Š„{{tultŠ}|tslu{{uzt{||¦§¨‚v{„„Š{u{{{|„…LKR\UZlddllk{{{{lksnv‚mtt‹’ŠUTSVTL]bZtt{llktll}ŚŚšŚ”•Š}|tslMRK]bZ]bZiq]]cdtzl[[Tsre{zm‹’Š{{t|„…|‚ztts||rg]„„f]c|‚v{dc\llkSKJ‚v{{ttŁ››}llkztl|‚ztslztf}j]\rfkŠŠ}sle\[[ultekd„Š„Ś”•{{{{lri…‹’z‚lJHFtzltslyle‹„‹|b[Uuztlrilrilld|‚zŚ”•„„Štt{™š¤„„Š]cdlrisreztlf]c{{“Ś”tll*)(SKJkd\VTL3+**)(D;93+*JHFJHF{{tztl‘Ś…Š}ztfVTLSKJjcVVTLSKJb[UVTLkk]jcV‚wlj]\kd\i\V[[Tkk]‚u{{ttslZbNzllr]Zzllyle””‹[TTkd\{{tµ¶·LKRLKR›”›‹‹‹›˘›ŁśĄf]c‘}˘—Ť„Š}tt{““““Ś”j]\JHFUTS’…‹Ś‹“„Š„¦§¨¨©´˛««™‹†ldd]bZ‚|u‹’Š|‚z{{tred[TTsleŁ››mttmttuztš””{{t|‚z‹‹„{{t’ŚŚ|„…¤¤ť›”››”›{{{{t„Š}{||{||ult¤¤ť‹‹‹lld\UZllk{||lddb[Ud\\‚v{uzt‚ut„„Šlri{||dc\jcV{{llk||„„{tt\[[kd\{ttb[U|tsl||sleSKJ‹‹„›”›””‹r]glldf]c\UZVTLŠ}|„„{{tVTL{ttlksSKJtsl[[TJHFš””‹…’‹’Š{{tlri„„…‹‹mttuztuzt|‚z|„…ultllk{{“Ś”{{lks{{}|„…edk{{ś¤¦|„…Ś”•‹„„{||sleddcddclld|f]cŚ‹“…„’¤¤ť{tttslVTLVZ[tzl‹…’„„tsl“““‹‹„{ttddc…‹‹|„…|‚z””‹„Š}‚ut|‹‹‹mwUTS{{tslelek‚v{Š}Š}tts‚utsre\[[b[U{ttŠ}‹…’“““{{tsle„„‹‹‹lksd\\ldduzt„„ŠŚ”•mtt‹„‹ś¤¦„Š}[TT|‚zttsŚ‹“”š”JHFz}››”llk|„…™š¤Ś”•“Ś”{{\UZek][[T||š””tlllks|mttSKJzllekd\[b?;CFD;"[TT„„slei\Vsle‚utVTLrr]bVUPF=VTLjcVd\\lldVTLsrelddi\VVTLSKJ‚wlz‚lŠ}|lrirg]b[U{ttbVU‚ut‰|v’ŚŚ‚|ukk]|‚z¦§¨VZTUTSult„„””‹‘}zrg]‘Ś…‚u–˘‹„Š„j]\j]\bVUMRKSKJ{tt¨©´ś¤¦›˘›”“›µ¶·Ł››‚ut””‹ztl‹„„{{t··Ä|‚zŠ}‚|usle‹‹‹u{{‹’Š{||{tt‚u{zm{tt‹„‹””‹|š””{||Š}™š¤‹‹‹{ttlri¦§¨’ŚŚ™š¤‚|u‚v{d\\lek\[[]bZ[TTf]c„Š}uzt„„bVZ“Ś”||‚wldc\lddd\\‹’Š{zmtlltsl‹„„{ttj]\ztf„Š„kk]SKJŠ}|„…Ł››››”{tt{ttJHF[TTd\\ult’…‹ekdJHF[[TSKJ\UZdc\dc\SKJVTLultult‚|uµ¶·u{{{u{…‹‹|„…‹’Š››”|‚z„„Š{ttŚŚš„„ŠŁť˛‹…’\[b\UZult™š¤lksu{{ŚŚš{u{Ś”•kjVu{{\UZJHFj]\]bZ]cd\UZ{tt‹„‹‹„‹„Š}””‹…‹‹tzldc\Ś”•™š¤‹‹„››”{{t’ŚŚ{||sre|‚z‚|uredf]cSKJś¤¦llkf]cVTLJHFSKJbVUŠ~‹yleš””bVZFD;kd\{yf””‹d\\{zmzll‹‹‹|rfku{{d\\r]g{{tf]cJHFultf]c„Š„]bZ]bZek]{{t‹„‹\[[{{{{llkf]csle„„„Š„‹‹‹tt{ŚŚš„Š„edk{{t“““ldd‚|u‹„‹|„…jcV{||ekd\[[VZT[TTF=CFD;74,lldf]ctll‚wl|‚utVTL[[TVTLb[UVTLb[Ulrikk]bVZddc„„SKJsle{ttVTL{zm‚u|‚ztsllldlddtll‚v{rr]‚wlztf{{t‚wl¦§¨fkkMRKttsŁ››Š}|‹„„tzl’…‹‹’Š””‹}jcVVTL|‚zF=C?;C¤¤ť›˘›„Š„…‹‹}›˘›tslsle|„„šŤŚ|‚z”š”””‹Š}¦§¨‹‹„‚u]bZ‹’Š…‹‹”››|{{t||“Ś”rfk˛¬µ¤¤ť{u{tsl¦§¨™š¤lddekdŁśĄ||Ś‹“››””“›d\\}ŠlldllkbVUzll¤¤ť|‚z[[Tsreult‚uldd‹„„tsl‚wl‚|u{{t…‹‹tslf]cekdPF=bVUŠŠ}j]\[[T’ŚŚ}Šlddtt{f]c{tt:97lldUMRultekd]cdVTLbVUbVZfkk|„…ztltslSKJ{tttsllri‹‹„‚|u{{lri‹‹„„Š„‹‹„ś››‹‹‹„„fkklkstt{JHFVZ[›˘›g\rmtt\[b{{tt{„„ś¤¦d\\[[TVTLVTL{zmcbVtts{u{bVU{u{‹‹‹››”“““uztVZTttsuztuzt„Š„ldd””‹››”f]c„Š}„Š„[TTtsl‹’ŠMRK[[T{{‚v{d\\||tsl‘…„’ŚŚ’ŚŚf]c››”‚utrg]VTLkd\’…‹{{tlek[[TŠ}tygllk””‹ljVTL[TT\[[|‚zldd|dc\lri”››‹‹‹„„edkekd]cd{{\UZ[[TŠ}|uzt“““Ś”•{{tmttttsŚ”•lriVTLsle…‹‹lldr]ZD;93+*|‚zkd\{yfFD;JHFSKJjcVMRK‚|u|dc\‚utkk]SKJtsl]bZbVUkjVsre[[TtllD;9aWMslesreultj]\sre””‹‚usreredtts‚utŁ››ult‚wl‚u{{t‘…„µ¶·]cdMRK‹„„“Ś”’ŚŚŁ››Ł››™š¤Şł·š…Ž\[[{ttldd]bZ]bZzll‚wl|‹„‹„Š„Š}””‹||SKJFD;š””‹‹„Š}„Š„‚u“Ś”š””{tt”››tll‹’ŠŚ”•‹„„{{tŠŠ}|tll||Ł››|‚z„„¤¤ťred{||cbV]bZ{u{ŁśĄ›˘›¦§¨ztl\UZ}Š¨©´|‚zŠ}‹…’{||tsl„„dc\š””¤¤ť{tt“Ś”‹‹‹||Š}‹‹„“““slekd\ultsleztlult‰|vtll{ttllktllredUMRtslVTLtts{tt…‹‹{ttekd]bZaWMred‹„„llk|‹‹‹””‹kd\Ś”•‚uś››¤¤ť”“›‚|u„„”“›‹’Š„Š„{||ultlek„Š„{{ddc]cdf]ctslŚ”•{{“Ś”lks{{…‹’j]\VTLFD;[[Tldd|‹‹‹ultllk{||„„Šlri|{{t{{t{|||‚zd\\‘Ś…‹‹„tzl””‹{{t|‚z‚u‹‹„Š}[[T3+*lektllyfltsld\\lddŠ}|‚ut{tt‚wl{u{VTLcbVŠ}||‹„‹‹‹„[TTVTLVZT‚ut„„tsl…‹‹{u{{yfmtt\[[{u{kjVŠ}|„„“Ś”¦§¨“““™š¤tzl|„…lkslldkd\„„Šllku{{‹‹„‹‹„|‚ztt{””‹VTL‚usleJHFbVUUTS:97UTSD;9VTLiq]JHF%PF=b[Ulekrg]„Š}|‚z||‚|utslkk]kjVVTLdc\llkdc\JHFb[Ukd\[[Tb[U{tt‚wl‚wl‰vtsl{zmš…Žred˛««‰|v¤¤ťsleŠŠ}‘}‹‹‹¦§¨\[[JHFŚ”•¦§¨“Ś”‹„„ŠŠ}‹’Š‹’Šultdc\dc\‹„„kd\VTL’}™Ł›››˘›””‹«˛«…‹’{{[[Tdc\b[U¦§¨””‹kd\›˘›lri’ŚŚ||””‹Š}tzluzt|‚z™š¤sre›˘›””‹tllr]gz‚l‹‹„lri””‹¤¤ť››”‚|u”“›Š}š””””‹ŠŠ}„„‹‹„|‚zttsVZTŠ}|{{tsl[[T‚|u‘Ś…ŠŠ}‹‹„||llk“Ś”tll|‘Ś…tslŠ}Š}lddred‹„„aWMtll„„cbVJHF[TTult{u{j]\UTSllk„Š„Ś‹“ztl|„…››”tzlkd\ult„„{{tŚ”•’ŚŚ‘…„›˘›ztltslkk]‚|u‹„‹{||lkscbV””‹mttŠŠ}›”›‹…’lksJHFuztmtt|„…ulttt{ŚŚš…‹š„Š„{||mtt\[[{zmSKJMRKlek‘…„ult„Š„„„Šult[TTlritsl|‚ztsllri…‹’{tt””‹µ¶·„„Ś‹““““‹‹„|š””|‚zdc\b[Uedkrfkred‹‹„[TT}Š}‹„„Ś‹“””‹‚v{[TTkk]‚|u‚ut‰‰w‚v{lld||SKJd\\tll{||j]\mtt„Š}„„tsl{zmztl|‚zŞł·¤¤ť“““}f]c]bZu{{{tt||ztlred…‹’‹‹‹u{{Ś”•Ś‹“””‹tsl‹‹„‚u|‚z|UMR7-2SKJFD;MRKLKRtt{3+*73JHF[[T‚utsledkV[TTPF=VTLFD;bVZ‚u‚|u{zmtsl]bZ{||i\VztlSKJ‹‹‹edk„Š„¤¤ť‚wl|‚zr]Zljzll‰|vlj‚|uŠ}|‚v{¦§¨[TT:97„„tsl’ŚŚ‚uuztŁ››Ś”•””‹„Š„\[[Š}|lld]cd“~””‹›˘›””‹””‹f]c[TTb[Uyletzl{{ztl„Š„””‹[TT“Ś”bVU|’ŚŚ{{tddc”š”‹„‹lrisreVTLtllult‹‹„kd\Ś”•”š”‚uš””‹„‹|‚z™š¤””‹{zmŠ}›˘›lritzl{tt‹’Š¤¤ť‹‹‹„„{{ttslkk]ŠŠ}red‘Ś…“Ś”tsl‚ut’ŚŚztllri{zmaWM‚ujcVd\\SKJVTLkd\{u{\[[lri{{tf]cSKJ{{[TTrfktts||lri’ŚŚ’ŚŚyfllek‹‹„{{tult{ttsresre{zmŠŠ}sretll‹„„{||lri‹„„kk]{||{{t“Ś”ultf]cVTLVZ[|‚z]cdmtt‹…’llk„„Š}Šttsdc\MRKjcVtslztl””‹ultf]ctslultŁ››Š}„Š„dc\|‚zVTLttsult||’…‹‹‹„››”›˘›„Š„Ś‹“‚|uztliq]lriSKJu{{UMR|‚zSKJf]cŠ}’ŚŚ‹‹‹‹…’{||}f]csre{u{lddŠ}ultuzt\UZVTLlrilld‹‹‹{u{ddcek]lddkk]b[Usle„Š„}’…‹‹…’’ŚŚś¤¦‹…’\[b””‹{zm…„’ztl{||‹‹‹|‚z„„„Š„„Š}]bZ‚u}|‚zttsmttlks[[TVTLFD;74,UTS3):97iq]dc\|‚z{{tVTL‘…„‚|u„„cbV[TTVTL|‚zsle\[[VTL‚|uztlŠ}|edktll‚wl‚|utsllldd\\d\\Š}|ztl||‚u{zm‚u‚v{Ł››UTS*)(‹‹‹“““‘Ś…ztfVTL‰|vlriVTL”š”llkr]Zb[U:973+*‹’Šś››¦§¨rfkyfl‚|ubVUVTLFD;red|””‹››”ultult‹„‹”“›Ś”•‹’ŠŹˇˇ¨©´Ś‹“{{ttslŁśĄ‚v{lri¦§¨‹‹„…‹‹‹‹‹““““Ś”‹‹‹lks™š¤™š¤‹„„””‹”š”„Š„uzt›˘›”š”””‹tt{‘}zedkaWMek]‚|uztfzll‹„„|tll{tt‚wlkd\rg]sleŠ}|ztllrir]gSKJf]cb[Uekd‚|u{ttŚ‹“d\\UTSult‹‹‹„„‹„„tslsle|kd\uzt‹…’„Š„lkskd\SKJlld””‹|‚zlld…‹’‹„„„Š„Ś”•{{tzllldlldŠ}ddcf]clksJHF]bZmtt\[[tt{}Š{{u{{…‹‹bVZFD;tslddclld‚|uu{{lks{{t„„|’ŚŚ{{tuztekdUTSŠ~‹ztlŚŚštt{‹‹„Ł››‹„„uztŚ‹“{{tztlŠ}kjVuztŚ‹“ultjV[””‹‰|vjV[‚v‚||„„Š‚utf]c{{tcbV|{||‘Ś…“Ś”ztfultb[Uttstll””‹ddc„„MRKlriVTLFD;lld|„…llk{u{llkš””’ŚŚ™š¤“Ś”mttś¤¦„„‹‹„‹…’™š¤llkŚ”•tt{ŠŠ}”š”¦§¨“Ś”lriekd]cdf]cbVUVTL>B9FD;:97FD;&&C8.{{t„Š}‹‹„kk]ultsleulttslJHFVTLVTLsre]bZVTLbVZlldlddcbVlld’ŚŚ„Š}‚wlttskk]||||Š}|‚wlbVU‚|usrei\V‚|u‘}>B9:97››”„„‘Ś…””‹jV[bVZu{{i\Vekdllkkd\aWMVTLJHF¤¤ť™š¤™š¤|„…tts{u{sle\[[tzlr]gtslldd|‚z’ŚŚ||“““ŁśĄ||lri|‚z|™š¤‹‹„SKJ„Š}™š¤{|||‚zkk]tsl|„…“““„„Š}VZ[™š¤‹„‹›”›’ŚŚ‹‹„‹’Š|„…{zm}””‹„Š„ztflld{zm{||„Š}SKJb[U„„|[TTredzllztlldd‚uylelj{u{tll||llktll„„””‹„„ultb[U{{JHFtsl{||lri‚u‚v{]bZ}|„…Š}u{{tts‚wlsle‚|ulld‹’Š¦§¨‹„„}„Š„ztlŠ}|‚udc\ekd’…‹rfk{{mttF=C>EC]bZf]c”“›…‹’…‹š„„”››dc\\[bVTLVTLUTS‚|ui\VF=Clld‹„‹‹‹„Şł·‹’Šiq]dc\[[T„„||{||šŤŚ‚u›˘›„„Šuztuzttsl””‹›˘›Ś”•]bZ™š¤redult|rg]f]c[TT|„…‚v{Ś”•}|‚z‚|u‚v{Š}|{zm||„„redbVUUTS{u{lld|||„…lri|‚z‹‹‹kd\d\\kk]u{{ult\UZšŤŚtts\UZtt{…‹’¨©´’ŚŚ™š¤”››‹„„u{{{||‹‹‹”››„„¤¤ť‹„„lrilld>EC%FD;74,FD;SKJVZT3+*&&C8.yle|‚z|||‚z‘Ś…Š}JHFJHFlri]bZVTL:97VTL{u{tzlŠ}lddrfkllk{zmlri|VTL‘Ś…rfkŠ}‰|v{u{””‹Š}‚utztfµ¶·MRK*)(‹’Š‚ut|‚z‘}{zmJHF|‚zllkuztlekttsi\VD;9D;9‹‹„«˛«ŠŠ}Ś‹“””‹{{cbV[TT‹’Šedk‹‹„||¤¤ť’ŚŚ™‹†‹‹‹’…‹b[U„„lri¦§¨Şł·””‹kk]Ś”•”“›ddclldVTLekdSKJj]\F=Cj]\{{„„Š„„››”’ŚŚsle]bZlld{zm‹‹‹””‹‹’Šrg]ddcf]cj]\‹‹‹š””“Ś”j]\ddclddŠ}š””tzlztlsle}‚ut{||Š~‹“Ś”fkkŠ}|„…tslmttf]ctslUMRSKJ‹„‹lksslef]clddddc{{Ś”•‹„‹tsl„„tts’ŚŚlriuzttslz‚l{||‚utsre||’ŚŚ…‹‹uztVTLtllultddcedkekdLKRu{{lkstts…‹’ś››Ś‹“”“›{tt{{j]\MRKVZTrfklektsluzt}“Ś”“““ttstsllks‹„„…‹’„Š„tts|lldŚŚšŚ”•‹‹‹{||ldd“Ś”‰‘~„Š}mtt{{“Ś”ŁśĄ‹’Š‹„„lek‹‹‹||tts”“›‹„„||‘Ś…‚wl››”Ł››b[U\UZtllrfkldd‚v{”››”››|‚z}„Š„j]\‚|uSKJ{{JHFddcredult„„Štt{ult‹„‹{zmµ¶·”››ultldd‹‹‹…‹‹”››‹„„¤¤ť‚utlldllk]bZ:97aWM3+*C8.Q?@F=C%&&&tlllri{zm‘Ś…VTL||VTL|ztl{u{JHFVTLlldJHF\UZ[TTtsllddtlld\\tts[[Tsre[[TVTLkd\kd\ŠŠ}Ł››Ł››rg]Š}sle‚utµ¶·MSS:97tsl|“““‚wlekdJHF|‚ztt{uztdc\|„…rg]74,bVU…‹‹”››””‹“““UTS{||ddcekdlritsl‹‹‹’ŚŚ‹‹‹‹‹‹Š}sle„„””‹llkVZ[‹’Šś››‹’Š{tt\UZ„Š„{|||VTLSKJ]bZ’ŚŚś›››”›FD;[TT“Ś”¤¤ť¤¤ť‹„‹‹‹„ś¤¦””‹|‚z¤¤ťmttrg]tts‘…„‹‹‹d\\rg]Š}|{tt„„‹„„kk]tsllldtsl‚v{{zmkd\ldd’ŚŚ„„mtt„Š}}Š‹„„„„{u{f]cultUMRztlult’ŚŚj]\Š}kd\llk||lri„„Š{||ttsf]c[[Tsre„„‹‹„‹‹„{tt””‹{||ttstsl{tt{||‹‹„Š}lek{ttuztMSSmtt“Ś”{u{ek]{u{{u{f]ckd\lddd\\SKJtsl’ŚŚf]cdc\{{t[[Ttllf]c\[[u{{mtt{||ekd‰|vŚ”•kd\””‹‚|u›˘›˛¬µ„„Ś‹“‹‹„{ttVTL[[TVZTlri‚|uś¤¦Š}“Ś””››|{u{tsl{u{{tt‹‹„‹„„‚|u|‚zllkultlddslej]\{u{j]\‹‹‹}„„tzl“““‹‹„Š}UMR[[Tj]\{tt‹„„ultf]c\UZ‹‹‹slerg]‹‹‹f]c{tt„‰v‹’Šfkk””‹f]ctsl\UZŠ}{u{{{:97lldmttF=CFD;>B9FD;|‚zj]\|‚z|‚z‚wlsletzlaWMrfk[[T[TTlri{zm\UZ‹’ŠlddcbVtsllldSKJttsttsVTL[[Ttllsre[[Td\\{zmrg]lldrg]|‰|v{zmĂÄĆJHF3+*{{t””‹”š”˘—Ťrr][TT”“›|„…|llk{{t‚|uC8.JHF{{t“““uztś››{{t”“›}lksdkVŚ‹“lld‹’Š‹‹„|‹‹„¦§¨ś¤¦\[[|„…„„‹„„ŁśĄztl‹‹‹“““tzl””‹|‚z“Ś”lriŁśĄ}{u{‚utultŞł·{{t’ŚŚ‹„„‹’Š‹‹‹tslkd\””‹jcVš””‘Ś…|‚|usle„„‘…„r]gyledc\d\\‚|ulld{{tsletllrfklddllkyleś¤¦ekd{u{edktzl{zmlekf]c{{VTLrfk‹…’””‹]bZ|‚z[TTŚ”•{u{„„tzl”š”fkk{{t””‹redlri””‹‚v{lld[[Ttslzll’ŚŚ|‚z{{t}’ŚŚ…‹’lek{||Ś—ŁŁ››‹…’Ś‹“{{{{{u{ttsttsfkkd\\\[[‹’Š™š¤zll{u{››”||||¤¤ť]cd|„……‹‹“Ś”|„…››”Ś”•‚ut|tsl“Ś”””‹Ś”•ś››””‹„„JHFmtt{{t…„’‹’Šś¤¦«˛«‘Ś…‚uult””‹“Ś”tt{kd\{zm’ŚŚ‘Ś…sre{u{\UZlekult’ŚŚ“Ś”š””‹„„|„…lrirg]””‹iq]||“““ttsldd‹„‹[TT“Ś”ult||lldredlld‚v{“Ś”Ś”•||“Ś”„„¤¤ťkk]u{{“Ś”VTLb[U…‹‹\[bSKJ{{r]gUMR‚uVTL]bZJHF\[b{||‚|u“Ś”dc\kk]ultrg]\UZtsl„Š„tzlddclddu{{tts{{tVTLredUTSUTS]bZdc\]bZrg]SKJrg]{yfkd\i\VSKJsreldd¦§¨SKJ:97””‹‹„„{zm‘Ś…]bZttslri„Š„‚ukd\dc\rg]PF=bVU‚v{ś››”š”ś¤¦ztl”“›Š}tsl„Š„”››||“““¦§¨‹…’‚ut{||ddc‹‹‹b[Utts””‹Ś‹“lddkd\lrilritzlŚ”•‚u„„Š‹„‹µ¶·„„Š“Ś”tts¨©´Š~‹Ł››d\\dc\ldd…‹‹jcVVTL{{t{ttztltsl|ztl{{t’ŚŚŠ}|Š}rg]mw{zm{zmredrg]‚v{lddred”“›ult‚v{fkkd\\‹„‹kk]|‹‹„‹„‹lek\[[kd\}tll„„|‚zek]uztŠ}uztlri‚|ufkk|”š”{tttsl|{tt“““‹’Š“““ldd|”š”‹’Š™š¤ulttllb[Ukk]|„…ś¤¦™š¤Ś”•ŁśĄfkk|‚z‹‹‹{tt[[Tslelri„„Š|‚zŚ”•¦§¨‹’Š{||‹…’{{tVZTdc\\UZ|„…|„…llkŚ‹“„„“Ś”‹‹„ŁśĄ}›˘›||ekdttstts”“›{u{””‹{{tttsztluztŁ››‹„‹‚v{tlld\\sre‹’Š’ŚŚ‘Ś…{tt‹„„d\\Š}{{tldd[TT…‹‹lldbVU’ŚŚ›”›tll‚utllktzl‚|ubVZlekllkSKJlri[TTttsd\\{zm’ŚŚ¨©´„„Š||„„“““›”›‹‹„tllbVZkd\„Š}]cdu{{:97{{JHFD;9”š”|„…]bZ:97dc\{||rg]‚wlekdtslztlllkultsrettsŠ}|mtt{{{tt|‚zš””{||||d\\slesrett{ŠŠ}b[Ub[UcbVrg]””‹cbVjcV‚wlrg]µ¶·ddc*)(‹’Šś››„Š„zll›˘›u{{lld„„ŠsleUTScbV{zmHI/ultult¤¤ť‹’Š‹’Šred™š¤f]c{zm‹‹‹tts{{t”››‹„„Ł››ult¦§¨ult…‹’dc\{||tts¨©´”š”„Š„„Š}…‹‹Ś”•||cbVtt{{{ŁśĄtts‚ut‚v‚ddc”“›š””||f]c‹‹‹UTSkk]lldVTL{{t|‚|ud\\ztlsre||‘Ś…‰vbVU‚utlrilldVTLVTLd\\kd\b[U]bZ’…‹{{JHFd\\ultek]tsl||}lri]bZdc\lek]cduzt{{kd\b[UUTSult„Š}slelek””‹ek]‹„„tsl{{tred{{t{zmj]\lkscbV{{t|‚zult’…‹kd\lekUTS{{ekd{{”“›“Ś”{||„„ś¤¦‹‹‹‹„„›”›„Š„‹’Š{||tll„„ek]tt{}{||‹’Šlldlek{{Ś”•tslŚ”•‹’Š’ŚŚ›˘›“““”“›”š”||‚zmttf]c]cd…‹šddcztl|„…‚u|‚zuzt„„Š‹„‹{{f]clks|¤¤ť«˛«››””š”„„Š{u{zllult‹‹‹fkk“Ś”’ŚŚ‹„‹‹„„tlllldsle‚|uŁ››{{||lrildd‚|ubVUttsultztfŠ}tll…‹‹rfk{{t…‹‹‹„„cbV{||mtt|UTS]bZUMRD;9\[bekdzllVTL{ttedkSKJ>B9f]c{zmredVTL„Š}Š}b[U\[[{{fkk‹‹‹{||lks{{[[Tllkdc\dc\‹‹‹u{{Š}‹„„„Š„dc\lri‹‹„{zm””‹›˘›ljsle‰‘~˛««[TT:97››”””‹¦§¨’ŚŚuztttsj]\f]cVTLbVU{{t{ttFD;JHFyfl‘Ś…zllmtttsldc\d\\kk]”š”“““‹„„”››””‹…‹‹šŤŚŚ‹“lks‹’ŠŠ}llk„Š„µ¶·ś¤¦…‹’{|||‚z|„…{||„„uzt‹„‹”“›ultšŤŚlrittsś¤¦’ŚŚ{tt„Š„ult{||sleŠŠ}Ł››{zmslesreVTLtllsre’…‹i\V‚wlultš””lldztllldtllkd\VTLSKJ|}lektslzlllriVTLd\\{ttultuzt\[[VTLrfkttsttsuztkd\b[Ulri}{zmrfkJHFJHF74,b[U{{tVTLllktslsrelri‚utsl|‚z‹„„ult‹…’bVU{u{ekdmttfkkŁśĄ}ŠŚ‹“¦§¨{{u{{f]c}JHFcbVllk‹’Š„Š}{||‹„„…‹‹Ł››{||lldŠ}|„…Ś”•Ś”•|‚z…‹’„„‘…„‹’ŠŠ}|{{u{{JHF]bZredyl„lksllksreztf|‚z’ŚŚ’ŚŚ¤¤ť{{t{u{‹…šf]cd\\lldsle‹‹„|‚z„Š„Ś‹“\[[tllztlred“““{ttŠ}tll…‹‹ek]bVUtsl‹‹‹˛««š””‚v‚{{Š}|ultekdlek‹„„yle‹„„ś››ś››lld‹‹‹“Ś”tzl{||slemttuztMRKVTLJHFFD;FD;tzlD;9lldsre]cdJHFJHFddcaWMrg]VTLtsl|edklddlek{{llkUTSddc{tttzlult{||llkultŠ}|„„‹‹„{{tSKJi\V””‹{zm””‹Ł››¤¤ť{||ŠŠ}‹‹‹VTL:97‘Ś…„Š„‹„„‰v‹‹„„„‹‹‹[TTjcVkk]kk]VTLbVU%UTStsl|…‹’{{tlrid\\lksuztś¤¦ldd””‹“Ś”{||¤¤ť“Ś”“““””‹}”››››”ŁśĄz‚l¦§¨‹„‹ekddc\||…‹‹„„\UZultkd\‚v{VTLddc”š”lek›”›“““ś››lld›˘›ult‹„„kd\rg]‚|u{{tlddlrid\\ŠŠ}›”›‚wlred\[[sref]c‚|uVTLSKJVTL‚|uultredfkkd\\|„…dc\lldlektlllld[[T‚v{f]c{ttlri„Š„d\\zlllriultztl\[buztddclldrfkuztcbVllk‹‹„„Š„Š}{||ldd}|‚z||Š}mttŚ‹“lks|„…”››tsl]bZ|„…tts}Štts\UZtts]bZultlldlks‚|u||tlllddŁśĄ„„llk…‹‹‰Šˇ}ŠfkkŚ”•„Š„‹‹‹lld››”“Ś”‹’Š‹‹„›˘›\[b„Š„lldtt{d\\dc\„Š}„„‰|v‚|u‹’Š„„Š„„‹„‹edk{||[[T‹‹„{{t|‹„„‹’Š™š¤’ŚŚr]gŠ}|‹„‹‹„„ś››{{|‚zrg]llk‹‹„‚|u}„„„„||rfk“Ś”‹‹‹tt{{u{zllkd\Š}|tt{sre‹’Štll|\UZddcek]…‹‹‹„„|‚z\[b>B9\[[ddc\UZVTLJHFC8.JHFFD;ddcylecbVztllriztlllkddclek{ttttsllkllktts””‹‹„„ddclek{tt|„…tsl’ŚŚsrerfkcbV‰v‰|vŁ››””‹‰|v“Ś”‚|u¤¤ťVZ[JHF‚|u{{tś››Š}||{{™š¤†~‘lldtllkk]‰vsleD;9UMRultsle{{t‹‹„“““uztu{{Ś”•“““››””š”™š¤‘…„ult‚utldd[[T’ŚŚddcŚ‹“‹‹„“““Ś”•š””tts”››‹‹„Ś‹“”››ś¤¦“Ś”Š}¦§¨b[UllkŚ”•ŁśĄ›”›|‚ztslś¤¦llklldlldrg]cbV‚|uVTLj]\{{tztlztl‹‹„red“Ś”d\\‚u‹’Š{ttFD;cbV{{t¤¤ť’ŚŚultztlSKJ]bZMRKkk]}“Ś”u{{tsl››”“Ś”‹’Š|‚zu{{Š}‹‹‹tts}ylef]c›˘›]cdlridc\”››‹’Š{ttś¤¦{zmultlld{||tllllk{u{„„[[Tdc\]cdlks…‹’lks‹’Š{{tt{lks‹uŠbVZldd\[[{tt\[[]cd‚ut}Štll}“““‹’Š|Ś”•‹…’lks··Ä‹’Š‹’Š“Ś”’ŚŚkk]“Ś”›”›ttsuztllk{{t{||edkJHF“““‘Ś…”“›‚utuzt””‹›”›lek‚v{Š~‹tlltsl’ŚŚlri|‹„„”“›||ultj]\‚|utts{ttldd||b[Usleš””lri””‹“““{||Ś‹“|”“›“Ś”|‹„‹“Ś”||š””“““{{tslemttjV[tsl‹’ŠŚŚšllkmttSKJMRK]cdJHFD;9JHFSKJD;9fkkaWMedk‚v{ddcrg]{zm››”lld{zm„Š„tts„„Š{u{bVU|‚ztll}“““|„…‹„‹lddttsŠ}lldŚ‹“tslrg]b[U|ztl|‰|v‘}rg]››”µ¶·UUYLKR‰v¤¤ťŠ}™‹†|[TT{ttuzt‚|u„„i\Vrg]FD;VTL[TT{||dc\|‚z||tts]bZ\UZ››”’ŚŚŠ}ś¤¦„„‹„‹‹’Š’…‹‹’Š|„…tt{dc\}„„„Š}jcVzll…‹‹lri¦§¨‹„‹„Š„„„lks“““›”›ekd‹…’‹‹„¦§¨¦§¨”š”d\\lks›˘›tslŠŠ}srerfksre{{t‘Ś…””‹‚ut‹„„›”›jV[Š}{||‚u||tzlek]cbVmtt[[T‹„„lekSKJlld|‚z››”’ŚŚ’…‹‚ut|‚z[TT””‹…‹‹tsl|„…‹‹‹slelldFD;sre||“Ś”|‚z„„{{t‚|u„„|”“›‹‹„‹‹„‹„‹ŁśĄ“Ś”‚v{‹’ŠŠ}{ttultuzt|„…MSSmttu{{ttsllklkstt{{||Š}lekuzt‚uddculttts„„{{™š¤ldd”“›”š”™š¤··Ä„„Š|‚zfkk“““‹…’”š”tslztl|uzt‹’ŠŚ‹“‹„‹‹…’tlllekdc\‹„„‹’Š“Ś”‘…„‹’Š›”›’…‹¨©´||VTL„Š}|||Ś”•{ttŚ‹“”“›””‹tts“Ś”u{{||„„’…‹‘Ś…‚wllks|‚zkk]}sle“Ś”Š~‹‚v{ś¤¦redrfkn’…‹Ł››“Ś”tslŚ”•cbVztl‚u{||ŚŚš||UTSFD;ZbN:97:97SKJ[TTcbVsreSKJVTL[[T{u{[TTsleult‚wlcbVŚ”•dc\{ttlek„„ztlnv‚mtt}‹‹„„„tllf]clddcbVdc\‹„‹kk]‘}||‚u””‹””‹‚wl‚|uŁ››“““¤¤ť\UZ>ECztf›˘›‹„„rg]iq][[TŠ}llkztlkd\tts””‹redFD;{tt{tt‘…„|„…|‚zŚ”•ekd{{‹„„|||¦§¨¨©´˛¬µŁ››“Ś”‹’Šmtt„„tll{{tekd››”kk]Ś‹“‹‹„„„™š¤tt{”››‹„„Ś‹“‚ut“Ś””š”ekd’ŚŚŚ‹“‘Ś…{{t””‹tt{„„”š”‹‹„””‹Š}|‹„„{{tjcV|||””‹‚wl{{t\[[d\\lld{||iq]rfk„‰vdc\d\\[TT\[[tts””‹llk|„…š””’ŚŚ‚v{„„f]csle{u{|…‹’lldSKJd\\tll‹‹‹‚|uŁśĄztflld‹‹„””‹uzt{{t“Ś”Ś”•‹„„|„…‹„„ś››„„Ś”•ztlbVZddctsllld}‡’|‚z{{ddcŚ”•„„lks}ddc“““\[[{||tt{{{””‹‹„‹„„ŠšŤŚ{tt“““||¨©´™š¤›˘›lkstt{„„…„’””‹{{t{u{ś››”“›Ś”•„„Š…‹‹‹„‹™š¤lriztlrfkf]czllztltsl›˘›}„„ultldd|‚z||‹‹‹dc\‹‹„ŁśĄš””b[Ukd\{zmtslŠ}|Ś‹“‹„„””‹||}lriSKJrfkultf]c}“““lks‚|u™š¤}š””Š}|||Š}‹‹„„Š„””‹{zm}Š|‚z’ŚŚttsb[Ullk\[bFD;%UMR[TTtzlJHFVTL’VTLlriŠ}|kd\Š}|llkttsllkddcllk|ult{{{u{„Š„Ś‹“u{{lksult‹‹‹‹„‹{||‚u{tt››”¤¤ť””‹‚|u‚v{¦§¨‰|v‹’Š›”›UMRJHF{{t””‹j]\‚|uttsb[Ub[Ured‰|v‚|u{ttztlD;9FD;{{“Ś”sle|‚z‹‹„ś¤¦llk[TT|‚z“Ś”‹„‹„Š„‚v‚µ¶·››”|„…ś¤¦mtt…‹‹|‚z”š”|„…{{t„„{||”“›{||„„lkskd\f]c{u{‘Ś…{tt‹„„}¨©´{ttrg]‚|uldd{u{Š}|tllkk]tsl’…‹[[TVTLš””|‚z“Ś”‘Ś…‰‘~‰‰wtlllritsld\\JHF’ŚŚ|tsl||{tttts\[bekdllktsl‘Ś…‚|u‹„„lritlllek‹„‹|‚zdc\‹‹„lldttsd\\‹„„bVUtlltts[[T[TT{{ttsVTL{u{›˘›lridc\Š}||||‹‹„lddf]c{{t”š”{{mttfkklldmttuzttt{lksVZ[{||ztlVZT|llkultŚ”•’ŚŚ\[b‚v{‹’Š«˛«||™š¤¦§¨¦§¨Ś‹“{{u{{™š¤”“›|›”›|‹„‹|„…µ¶·›˘›™š¤„„Š™š¤‹’Šf]csre‹„‹tllllkkd\‹„‹‹„‹{||d\\llkult””‹tts‹‹„]bZ‹„„lld[[TSKJult‚v{{||’ŚŚ“““{||“Ś”tzli\V{tt„Š„Š}‹„„š””fkk\UZ{u{tll||red„„””‹„„„‰vuztdc\{||ekdj]\tlllddVTLMRK[[T>B9\[[kd\tsl\[[MRK*)(u{{{||redj]\‹‹„ś››ttsekd[TT[TTddc‹„„edk\[[tts|‚ztts|„…„„Šlek„Š„ldd}‰‘~‰v‹‹„››”””‹””‹ ŤŤ™‹†tll””‹µ¶·\[[,55‹‹„|‹’ŠjcVz‚l]bZttsztl|‚utFD;sref]cVTL‹„‹“Ś”d\\ś¤¦››”ś¤¦„„Š™š¤lek”“›‘…„”“›tts“Ś”Şł·Şł·¨©´ÂĹÓ›˘›Şł·”››„„””‹|‚z“““{{tf]cultŚ‹“|{ttd\\Š}Ś‹“tzl„„Š”“›}tll|redu{{zllkd\‚wl|‹„„„Š}›”›i\V‰‰w‹„„Š}{zm|||lldbVUttsb[U|tygredzll‚v{\UZ[[Tkk]{{lks››”kd\rr]lld‹„‹uztmwś››||„Š„d\\ddcultzllŠ}|yle’ŚŚsle‚|ubVU{||SKJŠ}|[[TultŠ}||zllllktts‚ut„„uzt\UZMSSMSS|„…UTSUTS\[[ult\[b|„…“Ś”{||{||››”„„ultedkddc‹„„‚v{{{t”š”{||ś¤¦ŚŚš‹…š{||mttŞł·Ś‹“¦§¨Şł·“Ś”‹‹‹Ś”•”š”‚u‹’Štt{llk{|||‚zf]ccbVtllmtt“““|‚z\UZ‚v{jV[sle[[Tkd\{||ttstts{tt‚|u””‹ztlkd\š””tts“Ś”„„Škd\‹‹„r]g‹‹‹tsl‹‹‹‹„‹Ś‹“sle‚ut|„…|||‚z“Ś”‚ut|‚zttsŁ››|Ł››¤¤ť“Ś”lrimtt‚utś››|„…{ttek]JHFJHFFD;JHF{||MSSMRK}JHF|‚z„„‹‹„‘Ś…dc\„„UTSyfllekf]c“““mttred‹…’llkŚ”•tts‹„„{tt‹’Štllś¤¦|‰v{zmŠ}››”›˘›˘—Ť“Ś”{ttŠ}˛««MRK:97Ł››{tt‚|usreSKJsrezll{{t‚|u‚|ubVZsrekk]SKJrfk’…‹Š}‹’ŠŠ}lks„„Š|‚zedkUTS||”››™š¤š””Ś”•‘…„¦§¨ś¤¦ś¤¦››”|„…lri‘Ś…’…‹tllddcrfkf]cultš””Ł››{u{‹‹„{{t|‚zddc‹„‹f]c‚|u”“›…‹‹lri|‚zrfk{{t‹„„’ŚŚ„Š„{tt’ŚŚtslzll‚uzll‘Ś…|ttsb[Ullkdc\‚uVTLd\\‹„‹f]cddcekdf]cf]c|„…Ł››Š}tsl’ŚŚ{tt‚v‚{tt‹’Š„Š}lldSKJtllbVZztf“Ś”Š}|ultdkV|zll„„ś››‚v{{{t‰v{ttred{{t}ult{|||„…ultllk>ECMSSUTSllkddc…‹‹{{mttfkk„„{tt{||ekd{||f]clksddctlltll{{tś››”››„„Š”“›ult”››ultŚ”•}›˘›ĚÖЦ§¨¦§¨™š¤”››‚|uuzt“Ś”Ś”•”“›sreś››„„||‘Ś…{{t„„„„||‹…’{{t{{t˛««{tt„Š„{||ttsztl„Š„{ttkd\|ult„„{||lld…‹‹›”›’ŚŚ||}{{…‹‹‚|ulddult|‚ztzl„„ś››Ś‹“’ŚŚ“Ś”ztl‚uztl{ttyfl…‹‹lddtll{u{VTL\[[FD;F=CUMRd\\„„[[TZbNedkUTS™š¤Ś”•µ¶·‚|u{{t{||rfk|‹‹„|‚z|ttstslŠ}lriu{{]cd„„Š™š¤“““{{t“““{{t‹„„‘Ś…kk]‘Ś…{{t‚utŁ››tll{zm˛««llk7-2ŠŠ}””‹„„””‹cbVkd\‚wl|tzlś››yfd{||SKJPF=„„„Š„‹„‹‹’Škd\Ś”•|‚z{{]bZztld\\|‚zŚ‹“‹„‹tsl“Ś”}„Š„…‹‹„‰vś¤¦„„Šd\\››”’ŚŚlldf]cŚ‹“{{‘Ś…rfktlllks›”›‹’Štts¦§¨{{}tsl‹‹„MRKlks‹‹‹{tt{zmtll{|||””‹[TTredkd\Š}‚uddc||||u{{lldbVZ[[Tek]\[[{u{leklekŠ}|‚zultsleekdtllkd\redllksleuztcbVlldFD;lekj]\ztl‰|v{tt‹„„|||“Ś””››}ult“““||i\Vredrfkult{ttultlrifkklld|‚z]cdmttultuzt„Š„ult^^qf]c||}fkk„Š}||”››uztf]c‹„„‹„„{||‹’Š“““|„…f]ctlltslddc¨©´„Š„¨©´¦§¨“Ś”ŽŁlri„Š}}{||{tttt{ultlddzlluztŁ››‹’Štzl‹‹‹{u{‰v|}ddc‹‹„›”›lldlld|™š¤‚ut|‚ut‹„‹slekd\ult¦§¨|kd\{{t‚wl‹…’Ł››„„„„‚|u’…‹…‹‹lriztllek|}ŁśĄ”››tll„Š}‹’Š‹„„“Ś”lld“Ś”Š}|Ś”•kd\VZTVTL:97UMR{zmekdUTSFD;MRK]bZ|‚z””‹””‹sle{{t|‚z{{t‹„„Ś‹“ztl{{tllkd\\sle|„…ttskk]llkldd‹‹„lektsl‹’Šztl{tt‹‹„{zm‹’Š‚v{Š}||ŠŠ}˛˛¬VTL*)(ś››tzlś››ljcbV|‚zzll””‹tzlkd\sreŠ}|74,D;9{{t”š”„„ś››tll„Š}{||}„Š„„„ultś¤¦“““¤¤ť‘…„jV[yfd|‚z”››””‹|„Š}Š~‹||‹„‹tsl}}Šµ¶·””‹šŤŚµ¶·¦§¨{{|tt{ś››¨©´’ŚŚ[[Tddcek]sletts|Şł·‹‹‹{zmultsle\[[kd\tslVTL|{{tlddlddulttll‹‹‹JHFultred’ŚŚtsl{{bVZmttlri‰v|mttkd\kd\dc\‹’Š›”›|‚z„Š}{{ttslUTS{{t{ttljtlltll{u{’…‹‹„‹tts‹‹„’ŚŚ„Š„ultredlddkd\{ttult{||edkultJHFmtt\[bfkk{tt|‚z„„Š…„’ult|„…{||‚v‚UTSdc\“““Ś‹“llkŚ”•‰|v‚v{Ś”•‹‹‹u{{mtt{{“Ś”Ś”•‹‹‹|‹’Š{{””‹‘…„Ł››‹’ŠŚ”•}‚v{{tt[[T‚|u|¤¤ť||’}™„Š}|‚z“Ś”‹„‹Š}|”“›››”{zm||{{tmtttts„„zll|›˘›uzt‹„„’ŚŚd\\{{ttslztf|‚ztsl}Š}tslsle””‹}{u{kd\d\\””‹››”„„Š„Š„}Š„Š„ekd”š”“Ś”rfkJHF||bVUlekb[USKJJHFFD;MRKSKJVTLJHF|\UZ|„…f]c|‚|uŠ}|llk…‹‹ekd||lri{||kd\MRKred{|||‚ztts‹‹„||ultu{{{||…‹‹{||kd\‚|u«˛«„Š}ŠŠ}{{tsle‚|uŠŠ}µ¶·JHF-1+|‚z“““‘Ś…rg]kk]jcV‰v”š”b[U‹‹„„„b[UVTL3+*‘Ś…„Š„‹…’ttsVTL}tts|‚zmttŁśĄ””‹tt{‹‹‹›”›¦§¨ś››}”“›llktt{¦§¨¨©´Ł››‹„‹{tttslf]clkstsl“Ś”‹…’{{||‚v‚”š”¦§¨„„Š‹„‹Ś‹“‹‹‹ultttsdc\f]c‚ut„„Š||‹‹‹redi\Vkd\zllVTLldd{||[[Tllk||ttssredc\„„bVUttsSKJ}ultllklriś››redztltsl„Š}d\\ztl„„{tt’ŚŚdc\‹’Šd\\”š”‚|uztlŠ}|cbVkk]kd\“Ś”||„„Š}|””‹’ŚŚ‚wl“Ś”kd\ult{{ult„„lldfkk|„…JHF\[btlluzt‹„„„„Š{{}|’Ś‹“{{t{u{”š”’ŚŚ„„ddc„„tll„„Š‹…šś››Ś”•{||”››’ŚŚlriŚ‹“”››{tt|„…|‚z||›”›””‹}”“›edk…‹‹|‚z“““‹‹„sle…‹‹lek¦§¨{||tsl„„}Š}{{t{{t“““{{t|‚zdc\‹‹‹rfkś¤¦””‹’ŚŚ‹„„Š}‹„„{||‹’Š‘Ś…llk„„’…‹ult|„…‹„„‹„‹›”›Ś”•{{tslett{”š”‹„‹“““{{|””‹‹‹„Š}|bVZlldlekztluztkd\D;9VTLFD;[TTsleUTSf]c&&\[b„Š„‹‹‹‹„‹‚|u‹‹‹‹’Š…‹‹Š}Š~‹””‹sle|}‹„‹}Šlld‹‹„ztlttstts‹‹„“““‹’Š”š”‚ut‹‹„lld‹‹‹|‚v{yletsl|¦§¨:9774,|‚u{{t‚|urr]rg]‘Ś…tslyle{u{||VTLSKJŠŠ}ś››}Š¦§¨|„„„Š}tt{lri‹’ŠŁśĄuzt…‹‹“““””‹Ł››‹„„ult|‚z«˛«|„…||‘Ś…™š¤›˘›…‹‹dc\Ś”•„„d\\[[TUTSrfkldd‹‹‹|„…}“Ś”Ś‹“™š¤“““„Š„j]\“Ś”b[U“Ś”{{t‹„„š””‹’Škk]{tt|kk]uzt|‚ztts“Ś”f]c{{tsletsl}d\\‚v{|‚z{{ult„„’ŚŚ‹‹„{||Š}Ś”•uzt‹‹„‹‹‹¦§¨{||jcV\[b||{u{”š”‹„„š…Žult‚ut{{t‹‹‹‹‹‹tllŠ}|Š}‹„„{u{„„Ś”•”“›f]c}‹’Šlri|„…lri]cd\[[ekd…‹‹‹„‹tt{{{…„’‹‹‹tsl{u{{||||„„Š„„ekdtllŚŚš†~‘llk„„Š…‹’“Ś”“Ś”„„Š„Š„Ś‹“’ŚŚ“““‚wlult‹„„µ¶·Ś‹“…„’‚wlult|‚z„Š}|ult“““ult{tt{{t{tt„„“Ś”Ł››||sle’ŚŚtsldc\{||ś››lek{{t{{tŠ}‹„„“Ś”ŁśĄ¦§¨“““¦§¨„„|“““tll‹‹‹‹„„„„Šmwmttd\\mttztl‹‹„{u{š””’…‹{{t‹’Š|„…‹„„redlldtllŠ}|‘Ś…rg]uzttygC8.dc\[TT‹‹‹ldd\[bmtt„Š„”“›\[bkd\rfk…‹’{{t[[T‹„‹|„…š””‹‹„ttsŚ”•‚v{’ŚŚ{{tslellk”“›””‹‹„‹¦§¨‹’ŠŁ››››”|‹’Š¤¤ť‹„‹ztl››”‚utĂĽżSKJ:97kd\kjVŠ}ztlkd\ŠŠ}d\\tsl|‚zuzt}{zm[TT‹„„{zmuzt”“›ŁśĄ‚uŁśĄ|b[UŁśĄ{||{u{Ś‹““Ś”{{{{t’ŚŚ‘Ś…››”Ś”•{||‹’Š”“›””‹Ł››tts\[[ek]|„…u{{‚ulksult{{t{{‚uu{{”“›’ŚŚ“““„„Š‚ut‹‹‹Ś”•}‘Ś…”“›“Ś”Şł·||b[Usre||sreŠ}tt{||‚|u“““ult{ttsretzlŚ”•d\\lrir]Z|‚z‚ut“Ś”‘…„‹‹„ś¤¦tts{{t‹„‹{{{ttek]tslkd\d\\tll‹‹‹Ł››‹„„¦§¨››”tlllddf]c|llkŠ}|„Š„||lddŁ››sre}{{“““|]bZ…‹‹„Š„{||…‹’{u{|‚z|„…}mtt{||…‹‹|‚z‹„„ttstt{}tllult„„lddŁśĄ™š¤¨©´ś¤¦“Ś”“Ś”š””¦§¨«˛«‹‹‹„„‚u¦§¨‹‹„‹’Š‹„‹‹…’f]c„„Štts››”””‹››”µ¶·‹…’tzl‹‹‹””‹|‚zŠ}‚ut{||ldd’ŚŚ””‹|„…{tt{{t„Š„{zmuzt””‹›”›“““ŁśĄ”“›ś››””‹{u{||{tt›”›tts}lddldd{{t[TTllk‚|u¦§¨|”“›}u{{‹’Š„„’ŚŚ‹„‹‹„‹Š~‹ztf{{tsleŚ‹“kk]D;9ult{{|‚z…‹’mttUUY„„d\\fkkzll‚|u›˘›„„uzt}{u{’ŚŚ‹‹‹\[[‹„„Š~‹ddc]bZ[[Tddctsl‹’ŠŚ”•Ś”•tslb[U|{||””‹¤¤ť“Ś”Ł››‚v{ztl¦§¨[[T74,››”„Š„{zmŠ}Š}|‚z{zm|‚zllduztś››‹‹„|||‚z‹„„Ś”•Ś”•“““ztlldd[TTddc|„…{u{{u{’ŚŚ‹„‹”››Š}Š}„„Š„„VZ[u{{…‹‹¦§¨‹„„|ldduztdc\lksŚ”•lriŚ”•ult‘…„{tttsluzt”“›Ś‹“{{d\\ś››‹’Š‹„‹}‘}ultŠ}zll{ttś››lddś››››”Š}{{t{{lddtsl{||‚u||kd\‚|uultj]\tllllkrfk‹‹„||{{tś››|›”›{ttlld|‚zrfkj]\‚v{mtt}lekrg]Š}‘…„‘…„ztl“Ś”›˘›‘Ś…tslldd„„{tt{{}red„„„„Šuztkd\b[Utts{||{{„„Š„„|„…{u{~’“mttlks[[T{||llkdc\rfkmtttt{|„…””‹}“Ś”f]c‹…’™š¤Ł››››”Š~‹tsl‹’Š{{tt{‹‹‹{zm””‹Ł››„„¦§¨}Ś”•‹‹‹‹’Š””‹ś››™š¤Ś‹“‚|uś¤¦‘Ś…{||“““‚v{}‚|uŠ}lld|lld‚ut¤¤ť‹‹„”š”‚ut‹„„›”››”›‹„„tts›”›š””‚ut„„“Ś”Š~‹mw„„Š{tt|ddc“““|››”lks”š”{u{…‹‹|‚z”››“Ś”‹„„}‹„‹||d\\sred\\|‚z‰|v™š¤ttsŚ”•\[b>B9f]cJHFtll{||uztkd\tsl{{Š}“Ś”„„Šš””|‚z””‹„Š}›˘›{||lld{{t\UZmtt|‹„‹llktslSKJVTLkk]kk]{{tš””Š}|’ŚŚtll¦§¨VZT-1+‹‹„””‹||‘…„‚|ukd\tzlVTL[TTllkŠ}‚ulrilks{{t|‚zlks|sre‹‹‹[[TUTSUUY}Šzllś››ŁśĄ”š”››”||‹‹‹lri|„…cbVŚ”•…‹‹‹…’slettslrikk]lddlkstts|„…”“›‚|u[[TŚ”•„Š„ttsekdldd„Š„tt{„Š„„„Š‹‹‹[TTztltts{u{‚ut|‚z”š”””‹‚u‚u‘Ś…‹‹‹tll‹„„{u{lddkk]‰vlddredbVUtlllld}tt{||||‚z|b[Utts{{t{u{Ś‹“sleSKJd\\d\\„Š}sleldd[TTddc’…‹ek]‹‹‹„Š„“““‚ut‹‹„llk{u{{{t””‹„„Š[TTkd\|„…slelrimttlek|„…||‹’ŠŚ‹“{{…‹’{{{||llk{|||‚z’…‹‹…’|„…{||||{u{}‹‹‹{{}¦§¨›”›„„|‚z„Š„ult¦§¨”››’ŚŚ“““{||”››{{‹‹‹|‚zlld„Š„ŠŠ}‹’Š{||›”›“““„Š„¤¤ť“““Š}|{u{{u{|””‹|tslś››¤¤ť|||””‹{zm””‹d\\f]c‹‹‹„Š„sle{||Š}››”“Ś”{u{”“›ŁśĄ””‹uztbVU|‚z‹‹‹kd\‹‹‹tsl…‹‹“““|‚z”››ś››’ŚŚ]bZ‹„„š””tll„Š}Š}sletzl{{lddtzltt{SKJJHFFD;llk|‚z››”tsl|‚ztt{sle“Ś”ztl{u{kd\Ś”•‹„‹ekd{u{[[TbVUtts|‚ztsltt{lldlrib[UaWMcbVdc\tslŚ‹“}tsl‰|v’ŚŚJHF3+*}””‹‚|u‚wl””‹tsltslsletll„Š„lri|u{{sle“““{||ddclri‘Ś…\[[ttsf]cUTSzll“~{u{’ŚŚ¦§¨sre||’ŚŚŚ”•mtt|‚zf]cttssle¦§¨ddctsl:97ek]VTL[[T‹‹‹ttslri{|||{||“““”››”“›„vŚ|||‚z‹…’{u{zll‚v{‹„‹„Š}ult„Š„‹„„‚|u‹„„ztlś››‹‹‹„„ult”“›‘Ś…sreyfd‹„‹sleredd\\kd\bVUtts‹‹„sre|’ŚŚ‘Ś…]cddc\{||ttsredredUMRd\\…‹‹‚|ud\\yleŠ~‹‚|u„„‹„„‹’Š{tt‹„„„Š}{u{ttsreduzt}tll‹’Š„„{u{\[b]cdyl„lks„„|„…”››|„…Ś”•}’…‹llk„„{{„Š„“Ś”|„„}›”››”›“““”“›Ś‹“››”›”›Š}|‹’Š¦§¨”››|‚ztsllld‚|u„„„„Šult’ŚŚ‹‹‹|‚zš””›˘›‹‹„\[b}{tt|‚zsleś››ult‚|u‚v{Š}š””tsl„„ŠŠ}{zmsle‹‹„|‚|u’ŚŚŁśĄ‹„„{u{„„‚utlldŚ”•{{t¦§¨ult||}‹„‹„„||¤¤ťtts‚|u‹„„”š”dc\tt{”››¦§¨ś››Ł››Ś‹“Ś”•’ŚŚzll|‚zj]\[[TŠ}|SKJ‹„„ŠŠ}SKJVTL[TTlrimttddc‚wl{{tu{{Ś‹“tt{||{u{‚v{b[Utsl„Š„{{Ś”•Š}lldlek|‹’Šultttstsl‚v{{zm¤¤ťtsl””‹››”‹‹‹“““{tt«˛«JHF*)(}uzt||f]c‚|udc\‚|ulritllUTS‚|ulri”š”““““Ś””š”Ś”•‘}SKJ‰vlldekd\[[UMR{ttŁ››‹„„Ł›››˘›ś››Š}™š¤‹’ŠlksŠ}„„‹’Š{{tred„Š„lldSKJ{||tslŠ~‹uztlri™š¤||‚z™š¤…‹’”“›”“›||¦§¨ś››ult||zllztlŠŠ}Ł››dc\|Š}’ŚŚrg]ŁśĄ„„|‚z”“›d\\tlltsl{tt„„rg]ultSKJ{|||{{tsre{{t‹‹‹‘}||tsld\\mtt„„{tt„„‹‹„„„slešŤŚldddkVbVU{||”“›{||mtt‹’Š‹„„uztllk{{‘Ś…}Ś‹“lld{||[[TbVU\[bd\\\[bedk|]bZ…‹’u{{Ś”•„„Š‹’Š|‚ztts‚|u{u{¦§¨|}Š{{¨©´¦§¨„„¨©´„„Šzll{u{„Š„|‚z‹‹‹”“›leklld””‹[[TlldŚŚš{{|„…„Š„|‚zztlś¤¦‚utVZT}””‹ŠŠ}››”“““ŁśĄš…Ž{tt[TTkd\ek]‹’Š„„‹‹„Š}‹‹„‹‹„Š}|‘Ś…‹„‹}Š}|„„Ś‹“„Š„ttstslš””||„Š„››”“““‹’Š{u{‹’ŠŠ}||||„Š„}Š||‹’Š||”š”‚|u„„”“›bVU||rg]ztl|„…ult[TT{{t„„slelrif]c{{ldd{|||‚z“““{{t‹‹„{||d\\f]ckd\VZTtts{u{¦§¨{tt‚v{‹’Š“““lks„„”››‹’Š„„šŤŚ¤¤ť›˘››˘›«˛«ŁśĄ›˘›¦§¨‘Ś…””‹VTL*)(sre|lriztl‚|uVTL””‹{{t‘Ś…„Š„}”š”‹‹‹{tt[[T|‚z„Š„‹‹„b[UŁśĄ{tt]cd…‹‹Ł››’ŚŚś¤¦‚ut“Ś”||}|}…‹‹z‚lŠ}„‰vsle[TTUTScbV‚|udc\‹„‹ŚŚš™š¤{||‚u}›˘›u{{‹‹‹“““”››‚v{}tslŁśĄ}tll‹‹‹‚ut|‚z‹’Šek]zll{zm››”‰v{{tuzttll‰|v„„Š}bVUztl›”›slered}lddŠ}sle””‹|llddc\””‹{ttllkd\\{ttkd\tll|‚zj]\”››Š}}‘Ś…{ttŠ}šŤŚllk‹’Šllk||‚v{}Š””‹tllŚ”•{{“Ś”tts„Š„tslmttf]c{{mtt“““uzt{{|‚z|„…Ś‹““““{ttVZ[{ttŠ}uztŚ”•‚v{Š~‹…„’||tll“““”“›””‹‹„„’ŚŚś››Ś”•{||ddc‚v{‹‹„Š}”››‹‹„“Ś”™š¤Ś”•‹‹„”š”¤¤ť››”dc\{||Ł››’ŚŚ””‹’ŚŚrfkŠ}š””Š}ztlŠŠ}tsl„Š„ś››ztf{{t{ttkd\sle‹„„”“›‚|u|‚zultŠŠ}‹„‹‹„„‹„„··Ä‹‹„ŁśĄŚ”•|‹„„j]\}Ś‹“red„Š„™š¤¦§¨Ś‹“”“›‚|utsl¤¤ť{||‚utlldtzl…‹‹{{tSKJ‚utVTL{{t’‘~f]cJHFlrittsŚ”•ŠŠ}“““‹‹‹”š”ultj]\}’ŚŚllktsllks|“““’ŚŚ”š”{zm„Š„{{t}„„tsl››”‹’Š””‹›˘›’‘~˛¬µµ¶·µ¶·¤¤ť¦§¨\[b)+2Š}””‹|››”‘}dkV‹’Š‚|u‹‹„‹‹‹Š}sreVTLsle‚|uŚ”•lrimttztl‹‹‹|„…\[[lrizll’ŚŚ‚|uuztVTL¤¤ť“Ś”šŤŚ“Ś”‹„‹lld“““”š”“Ś”Š}‹„„lri‹‹‹f]ctsllri{{™š¤¨©´‹‹‹”š”…„’{{{u{‹„‹™š¤tllsleŠ}{u{‹‹‹‹’Š}sle{ttj]\„Š}ldd{zm‚|u””‹||‹‹‹sle‹„„„„Šdc\‰|vj]\‹‹„“““‹„‹]bZŚ‹“”››tll{{t‹’Š{zm‹„‹{u{‚|u“““Ś‹“kd\’…‹ttsedktlllddsleztf{u{||‰v{tttsldc\‚v{‚|u{u{‚u›”›””‹edk{u{„„ttslldult{{t{||™š¤|‚zuzt|„…Ś”•|„…|„…|‚zlksu{{{zm„„lekŠ}tt{}““““““Ś‹“Ś”•‹‹‹Ł››ultlks|„„„„Š{||‘Ś…”š”š””‹’Š„„„„Š|„…ttsŠ}‘Ś…‹‹„‹„„{{ultś››”“›¦§¨›”››”›yfl‚|u””‹‘Ś…””‹sre””‹ŠŠ}„Š„‹‹‹yfdztl‚|u‚|u„„‹’Š‹‹‹‹‹‹‹„„{ttś››’ŚŚ‹„„|‚z|‚zrfklri{ttult“Ś”¦§¨¦§¨›”›‹„‹„„|„…›˘›‹‹‹{tt‹‹„{{tš””uzt„Š}lldztfVTLSKJsleuzt[TT:97f]cmtt\[[lri”š”™š¤{{tmtt}“Ś”{u{¦§¨„Š„|“Ś”‹’Š|‹„‹„Š}ek]tlltt{[TT„„“““””‹‚uŠŠ}”š”¦§¨™š¤ŁśĄ››”¦§¨¦§¨JHF*)(‹‹„‹‹„lri‘Ś…ztliq]‹’Š‹‹„‹‹„lld{u{VTLtsld\\|„„uzt™š¤||uzt‹’Šu{{u{{tll‹„„ś¤¦ulttts{||Ł››¤¤ťś››Ś‹“‘Ś…rfk“Ś”š””ś››‹„„„„ldd\[[{{t„Š„{tt„„“Ś”tt{„„u{{|‚zultś››red‹‹„˛««||{{“““tll‹„„b[U’ŚŚ{||tts{zmslei\VŠ}{tt‹„„‚utddcddckd\‚|ud\\„Š}tll||zll‘…„UTStll|‚z””‹‚usle“Ś”{u{ttsŠŠ}Š}{||{tt„„f]ctll‚wlš””lldsle|||‚z‹‹‹”š”›”›‹‹„“““{u{ultttstts{tt||||‹‹‹lks||lriu{{|„…„„Š„„Š|„…VZT]cdu{{{{]bZ‹’ŠŠ}™š¤’ŚŚ{u{tll“Ś”lri‹’Š„„Š™š¤¦§¨Š}|sle|ulttts‹‹‹ŁśĄ””‹‘Ś…«˛«””‹Ś‹““““{{tJHFztl{{tŠ}ultŠ~‹tll‹„„Ł›››”›Ł››Š}|‘}lj˛««lri‹‹„{zm‹’Š””‹„„Š}|zllkd\šŤŚ‹„„‹‹‹|‚z||UTS{tt{||š””’ŚŚ‹‹„‹„„tll\[[Š}|{tt{u{’ŚŚŚ‹“‹’Š„„‹„‹Ś”•ś¤¦‹’Š“““¦§¨„„ś››“Ś”|‚z]cdztlVTLSKJŠ}…‹‹Ś‹“MRKSKJuztd\\mtt‘Ś…„„Š‹„‹“Ś””“›“Ś”›”›ś››‹‹‹|tt{|„……‹’}‹’Š}‹‹„ttslkstll„„š””tsl›˘›{{t‚|ullk||tts|¦§¨MSS*)(cbV„Š}Ś”•{{t|cbV’ŚŚdc\‹‹„sreŚŚšztlekdldd‚|u‹’Š‹’Š¦§¨¦§¨¦§¨|‚zJHF¦§¨|[TTred[[T‹’ŠŠ}ś››‹’Š˛««Š~‹{zm””‹llk’ŚŚ{{t‚ut…‹‹„Š}|„…›˘›”››{{lks}Š|‚z„Š„…‹‹‹„„™š¤}Š‚wl””‹‚v{Ś”•yflf]clld{||‹’Š‚|uddcdc\uztb[U‹‹‹||{||˛««Š}|„„tllkd\„Š„lek‚ut{tt}tt{|lektll„„Š„Š„ztlrg]”š”tts{u{lld‚v{{{tddcVTL||„„‹’Šult|sleiq]]bZlri’ŚŚ›˘›Š}Ś‹“\[[‰v|sle||’…‹{ttś¤¦”“›“Ś”{{tu{{u{{fkk“Ś”}mtt{{\[bŚ”•tsl„Š„{{tkd\lekultddc{u{UMRuzt‹‹„uzt›”›¦§¨‚u”š”Ś‹“…‹‹{{tllk¦§¨‘Ś…“““µ¶·„„{u{’ŚŚiq]‹‹„tllŠŠ}‹‹„‹„‹„„šŤŚ{{‹„„’ŚŚš””’ŚŚ˛««Š}{tttsl|ttsuztŠ}|||b[Utsl››”š””Ś”•„Š„uzt“Ś”„„Š{u{||ult}‹„„{ttedk’ŚŚSKJsle¦§¨tt{‚u“““ś››“Ś”„Š„‹‹‹¤¤ťš””””‹Š}¦§¨…‹‹sle‹‹„cbVrr]SKJdkVŚ‹“Ś‹“MRKf]ctzlmwekdŠ}„„›”›‹’ŠŚ‹“”“›“Ś”ldd”››„Š}tts‘}…‹‹ŁśĄ‹‹‹„„{||Ś‹“„„‹‹‹“““tll|‚z{{ttslztl„„Š}„„ult˛¬µ[TT*)({{t¤¤ť„Š„’ŚŚšŤŚlks{zm{tt||{{t„„Šuzt‹’Štslyle””‹{{t‹„‹””‹”››Ś”•|‚z¨©´˛««ult‹’Šuzt{||f]c””‹{tt››”‹‹‹¦§¨›”›mtttlltzlttssle]bZ„Š„„„„Š}lri\[[™š¤\[[uzttt{tts{tt„„Ł››|uzt¦§¨ttslddb[U‹‹„|‚z„„ddc{{tlriztl“Ś”ŠŠ}‹‹„š””ztlttsztllddb[U‹„‹‚|uslekd\{{tŠ}’ŚŚ“Ś”|‚z””‹{||›˘›„Š„{{””‹‹‹„j]\|VTLtll“““|‚z¦§¨{u{“““š””””‹ttsllk{{tŚ‹““““ś››tllztl|‚z’ŚŚŁ››}¦§¨tlledku{{ddc|‚z|„…”“›ekdmttmtt|„…|tll“““ztlztlultult…‹‹tts}‹‹‹‹„„Ś”•Ł››¦§¨‚v{|”“›ś››Ś”•ŠŠ}¨©´¦§¨›˘›¦§¨›˘›¦§¨‹„‹|„„{{t‹‹„{zmś¤¦{{ldd||‹„„”“›“~š””ś››‹„‹‚|u‚|udc\›˘›””‹||‚|u||Ł››Š}„Š}„„‹‹‹””‹Şł·„Š„u{{}š””}Š{||““““““…‹‹||tll‹„„ttsŁ››|lddedklld‹‹‹””‹ztlkd\“““ŁśĄ¤¤ť„„‚|ukk]b[U{tt‘Ś…”››†~‘mtt}Štts{||llk‹‹„VZ[{tt||“Ś”“Ś”‹…’mwmttuzt{||¦§¨„„||Ś”•Š}‹’Šś››„„Š‹’Šddc||””‹[[T{u{{zmŁśĄ{{}Š}|”š”LKR)+2‚u‹’Š“““d\\Ś”•Š}‚|usleuzt””‹tt{‹„‹VZ[VTL‹„„„Š}\UZ‚|u|…‹‹u{{|‚z…‹‹”“›Ł››‹‹‹lriuztcbV‚|u’ŚŚ‹„„„Š„››”„Š„„„Š‹’Š|}|tsl\[[|‚zu{{‚|ulksŁť˛u{{”š”ś››tzlŚ‹“|‚z“““’ŚŚ|‹‹„ztl{u{{{tś››lritts‰vtslsleylelrirg]¤¤ťztl‚|u„„ult}ztlcbVf]cš””d\\‚|u{zmŠ}|{u{lldtslddc„„|‚z‚u””‹|tsl{||d\\sle‚|u{||sre‚|u‹„‹‘Ś…d\\‰|v‹’Škk]tlltsl‹‹‹uztŠ}sreŠŠ}|‹„‹„Š„||{u{„Š„Ś”•{{”››„„Š|„…ttsŚ”•|„…‹„„‹‹‹„Š„ztl„„Š}„„{||‹’Š¦§¨”š”ś¤¦¦§¨¦§¨Ł››µ¶·˛««‹’Š“““‹„„Š}¤¤ťµ¶·Şł·””‹¨©´‹’Štt{sreŠ}’ŚŚš””ddctslult›”›{{‹‹‹}›”›‘…„‹‹„tll››”|‚z|‚z¦§¨™š¤‚|u„Š}‘}››”””‹yle‹‹‹‹‹‹{||¦§¨‹’Šllk„„Š}“Ś”‹„‹ŁśĄ‹’Š‹’Šf]cred…‹’ldd”››ldd|‚z’ŚŚ”››¤¤ť‚uultdc\Ł››ztl”š”‹‹„|‚z‹‹„VTLš”””š”‹’Š{u{Ś”•lek{{t‚v{llk‹’Šu{{‚v{lek}‚v{‹„‹|{tt|„…llk¦§¨Š}’ŚŚ„„¦§¨‹‹‹™š¤‹’ŠŚ”•‹„‹„„Š}kk]ult‘…„“Ś”›”›f]c[TT¤¤ťJHF:97sre|‹„‹”š”‹‹„{tt|[[Tb[U||‹„„Ś”•lldtlllrilld[[T|‚z}tzl{||mtt„„{{t››”‰‘~ult|‚|u‘Ś…’ŚŚ||}tslś¤¦|„…‹„„dc\\UZ\[[{{ddcztlVZ[ztl}Ś‹“}‡’„Š„|‚z“Ś”}lriddcŠŠ}{{tś››sre}{||‹’Š|‚z{ttdc\tts|lldkk]ztlSKJi\V[[T{{ek]||‹’Š{ttzll{ttj]\|zll“Ś”‚utztlś¤¦llk{tt{|||ztlŠ}zllllkdc\lldultUTS‚|ub[UsleŠ}sre››”‹‹‹||””‹{{t“Ś”|‚zŠ}‘Ś…“““{{t“Ś”{||\[[{u{{|||„…]cd|„…‹„‹{|||¨©´‹‹‹{{t{u{{zmŠ}‘…„zll„„red‹‹‹‹‹„”š”Ś”•|„…“““‹‹‹Ł››””‹„Š„¦§¨¦§¨›˘›¤¤ť˛««‹‹„”š”{{t‹„‹‹’Š‹„„¨©´|µ¶·tzl{||{{Ś”•¦§¨¦§¨‹„‹Ł››||’ŚŚ{tt‘Ś…‚wllriŚ”•“““||‚|u‰v””‹Šut“““”“›ś¤¦lri‹„‹ŁśĄ”››‹’Šš””{u{{tt{||{||{||ult‹„„‹„‹}„„Š|||{tt‹‹‹‹‹„{zmyle|‹‹„‹„‹”“›‹’Šuzt””‹]bZ“““¤¤ť|‚zŁśĄu{{ult]cdf]c„Š„|“““„Š„„„Šult“Ś”‘Ś…››”dc\|‹„‹„„lekredsre‚v‚{||‹„„{|||‚zbVUrfk˘—Ť{{tlld‚|uldd{ttzll‚ut‹‹‹:97JHF‹‹„{{t|„…sle||„„Š||‚|u|‹‹„‹„‹ekdlri””‹tsl|Ś”•||tllŚ”•|„…VZT‹’Š{{t””‹„Š„„„«˛«‹‹„š””||ŠŠ}…‹‹’ŚŚ”“›{||b[U|„…sreŠŠ}lekttslri„„Š\[[lkssleVZ[{u{…‹‹ŁśĄ„„{tt{{t||lri‹’Š{tttllVZ[|||f]c|{||sretsllddsre{{tsre{{td\\{||„„lld””‹d\\‰|v||b[Ukd\‹‹‹ldd’…‹ś¤¦‹’ŠtslŚ”•lldb[UUMRtll‹‹„‹‹‹red’ŚŚ„„Š[TTtsl{||Š}‹‹„{||¦§¨¦§¨{tt‹„„ś››”š”‹‹„‚ut‚|ukd\tt{uzt›”›„„Š‹‹‹ldd{tttt{fkkmtt{ttu{{{{”“›’…‹‹’Š‚uldd“Ś””“›tt{™š¤Şł·“““«˛«ŁśĄ›”›¦§¨Ł››‹‹„‹‹‹{||›˘›ŁśĄŁ››‚|utsl«˛«“““‚v‚rfk“Ś”™š¤”››››”‹‹‹{||{u{“““„„tts“Ś”“Ś”{||‰|v‰v””‹””‹”š”ś››‚v{‘Ś…{{t‹’Š‘Ś…š””“““{{{{t{{t“Ś”™š¤“““””‹¨©´“Ś”¦§¨¤¤ťŚ”•tzl“Ś”zll‹„„||lldŠŠ}“““”››”››‹‹„µ¶·˛˛¬‹‹‹Ś”•||„Š„\[[||ttsMRKztl“““|„…Ś”•lkslks}bVZ…‹‹¦§¨„Š„›”›‹’Šult›”›Ś”•‹’Š„Š}„Š}„„‚ut{u{{u{‹’Š‹„‹„„Š„„SKJlrifkkred‚|u“““|Š}‹‹‹||‚utldd””‹JHF:97rg]|‚z|tzllri‹„‹¦§¨‘Ś…}tll}{{t]bZVTL||‹‹„ś§˛›˘›llk‹’ŠŚ”•tts|„…“““d\\“““tt{‹‹„d\\\[[ŁśĄyle{tttlllks‹‹„ttslldVTL‹‹„leku{{edk‹’Šd\\UTSultŚ‹“„„{u{‹’Šslelrilld‚u||‹’ŠŠ}„„{ttztlldd|‚z‹„„tts‚v{lldŠŠ}j]\jcVkd\VTLtzlŠ~‹ult{zm‚|u[TTšŤŚ‘Ś…jcV¤¤ťult””‹‹‹„›˘››˘›{u{{{tdc\Š}bVUldddc\{{””‹“Ś”„„ztl‚|utsl‹„„rg]„Š}Ś‹“„Š„||}„Š„{{tlddztlkd\sle{|||‚zult|„…|”š”{u{Ś‹“…‹‹tts„„ŠlriedkUMRtll“““{{t‹‹„„„{u{„„Ł››¦§¨”š”ś¤¦µ¶·››”„Š„š””ś››”š”›˘›“Ś”}šŤŚ‹’Š‹‹„„Š„“Ś”|¦§¨ŁśĄrfk„„¤¤ť„Š}{{t„„Šś››}ś››‹„‹ultiWUzllrg]‚utztf””‹„Š„Š}|ztl‚|ukd\‚|uŠ}‹’Šu{{tts‹‹‹ś››š””mttllk{||ult“Ś”tsl›˘›uzt¨©´„„“Ś”}„Š„|‚z›”›”š”ś¤¦“Ś”‹’Š‹’ŠŚ‹“ultŁśĄuztzlllddttsVTL[[Tsreś¤¦f]cJHFultultzll{tttll””‹‹‹„‹„„Ś”•’ŚŚŚ‹“{u{|‚z||Ś‹“{{tsledc\|‚z‰‰w{{ddc||tsl{||ztltll|‰vŁ››lddultldd‚u„„D;9,55|UTS{||lld\[[{u{tll“““|‚z‹„„‹„„uztult‚|u{tt‹’Š…‹‹’ŚŚ‚v{lkslks]cdddc{{t‹‹‹cbVŠ~‹‹‹„d\\‚wlf]c‘Ś…||‘Ś…ŁśĄ‚utzl[[Tmttlld\[bttstt{lri‹‹„tts‹‹„tslŚ”•|ztl‹‹‹|„…zlldc\{||”››sleVZTuztlri|”“›tts{ttŠ}|MRKŁ››‚wl{{tsle“““‹„„tllkd\tslsleŁ››{u{lri‚wltt{Š}tll„Š„”š”tll…‹‹lld‹„‹‚utb[Uredllk||Š}{tt“““{{tŠ}‘Ś…Š}|ulttzlf]c‹‹‹‹‹„‹’Š{{tsled\\‹„„‚|u{u{\[[]cd}Ś”•tts„„‹…’}Š‹„„{||edk{u{kd\„„Š„„|‚z„Š„š””}}kk]Şł·ttsŁśĄš””‘Ś…””‹Ł›››˘›ś››“Ś”¨©´“Ś”‚ut˛˛¬˛««ś¤¦ś¤¦„„Š›”›¦§¨[[Tztl”››ś››|}„„{u{{{t‹„‹š””Š}|b[Uztl‘Ś…‚|uek]¦§¨ŁśĄŠŠ}‰‘~‚utztf¤¤ť””‹“Ś”Ś‹“{||‹‹‹’ŚŚ{||tllŁśĄulttt{tsl”š”™š¤ŚŚšŁ››””‹„Š„“Ś”‹‹„|™š¤ś¤¦‚|u¦§¨‹‹‹sre‚u‹„„u{{lld|„…JHFdc\tsl‘Ś…[[TUMRMSSUMRultlks{{t{{t“Ś”{ttlddŚ‹“{||llkuzt{{t„„ttsŚ”•››”{tt‹’Šlld[TT‚v{„„„Š„‚ut‹„„‹‹„””‹Š}››”lldldd‹‹„“~ŁśĄ:97*)(|„„}ztlu{{|d\\Š}‚|u|„…tts{{tUTSŁ››…„’”››ttsredldd{u{llkekdtt{¤¤ť‹‹„{{tlld{||ttstll“““‹„‹‚v{‹„„mttdc\||ekdlrikd\{ttŚ”•™š¤lri„„|„…Ś”•tts„Š}|‚ztllŚ‹“‹’ŠŠŠ}tzl„Š„Š}{u{LKRd\\rr]f]cd\\ddcf]c‚utdc\kk]ztl›˘›¤¤ť””‹„„tt{srekd\[TT[TTj]\ultsleŠ}„„‚utŠ}|Ś”•tslult{{„„||‘…„‚|uult“““tslŠ}””‹{yf‚|u‘Ś…‘Ś…‹‹„z‚l‹‹‹uzttllrg]|„…tsl›”›{u{’ŚŚ{tt‚v‚dc\{tt„„‹’Š‹‹‹„Š„{{‹‹‹‹„„{u{{{{tt‹„„red‘…„‹‹„¦§¨‹„‹”“›}‹„„”š”›˘›„Š„Ł›››”›¤¤ťztl‚|u‹’Š{u{‚|u’…‹šŤŚ¤¤ť››”|‹‹„Ś”•rfk™š¤llk‚|u|¨©´‹’Š‹‹‹„„tts‹„‹¨©´“““‚utzllrg]Š}jcVsreŚ”•‚v{‹’Š””‹redŠŠ}ztlkd\„Š}VTLtsl””‹‚v{’ŚŚ„„››”‹„‹kk]››”lri‹’Šedktll›”›{{t™š¤¦§¨‹‹„ś››™š¤¨©´«˛«”››‹„‹„Š„…‹’{{mttd\\VZT|||”š”|[TTJHFf]c{{f]ctsl‹‹„”“›‹‹‹‚ut“Ś”lri|„…{||uzt¦§¨™š¤}””‹‚|u|‚wl„„ult{||‹‹‹““““Ś”“Ś”’…‹‚ut‹‹„‹„„Ś”•‹„„Š}ŁśĄJHF*)(‹‹„‹„‹|||mtt””‹ztl‚|u‚ut›”›¤¤ť{{tlri{||d\\ldd‹’Š]bZ}}Š|‚z|‚z„Š„‹‹‹‹‹„”››¦§¨™š¤‚|u””‹Ś‹“¦§¨‹„„””‹”š”uztlrillddc\{{tztl‹„‹rfk‹…’’ŚŚkk]™š¤|„…”š”[TT{||tts{||{ttlldllkmw’ŚŚ\UZ„„{zm‹„„{u{||‹‹‹‚v{tslsreztf‚wlkk]ddcdc\ultzll‹„‹{tt‚v{{{tkd\dc\’ŚŚ„„d\\›”›d\\[[Tkd\rfktslVTL‚utŁ››„Š„tslb[U“Ś”{ttulttllztltll‚ut|‚zlriŚ‹“f]cŠ}“““{zm‹„„››”Š}d\\f]clri‹„„{||‹’Š|‚zlldtt{‹„‹‹„„‹„‹{{|„…||Š}|„„„„Ś‹“‹„„’…‹ttsŠŠ}ś¤¦uztsleŠ}’…‹Ł››¦§¨Ł››‹‹„ultŠ}‚v{“““Š}¦§¨„Š}|…‹‹zll‹‹‹“““‹‹‹dc\‘Ś…dc\{||||mtt””‹tll‚v{’ŚŚ{ttŠ}|Š}|kk]sle‹‹„‚v{‚utztf}››”””‹|‚zsreSKJllk{||kk]›˘›…‹‹›˘›“Ś”‹‹‹ldd|„…Ś”•„„Š¦§¨‹‹„’…‹}””‹”š”ś››„„ŁśĄ|‚z{{“““‹‹‹lektts„„lrilddlri’ŚŚ„‰v{ttf]clri}“Ś”‹„„›˘›|{u{Š}|‹„„…‹‹‹’Š|„…„„„„‘Ś…Š~‹¦§¨ztlŠŠ}‹’Š{{tŚ”•‹„‹tts|‚z{u{{u{Š}|Ł››™‹†¦§¨¦§¨||“““ŠŠ}Ł››:97*)(Š}Ś”•‘…„{ttŠ}|}Š‘Ś…||{||„„Ś‹“›˘›llkkd\{u{…‹‹”“›’ŚŚ‹‹‹tts“““\[[z‚l{||‹‹‹µ¶·“““¦§¨‚|u›˘›”“›Ś‹“{{tslerfk„Š„‹‹„‹‹„›˘›{{tdc\}‹„„›˘›‹‹„ek]f]c|„…|‹‹„‚v{„Š„‹„‹“““zll{tt{u{[TT{{tllkzll{ttllklribVUultf]cdc\{{tVTL|||lri{zmkk]|lddtllŠŠ}‹„‹VTLred}“““›”›„„Š‹‹‹„„f]c|‚zsle‹„„||tllddc””‹š””‹‹‹„„‹’Š{zmbVU‚u“““dc\„„[[T‹‹‹{{t‹’Š“““‘Ś…||Š}ztlttsultttsfkkllk|‚z\[btts„„“Ś”mttlri‹‹‹tts‹‹‹””‹ult‚ut›”›ult‚|u{{t„Š„ttstll“Ś”Ł››š””Ł››{{t„„redf]cŠ}””‹‹‹„””‹¦§¨›˘›|\UZ”š”|‚z››”tsldc\{||‹’Šult‹‹‹{{t‚v{ztl}zll¦§¨b[Utzl„„ś››Š}dc\‘…„Š}‚wl{zm{{tuzt‹‹„ś››{tttzl{tt}››”{{t¤¤ťuzt”š”‹‹‹‹„„‹‹„“““u{{‹„„Ś”•”“›„Š}“““tsl{ttfkkŠ}|‹‹‹„„{||sle]cdtts‚|u|‚z|Ś—Łedkf]cult}Š„Š}|¨©´š””””‹|„…‚u‹‹‹„„|‰|v›”›™š¤µ¶·¤¤ť››”›˘›“Ś”“““”š”„„lddultultredš””Ł››Ł››“Ś”’…‹‚wl¦§¨JHF)+2››”ŠŠ}ult‹„‹”“››”›ŁśĄ‚v{sle‹„‹‹„‹lldlek[TTlks‚v{Ś”•|}„„Š”››uztu{{{u{‹‹‹¦§¨„Š}¦§¨¤¤ť|¦§¨Ł›››”›‹’Š‚|uŁśĄ”š”„„mtt[TT|‚zlek{||„„{||lldultddctsl„Š„sle™š¤’ŚŚjV[{{trfk‹„‹lek‚v{„„f]c||lddd\\d\\b[Ullk””‹rg]{{tkd\|„…‹‹„Š}|ttstts||sle‘Ś…””‹‚n‚|u„„Šš””ś››””‹„„}lddlddtllkd\‚utrg]f]cztl|’…‹‹‹„‚u}b[Ullddc\||}{u{llk{||tsl‚|u””‹{tt‹„„ddcŠŠ}{u{ddc„„‹„„“““tt{{{ttt{„„Š™š¤„„UTS‚v{lek|‚zddcd\\‹‹‹kd\ztl…‹‹“Ś”“Ś”¦§¨ÂľĆŁ››””‹¤¤ť«˛«””‹Š}ult‰|v“Ś”uzt„Š}‹’Š„„ś››‹„‹‹‹‹ŠŠ}„Š„{||™š¤¦§¨“Ś”{ttd\\ś››š””||‹„‹“Ś”š””””‹„„‹’Š“Ś”‹’Š‹‹„˛¬µsre‹‹„sretsl¦§¨Ś”•›˘›‚v{Š}{{t||“““‹’Š‹‹„lld|‚z|ldd“““‹‹„“““}uzt||{u{„„Š‹‹„„„‹„„ttsŁśĄ|…‹‹‹„„]bZ‹„„‚|u|‚zś››‚|u\[b\[bbVU‹„‹kk]„„“““›˘›|„„“Ś”tsllld{u{Š}|ŁśĄ¦§¨dc\””‹¤¤ť{zm”“›ś››Ś‹“ś››„Š„“Ś”‹„„‹„„zll¦§¨‹„„ŁśĄ‘Ś…‹‹„˛˛¬\[b*)(zll[[T{tt‚|uddc{tt„Š„ś¤¦||ult{{t‚|u„Š„š””}edk{||“Ś”tt{‚|uztl|‚z„Š„ult“Ś”tzl”š”‹‹„„Š„‹‹‹“Ś”||„„ztltts]cd””‹|‚z‹’Š””‹|„…u{{‹„‹…‹‹llklddtllmtt|š””ŠŠ}tts‹„„{u{}™š¤tllUMRllkttstll{ttmwSKJ[[Td\\“““’…‹cbV‚|uyle‹‹„„„š””‚|ulldŠ}tts‹‹„sleŠŠ}””‹ŁśĄ{u{™š¤“Ś”zllrfkf]ctsl{tt{tt{zmŠ}…‹‹||‹„„™š¤”››|‹„‹‹‹‹kd\llk||‚z‹„‹zlltsl{zm|’ŚŚ{ttš””„Š„‹’Štlltsl|„…{{t{||“Ś”{u{Ś”•‹‹‹‹…’”“›lri‚v{ult{||¦§¨“““||‹„„|Ł››””‹“Ś”“Ś”Łť˛ĂĽż¦§¨{zm¦§¨Ś‹“ś››˛¬µ{{t‘…„f]c“““›˘›¦§¨||„„Š‹„‹ŠŠ}{{tś››lri””‹|‹„‹‚v{lekf]c‚wl{||“Ś”šŤŚ””‹|“““›”›ś››{{t“Ś”sre””‹¦§¨‹’Š|‚z–˘‹‹‹‹ddc‹„„{{t‹„„šŤŚtslŠ}llk\[[}ztl}}fkk¦§¨“““Ś‹“””‹“Ś”Ś”•ultllksle‹‹‹“““|‚z{||„Š„VTL\UZ„Š}ŁśĄlddedkUMRŚŚšf]c‹‹‹{{tult{||‚ut‹‹‹ttslddllk””‹Š~‹›”›’…‹uzt‘Ś…tsl””‹‹‹‹Š~‹„„Š|‚z‹‹„„„‹‹‹Š}j]\‘Ś…|‹‹„tt{š””µ¶·f]c*)(tll‚|uš””‹…’mtt{u{Š}|{zmtslf]c|‚zlrikd\[TTtt{‚|ulri™š¤}dc\„„Š„Š}„„‹„„{tt¤¤ťś››Ś‹“›”›tts˛««‹‹‹‹„‹‹‹„{{t||”››|„Š„‚uŚ”•”“›tt{“Ś”Š~‹‹‹„‹’Š{{VTL‚v{|‚z™š¤‹‹‹’…‹|„…}Š‹„‹‹‹‹}Ś”•‚utdc\kd\\[[‚ut||{{t‹‹„‚|ulri‰v|ttsttsllk„„|‚z’…‹j]\‹’Š{u{i\Vsreš””›”›Š}||VTL‹„„ylellkztfmwlddtsl{zm|„Š}{u{‹„„‰v‚utś››‚ullk„Š„sre}d\\kk]Š}‚ut{tt‹„„‚ut{||ekd„„”š”tsl}|{||{{t{{››”ŚŚš™š¤{u{‹„‹¦§¨{{t¦§¨µ¶·‹’Š‹‹‹“““ŁśĄŚ”•‘Ś…ŁśĄ‹„„‘…„’ŚŚ™š¤|¨©´tll‚v‚““““Ś”{u{ś››””‹“Ś”ekdŚ‹“}‘Ś…|‹„„kk]ttsrfk‹‹„‚v{||zll‹„„lri›”›‘Ś…‹‹‹¦§¨”››Ł››‹’Š‘Ś…‚utŠ}{{t‹’Š‹‹„‹’Š”š”{u{tsl{{t‹‹‹u{{ddctts‚u…‹‹{||„„{{t„Š„‹’Š¦§¨{u{“““tll›˘›‹„„‹‹‹‹„„‹„‹””‹…‹‹”››lek{{|„…d\\ult{zm¤¤ťultlkslks{u{rfkdc\„„}lri{{t”“›}„Š„{{t‚ut{tt›”›Ś‹“‹’Š|llk{zm}||tts{zm{{ttllrfkŠ}{ttsre||{yf‹’Šztl””‹JHF?;C‘Ś…‘Ś…”››‹„„}tzlulttll[[T›”›‹‹„\[[ult||tll||Ś”•|‚z||’…‹‘…„lri“Ś”‹‹„”“›“““ekdlld‹„„u{{ult‚|ukk][TT{ttkd\ddc‚|u„„{{t„„Š||“Ś”“Ś”tllek]‹„„ddc‰‰w„Š„[[Tllkd\\…‹‹f]c{u{llk‚utlrittstllultsle{ttj]\{||ddcsleztl[TTred‹’Šlddzll||\[[‚v{{||{{t™š¤{ttlld’ŚŚ‹‹„u{{{||lek“Ś”Ł››tsl||ztl…‹’tsl„Š„”š”|‚zŁśĄš””””‹|„…{{‚ulri|lld‹„„dc\{tt|ztfult||‹„„lks{{t“Ś”|„…‹‹‹›”›””‹{u{tll™š¤llkŁ››ŁśĄ‹‹‹dc\|‚z””‹ś››‹„‹¤¤ť’ŚŚult””‹”››tll}ult|‹‹„lld”š””››lriŚ”•tll||””‹kk]‚ut¨©´›”›„„Š‹„„‹„„››”tts{||››”…‹‹rg]||šŤŚŁśĄ‹„‹„„}Š}|||‹„‹{||˛¬µŚ”•Š}‚ukk]‰v›˘›‹’Š”š”|’ŚŚ‹„„¦§¨ś››„„ldd|„…|„…‰‘~]bZult‹…’|››”sle„„llk}””‹‹„‹|‚z}{u{„Š„„„„„Š‹‹‹„„Š|‚z]bZŚ‹“›˘›„Š}|„…JHFlksult›”›‹’Š|’…‹|tllŠ}{{Şł·“Ś”‚wl‘…„„vŚ‹‹‹¨©´””‹sletts””‹‚ut’ŚŚ{||ttsś››ztl“Ś”‘…„‚|uztl‹‹‹{{tek]¤¤ť:97*)(‘Ś…tlltslekdult‹„„Š}|ultkd\mtt||„…u{{kd\{u{lddekd{{lekVTL™š¤ś¤¦ś¤¦”š”“““„„ś¤¦{{{|||„…’ŚŚ››”¨©´lldtll|‚z›”›||tsl„„¦§¨”“›ult”š”|„…‹’Š„„ddc||}{{t\UZllk„„Š‹‹‹{u{}ultj]\“Ś”r]g{||||{u{j]\›”›Š}tsl‰|v”››Š}Şł·ult{yfšŤŚtzl‚utbVUllkzll’ŚŚf]c||‚uttts\UZ{{tztl|||‹‹„šŤŚlld{{tz‚lŚ”•tts”››””‹{{t’ŚŚtts‚ut{||‹‹„„„“““d\\‹„‹ztf’ŚŚzll‹„„’ŚŚ„„››”ult…‹‹||š””Ś”•{u{›”›lks‹„„”››llk“““Ś‹“””‹ztl™š¤ś››˛¬µŁ››{{t{{tllk‘Ś…‚v{š””””‹ś¤¦‹‹‹›˘›ś¤¦“Ś””“›{{‚utkd\lld”š”‹„‹’ŚŚ¨©´‹„„„„{{t„„tzl›˘›‹‹‹‘…„¦§¨››”ŁśĄ¦§¨Ł››“Ś”Ł››‚|u{{t„„‹„„”š”{u{“Ś”dc\‚ut{{tjcVś››“““{u{lek›˘›””‹„Š„mtt‹’Šuzttzllrimtt\UZmtt”š”ś››{tt‹’Š‹„‹›”›¦§¨ś››ztltt{Ś”•¦§¨”“›„„Š›”›”“›‹’ŠtllŚ”•ś¤¦|UUYUMR\[bult‹’Š”››…‹‹uzttll“““}Š{||lks””‹ulttt{ldd„„“Ś”sretsl||‹„„tll„„‹‹„{u{“Ś”‚ut‚v{ŠŠ}{{t|‚z||lld¦§¨VTL74,‹’Šš””‹’Štt{“Ś”||‚v{[[T]bZlek‹„„”š”ztllri{{ult{||llkultkd\sle¦§¨Ś”•‹’Š¦§¨Ś‹“¦§¨‚utš””„„“““”››{{t||””‹Š}{||“““b[U›˘›ś§˛ŁśĄŚ‹“mttŚ”•‹„‹ultf]c‹„‹ldd‹„„tts‹„‹uztSKJ[TTultult„„Šllki\V}{tt‹„„””‹j]\Ł››||¤¤ťŚ”•‹„„dc\‹‹„ŠŠ}{{tVTL‚utSKJtzlb[U{ttSKJ{ttkd\„„bVU[TTŠ}{ttuzt‹„„zllkk]tll{||‘…„‹’Š“““lddbVU‚utkk]lri‹‹‹ttsŠŠ}…‹‹|‚z“Ś”¤¤ť‹„„{ttrfk‹‹„{ttŠ}‹…’‹‹‹”š”tts”“›tllš””{{„„„„Š“Ś””“›{tt›˘›kd\”››“Ś”‘…„ultttslld‹„„sle›”›}Ł››‹’Š“““”š”““““Ś”|„…‹…’Ś”•‹„„””‹Ł››“Ś”Š}“Ś”“Ś”¦§¨›˘›’…‹u{{tzl}edk“““¦§¨‰v|red¦§¨“Ś”‚ut|„…Š}‹‹„{||”“›‘Ś…Ł››‹’Š{zmŠ}„Š„¦§¨š””ś››™š¤››”‹„‹Š}Ś”•{{t||‚z|‚z’llk”š”|‚zddc„„…‹‹||{u{‹u…„Š}tt{‹„‹”››”š”Ś”•µ¶·ś››lri‹’ŠŚŚš¨©´‹’Š}Š[TTf]clek¦§¨{||lld|‚zmtttt{{{t||tt{{u{redd\\}™š¤””‹{u{‹‹„tslztlulttll‚ut„Š}‹„„Š}šŤŚ{tt‹„„…‹‹tzlmtt{zm›˘›JHF:97{{t‘}dc\…‹‹Ś‹“š””ztlztlllk‹’Šdc\|cbVz‚l„„Šult››”llk{||ultŠ}„‰v|„…|}“““‹’Štt{¦§¨¦§¨{tt”››tt{‹‹„lriztl{||tll|VZT|‚z™š¤tt{fkkllk||[TTJHFf]c\[[lldultf]cf]c\UZllk‹„„ult‹‹‹lekyfllek¤¤ť}{zmŠŠ}‚wlSKJšŤŚd\\JHF{{t|‚zsre’ŚŚ{{t||red{{t‚|usre{||Š}|cbVtllzll‹’Š{tt‹‹„‹„„ztl‚uttllllk||‹‹„{tttzlVTLtll]bZkd\‚u|”››‹‹„™š¤lld{tt|‹’Š“Ś”‚v{’ŚŚŠ}|››”{|||„…„Š„tt{Ś”•“Ś”‹„„„„Š‹‹‹{ttmttultzll„„¤¤ť}lddlddŁ››“Ś”ddc||‘…„¤¤ť””‹Ś”•”››tts”š”””‹ŁśĄ„„Š}¦§¨‚u››”ŁśĄ’ŚŚ“Ś”Łť˛‚|uredu{{ztl’‘~Š}||š””ŁśĄ{tt‹„„b[UŁ››kd\Š}kd\‹’Š‹„‹|Ł››Ł››””‹Š}|{{ttts””‹””‹ŁśĄ{{tlri‹’ŠŚ‹“tsllriz}‹’ŠŚ”•tsl“““ult””‹ztlzllś¤¦Š}||{ttŚ”•„Š„ztl”š”…‹‹”››‹’Š”“›||‚z\[[›˘›lldŚ”•‹‹„’ŚŚ{u{‹…’’ŚŚŚ”•„„ś¤¦™š¤‹…’‹„‹uzt‹„‹¤¤ť‹„„{tttll¦§¨|{zm„„ŠŠ}|ulttll”››{zm{{t’ŚŚš””tll‹‹„‹‹‹”š”“““””‹¤¤ťJHF*)(ultcbV|‚ztts„„]bZŚ”•red{ttj]\‹’Štsl|kk]ult¤¤ť”“›Ś”•f]ckd\bVU‹’Š…‹‹dc\d\\¤¤ť‹’Š|‚zŠ}|}Ś‹“|“Ś”zllŁśĄ{{t{{llkuzto€wlkstt{™š¤u{{Ś”•UMRd\\ldd‚v{UMRj]\ultmwtsledkUTS||||tt{‘Ś…tll‹‹„‹‹„{{t[[T{ttredztllldlri}tzl{{td\\‚u‚|u||‚u{||Ł››ldd{tt[TTd\\FD;rr]{tt{tt“““š””tll‹„‹„„‹‹‹tsllldd\\ztl{{t””‹ztltzl{{t|‚z’…‹‹‹‹…‹‹‹„„ztl„„rfk”“›‹‹„{u{‹‹‹{{ztllddj]\mtt‹„‹{ttlek“““„Š„tt{\[bllk|‚z””‹™š¤|||tll{||„Š„’ŚŚ„Š„¦§¨ś››ŁśĄ{||”š”Şł·ś¤¦‚uŚ”•Š}··ÄŁśĄ¦§¨«˛«ś››f]cŚ‹“‹„„{{t„„f]c‹’Š‹„„“““ldd{ttŠ}tllŠ}cbVddc{u{š””||ztltts|Š}–˘‹››”””‹|„„š””ŁśĄ„„Šztl{{t‹‹„…‹‹u{{lddlriŚ”•mtt]cd]cdŠ}edkj]\‚|u‹‹„¦§¨redult”š”™š¤’ŚŚ™š¤š””¦§¨uzt}Š|„…dc\tlllri|„…|‚ztt{u{{™š¤{{t||„Š„|ś¤¦}tsl}|‚z}‹„„‚|umtt{u{{zm„Š„ztlddcztlult‹‹‹{ttztl||kd\‚|uultf]c{{||”š”Ł››“““>EC:97tslSKJ{{tŚ‹“‹’ŠVTL‚wlŠ}|{u{d\\rg]|‚z„Š}mtt‹’Šš””™š¤{{tbVZ{u{sre|„…‹‹‹|{||zll|‚z{u{””‹”š”uzt”››ulttll{{tldd}Š{tt|‚z‹’ŠUTSŚ‹“ult\[blrilldf]ctllŁśĄmwtsllek‹„‹””‹…‹‹JHFuzt¦§¨{tt[[T›”›{||kk]’ŚŚ‚utSKJred‚v{‹’Šllk|‚z‹’Š‰v‹„„d\\tslultedk}“““||„…b[Uztl‘Ś…„Š}kjV‚|utll„„{{t{tt›”›dc\||{||lld‚u””‹‘Ś…””‹‹„„‹„‹”š”}}tts{tt‹‹„{{t‹„„}|{||Ś”•‹„‹”“›|„…{||Ś”•ttslektt{{tt{||Ś”•‹„„ś››‹‹‹¦§¨}{{t’ŚŚ‚v{tslŚ”•š””‘Ś…“Ś”¦§¨››”’ŚŚµ¶·ś¤¦‹’Štslś››{tt…‹‹¦§¨›˘›¦§¨“““‹…’}š””¤¤ť¦§¨Ł››š””›˘›¦§¨Şł·ś››‹„‹‹„„{tttts{zm‹„„Ł››{tt{{t{ttŚ‹“\UZred‹’Š{u{uztš””Š}ś››‹„‹{ttbVU{|||„…]bZŚ”•‹’Š›˘›Ś”•…‹‹‹‹„ult””‹‹’Š“““„„Šult“““š””‹„‹“““|‚zultdc\llkkd\tlledkttsultfkklks\[blekllk{{kk]‹’Šś¤¦¤¤ťŚ”•ś››¦§¨ekdtts}Š{||‹‹„“Ś”{u{uzt{{tdc\|‚z‘Ś…“Ś”„„Ś”•{{tztf‘…„„„›”›llkšŤŚ””‹“““’…‹‹’Š:977-2”››‹‹„ŠŠ}”š”llk{u{|‹„„„„Š{u{tzllld|‚zlldu{{ttstt{lriultŠŠ}]bZkd\{tt||tll””‹lld’ŚŚŠ}‘Ś…|‚z}”“›rfk¤¤ť‹’Š“““|‚z|{||™š¤llktt{„Š„lksf]c{u{SKJ}Š{ttlldŚ‹“tll{tt‚v{…‹‹|‚z|‚zuzt[TT||llk‚wlrfkVTLsle||slettslld‹‹„tts|‚zsle||aWMSKJFD;ztlultu{{“Ś”[TT””‹slelldkd\‚|utsltts„Š„‹„‹uzttllb[Utyg{{””‹ztlsrekk]‹„‹{{t™š¤¦§¨››”“Ś”ddc””‹‹„„sle‹…’„„”š”‹‹‹|‚ztts…‹‹}Š{tttt{{||“““ddc‹…’{||{{tts„„Š‹„‹¤¤ťŠ~‹“““‘…„}›˘›‹’Š››”{{tŁśĄ™š¤’ŚŚµ¶·ś¤¦ś¤¦¤¤ť””‹¨©´µ¶·™š¤ś››µ¶·¦§¨“Ś”ŁśĄ“Ś”f]c„„mw‹„‹‚wl‚|u””‹””‹””‹„Š„„„Š“Ś”uztbVU››”“Ś”lld‹‹„ddctsl‹„‹{ttsle‚|u„„ult“Ś”{||“Ś”rg]|Š}„„lri{||ś››mtt|‚z„„Štt{ddc’…‹“““›˘›{||rfk››”ŁśĄ‹‹‹„Š}ztlŚ”•zll‹’Š||lddŚ”•|‚v{uztVTLultSKJtslŚ‹“[[Ttzl‹’Š‹‹„{||{||„Š„{tt””‹„Š„““““““Ś”•{{‹’Šult|„„{{t‹„„{u{“““”š”‹„„Š}|||tsl{u{‚|u{tt|„…uzt”š”>B9*)(zll|||„…“Ś”{{tllklddbVUd\\lddek]UTSlri[[T{{tslult{{td\\„Š}u{{cbVbVZ››”}sleb[U{||zll‹„„{||”“›}tsl{tt‚u|‚z„„Šuzt|„…|„…{{\[bJHFJHF\[[f]cd\\\UZb[Ud\\„„ttsd\\VTL}‹„‹{zmtsl{||‚|u{{t|„„Šf]c]bZslelddŁ››ddclld|‚ztzl‚|utllaWMsre{{{zmŚ‹“j]\tll||‹„„tslztlf]cb[U|‚z{||Š}Ś‹“dc\|„…zll‹‹„Ś”•ek]tsl‚ut‘Ś…{tt|lri‚v‚‹‹„}¤¤ťtlliq]tsld\\{||{{t‹„‹|‚z›”›{{}š””Ś‹“›”›}{{{||}”š”{u{||‹„„Ś”•Š}‹„„¦§¨’ŚŚ‹’Š”“›”››“Ś”™š¤‹‹‹””‹¦§¨‹’Š¨©´{{”“›}Š}“Ś”¤¤ťś¤¦sle“““Š~‹ŁśĄ’ŚŚ“““ś›››˘›‹’Š||‚|u{{t|||‚z“Ś”ŚŚš\[[‚v{„Š}ztl{||“““‹„‹tsllldj]\ttstzl{||‚wl“Ś”}„„lld||››”„Š„„„Šlldmttlks|„…lksuzt„„Š“Ś”››”‹‹‹{{ttts“Ś”}‹‹‹“““””‹Ś”•{{t||’ŚŚ‹‹‹lri„„ś¤¦”“›Ś”•r]glld„„mtt|‚z„Š„lddś§˛‚v{‹’Š’ŚŚ„„‹‹‹‘…„‘Ś…tt{{{|‹„‹š””Š~‹’ŚŚ‹‹‹‹„‹‹’Š{{t…‹‹{{t’ŚŚ“Ś”dc\VTLtllVTL]bZ’ŚŚJHFJHF“““‹‹‹|‚z|„…]bZSKJd\\ultddcd\\b[U|„…|‚zlekttssleultuzt‹‹‹‹„„{{t{{‹„‹“““|‘Ś…‹’Š|‚zllkldd|‚ztts{u{ldd}|‚z|‚zMRKddcult]bZlddultf]cmtt„„Štsl[TTultd\\lddu{{Š}tllj]\„„Šf]c‚|ukd\{||{u{[TTŠ}|{u{sreztl‹„„{zmcbV||„Š„tzltzlultkd\{||’ŚŚllk…‹‹zll‚utult‹‹„¦§¨kd\VTLsle””‹|‚zdc\“Ś”||ztl’ŚŚsresre”š”kk]tsl‚utsleldd‹‹‹‹…’ulttlllddllkSKJiq]tsl‹„„}‹‹‹Ś”•{tt{{{||llk‹’Š{{™š¤’ŚŚ™š¤|‚zŚ‹“™š¤||tts“““{{tkd\””‹||¦§¨Ś”•{||}””‹ŁśĄ‹„‹”š”›˘›”››™š¤ult‹‹‹|‚z™š¤ŁśĄuzt‹’Šś››¨©´Ś‹““Ś”tsl|„…{{tś››‚|u¦§¨“““ś¤¦Š}™š¤ldd¦§¨Ś”•“Ś”‹„„’ŚŚ‹„„ŁśĄŚ‹“„„dc\ldd‹„‹””‹‹‹„‹„‹‚|utt{„„›”›‹‹‹…‹‹tt{ś¤¦tsl|„…|„…{{t¨©´”š”„„ŠŚ”•{{|„…tts’ŚŚ””‹‚utŠ}Ś‹“sle™š¤””‹”››‚ut{||Şł·Ś”•ŁśĄekdś¤¦Ł››…‹’Ś”•ś§˛|‚z‹‹‹”››”š”¦§¨™š¤ś›››˘›tsl”š”}ztl{u{llk||¦§¨‘…„}‘Ś…‚v{„„””‹{{t{||{ttj]\ttsŠ}|‚zttsddc„Š„‹„„SKJ*)({||dc\lddtllVTLf]c‹‹‹{u{uztttstslu{{””‹lriu{{f]c‹‹‹„„u{{lld‹‹„Ś‹“‹„„„„…‹‹’ŚŚ||||˛¬µdc\b[U¦§¨‹„„„„Šllk“““‹„„uzttzlddcu{{d\\ddcJHFVZTSKJ“““’ŚŚ‚v{tt{[TTlks||tsld\\[TTddc””‹‚|utts’…‹{||red{ttd\\sle””‹d\\}\[[z‚lŚ”•„„bVZŠ}|’ŚŚ||||{||‚v{rg]rfkkd\‹„‹|kd\{{tslesrelld‹„„red|‚zsletslztl…‹‹{tt‚|uš…ŽŠ}|“Ś”‹’ŠŠ}{{t‚|u{tttsl|sle|‚v{tsl{tt”››„„Ł››tts|„…|{u{ttstt{„„mtt“Ś”™š¤‚v{llk{ttŠŠ}™š¤ztlŁśĄ‹„„‹‹‹¨©´’ŚŚ™š¤“Ś”“Ś”„Š}‹‹‹|‚z¦§¨„„„Š}¦§¨“Ś”‹„„„Š„µ¶·ÂľĆŁ››Ł››Š~‹›˘›”š”„„Š›˘›Š}¦§¨‹‹‹{tt¦§¨””‹‹’Š›”›{||“Ś”tts‚utŁ››’ŚŚ‹„„‘Ś…{||Š}Š}}Š”š”‘Ś…‘Ś…”“›ultś››››”|„…lriš”””››|„…’Ś‹“…‹’|„…|‚z”“›ult|„…dc\“““˛¬µ’ŚŚś››{u{}”“›‚|u{zm{tt‹‹„™š¤Ś‹“‹„‹„Š„Ś‹“}{ttttsu{{Şł·¦§¨„„Ś”•Ś‹“j]\””‹””‹uzt‹„„tsl‚v{}uzt‹‹‹‹‹‹bVU||ztl‹„‹Ś‹“{{t{tt{{t‚ut{ttllk‚|u{{t|‚z\[[dc\‹‹‹:97&&UTSd\\d\\u{{ztl|„…š””™š¤{{t„„ś¤¦””‹|‚z|„…“““”š”“Ś”mtt‹‹„„Š„sle”››ŁśĄ‹’Š‹’Š‹‹„{{tlld›”›sletts‹‹„ŁśĄŞł·{tt“““ekd…‹’ekdsrelrif]c‹„‹{{mttsle{zmzll||Ś‹“¦§¨ldd››”lektlledkult{{t\[[|„…ŁśĄf]cttslddtslkd\sleSKJ‹‹‹\[[leklldtts{u{tll””‹{{t}š””ztlrfkttssle””‹VTLtllsleztf{u{uztŠ}f]csredc\Š}sre{u{{zm{||Ł››Š}|‹‹„“““lldkd\‹„‹{tttlld\\„Š„sreś››„Š„{{t™š¤Ś‹“||ttstll{u{mtt””‹{tt”“›‹‹‹{{{{{tt{{f]c”››”“›‹‹„Š~‹ŁśĄttsŚ—Ł››”tts’…‹}ŠŚ”•‹’ŠŚ”•|tsllri…‹’¦§¨‹‹‹“““»ÂÇ”š”“Ś”˛¬µ›”›””‹tsltsl›˘›š””Š}|ult”š”””‹‹„‹‚|u{u{{{t{u{š””›”›„„tts‹‹‹}{{“Ś”llk›”›‹’Š||š””|‚z‹„‹{{‹‹„|„…mtt\[[‹„„„„|„…|„…Ś‹“mttŚ”•f]cd\\|‚z|‚ut‹…’‹…’‹„‹„Š„tllmtt‹„‹tll”š”|›˘›…‹‹™š¤mtt™š¤¨©´ztl{ttŚ”•Žˇ›”››u{{ś¤¦tts}¦§¨‹‹„Ś”•”››|lrilekttsŠ}|{||{tt{{t|‹‹„š””‚uuzt‹„„‚ut‚v{lks‘…„‹„„{||{{JHFŁ››:97*)([[TSKJJHF\[[lri“Ś”{||‹„‹tsl{ttlri‹’Š|‚zŠŠ}„„u{{™š¤kd\„Š„„„Ł››…‹’‚v‚›˘›Ś”•|‚z‹„‹ś¤¦“Ś”¦§¨„Š„Ś”•¦§¨“Ś””š”¦§¨f]cf]cVTLek]kk]Ś”•ultd\\VTLŠ}{||„Š„f]ctt{Ś”•edkš””lddedk„„ŠuztVTLmtt…‹’ldd„Š„‹‹‹||kd\lddzlllks||š””|„…{||{u{||lddtlld\\u{{|f]c[TTtll||‚|u{zmj]\zllj]\{{t”“›tllŚ‹“{{tSKJ…‹‹¤¤ť|‚z„„ŠŠ}|ldd‹„„‹‹„}{tt‚u‹‹‹„Š„“““ldd‹‹„‹’Š“““|‚z…‹‹{{{tt{{t{{‹‹„sle{||„Š„uzttts{u{||{{{tt{u{‹’ŠtslŚ‹“‹„„Ś‹“ŁśĄtslŚ”•llktt{“Ś”lek„Š„”š”|„…›˘›ś››„‰vŚ”•ś››¨©´Şł·…‹’ś¤¦tt{‚v{˛¬µ””‹ś¤¦Š}|‹‹„‹‹„|Ś”•””‹ś››}‘Ś…™š¤|‹„‹{||Ł››’…‹Ś‹“””‹›”›Ł››Ł››{{›”››˘›¦§¨ś››|Ś‹“{tt‚v{}„„‹„„zllmtt™š¤|„…ŚŚšJHFlldlks{ttsleldd“““™š¤‹„„‘…„‹’Šš””™š¤‹‹„‹‹„””‹Ś”•ś¤¦”››Ś‹“dc\…„’}tts„„{u{lld’…‹„„Š¦§¨llk“Ś”“““{||tts|‚z“Ś”lek{{ult‚|uztl‚v{‚|u‹‹„š””‹„„„„Štzlś››‰|vtlluzt”š”ttsllklld{{t››”SKJ*)(lkslldVTLUTSsref]ctllbVZtzllldmtt|‚z{{t||‚z„„Ś”•‹’Š‹’Šlld›˘›Ś”•šŤŚ¦§¨{||\[[‹’Š‹‹„””‹}Š{||…‹‹tll››”|‚z›˘›ŚŚšult”››lld{||mttŁ››dc\MSS“““…‹‹”››’…‹{{„Š}lriztlsrezllŚ”•ttslddztl{||‹„„llkf]cllkultVTLsre{zmzll|f]ctsl{||{u{dc\SKJ‹„‹ultlld„„nf]c{||ŠŠ}””‹‰vŠ}ult{|||‹„‹tts{zm{tt””‹‹‹‹“““{||{tt{tt‘…„tslŠ}Ł››|‹‹‹kd\sleulttll|Ł››{{tŠ}„„”››‚ut…‹‹“Ś”llkllkttsllk™š¤{u{ddc…‹’Ś‹““““‚|u||”››”š”’ŚŚ¦§¨ś¤¦|‚z‹’Š{{{u{}ŠŚ”•‹‹„|‚z‹„‹¦§¨›˘›«˛«™š¤”“›„„Šš””‹‹‹}‹„„]cd„„|„…š””uztkd\’ŚŚ{tttsl”š”Ś‹“{tt›”›|‹„„lek›”›¦§¨Ś”•{tt¤¤ť‹„„’ŚŚŁśĄŠŠ}tzlš””|”š”‹‹‹tll}|„…redUMRtt{…‹‹UTS„„Š…„’„„…‹‹}“Ś”‹‹„ŠŠ}Š}|¦§¨µ¶·“Ś”‹‹‹“““tll“Ś”””‹››”›˘›Ś”•…‹‹lri„Š„{u{¨©´ŚŚš…‹‹u{{’ŚŚŚ”•”š”‹‹‹tt{™š¤uzt™š¤tts„„Š›”›¦§¨„„|tslš”””“›‰v||Š}kk]|„…ldd¦§¨š””’ŚŚ”š”‹‹„””‹{u{“““{||˛««JHF3+*”››||„…UTSdc\Š}|‚ut[TT{||lkstsl|‚z||‚z|‚z}“Ś”lri’ŚŚ{{””‹|‚z›”›{||‹’Š||ekd…‹‹rfkkd\‚utts||“Ś”‹‹‹›˘›Şł·‹„„mtt>B9JHFlks|tsl””‹\UZ{{…‹’Ś‹“\UZfkk››”VTLult‚|u‹„‹¦§¨…‹‹d\\\[[ult‹‹„ek]llkbVUj]\tzlztlslekd\ult¦§¨‹’ŠŠ}ldd{tt{u{tt{b[USKJiWU{u{”“›„„{zmVTLrg]sreedk||{tttts„„„Š„‹„„Š}|‹‹‹zlltll||rg]ztl||ztlbVUlddu{{Š}kd\lldtsl‹’Štllsle{{t‹‹„{ttllkedk{ttttslldedk{u{tt{llklks|„…sre„Š}Ś”•Ś”•¦§¨ÂĹÓ”“›¦§¨…‹’”š”ś¤¦”“›“Ś”‹‹„|‚z¦§¨„„‚u›˘›ś¤¦™š¤Ł››{u{{{””‹‚v{lrif]cdc\”“›ś¤¦|‚u“““„„Š‹‹„‰‰wsretts{tt””‹ŁśĄ„Š„š””‹„‹”“›‹‹‹„Š„ult‚v‚tllult|‚z„Š„{{tś¤¦‹„‹’ŚŚ‚v{„„ldd{tt{||ś¤¦…‹’…‹‹{{›˘›lkslek‹„„‹„„|‹‹„‹u…’…‹‹„‹‹‹„’ŚŚ{{››”{{t¦§¨ŠŠ}¦§¨™š¤…„’{{tult„„Š|‚zŚ”•llktslmttŁśĄ|„…llklddlek{{{{t„„‹„„|‚v{’ŚŚ¨©´¦§¨š””||””‹“Ś”‹„‹ś››‰vkd\redulttsldc\sle}lek„„””‹JHF{{tlldkd\UMRUTSlksSKJUTS]bZ||lritslkk]tslllk{tt{||||Š}|‚ut|‚z¦§¨‚v‚ś¤¦|‚z‹‹„|‚ztsl‹‹‹‹‹„…‹‹llkj]\Ś‹“|‚zŁśĄ{u{tt{\[[|‚zlldŚŚš“Ś”uztkk]||tt{lek{u{“““dc\f]cuzt‚|ucbVu{{tzlddc|dc\sle|””‹‹‹„VTLb[Ulri{zm‚v‚ek]lldsle{||’ŚŚllkd\\›”›JHFttsb[UbVUztl{zmtzlŠŠ}SKJ]bZfkk|‚z‹„‹tll“Ś”[[TtslultŠ}|}llkyle‚|u’…‹tll||‚v{ztld\\{||yletlllri‚wlj]\‹„‹uzt‹‹‹ldduztult“Ś”‹„„{{{u{{{Ś‹“lekmttddc„„Š™š¤{||¦§¨Ś”•{||··Ä¨©´ś¤¦Ś”•|‚z™š¤‹‹„u{{”“›„„Şł·¨©´Şł·Ś‹“¦§¨Ś”•‹„‹tsl™š¤ś››’ŚŚ‹„‹’ŚŚ¤¤ť”››“Ś”“““‹’Š||‹‹‹¦§¨tsl“Ś”‹‹„}tllŁśĄ„„Ł››‹„‹‹„‹„„‹’Š‹‹‹Š}ttsš””‹‹‹{{t||[[T“““{|||‚ztll}„„ś¤¦mtt|„…fkkŁśĄ”“›“Ś”‚v{‹„‹„Š„|‚z“Ś”‹„„tlllri‹‹‹‹„‹ŁśĄldd‹‹„‰‰w”š”|„…{{u{{¨©´Ś‹“lri„„Šllk{{tlks‹’ŠŚ”•‹’Šylelks{{tsl|‹„„lks‚v{‹‹‹{{Š}‹„‹ztlztlbVZ}™š¤ztld\\Š}{u{„Š„}srelekedk„„Ł››JHF:97llklldj]\lek[[T„„Štslldd{||lekdc\dc\{ttb[UŚ‹“lkstsl‚|uŠ}ŠŠ}|Ś”•{{ś¤¦””‹“““‹‹‹sleś››{u{ttsŠ}›”›‹’Šlld}lddmtt|„…mtttll{{¨©´“““sle‹‹‹„„f]cJHFlks|„…b[UJHF{{tD;9u{{|‹‹‹ś››tts{||b[U]bZ[TT||‹’Š„„dc\||ttstsllldllkztl{{‹’ŠlekbVZf]c||‚v{Š}|||ztfrg]VTLd\\lldllkttsf]c„„‚u|‚z‚|uŠ}lld‚|utll‘}zll’ŚŚrg]j]\{{td\\|‚z‹„„ztltt{‹‹‹uzt‚v{„Š„lldlld„„mtt…‹’}„„Š{u{Ś”•|„…mttllk\[[›”›‹’Š{{Ś”•|‚z„„Łť˛”››|„…ś§˛›˘›Ś”•„„ŠŁśĄ“““Ś”•‹„‹{{Şł·››”lks™š¤Ł››||{{t¨©´“““ś››Ś‹“„Š„”››¨©´‹’Š¦§¨¦§¨„Š„uzt¦§¨“Ś”{u{›”›‹„„’ŚŚ||””‹ultddc“““slerfk{u{{tt‹‹‹ś¤¦{{ttzl]bZmtt„„Ś‹“lri{ttŚŚš{tt\[[mttŚ”•{{}ŠŚ”•tt{‹‹„fkk{{t„„}Šztlś››uzt’ŚŚ“Ś”{{‘Ś…‘Ś…‚u„„Šedk}‹‹‹¨©´{u{lriultn|„…{{”“›lri‚utš””“““‹‹‹{{››”¦§¨”“›„„‹’ŠŁśĄfkk‹„„‚|u””‹{tttzlŁ›››”›{{t‚v{{u{tsllddcbVSKJlddf]cŁ››JHF*)(\[[[TTSKJ‹’Šdc\}[TT‹’Š{{tlddSKJtsliq]b[U{{tek]‹‹‹sle””‹lldlrittsultlld]bZ”š”ddcŁ››ttsf]cttsu{{ultUMR‚|ulddultŚ‹“}‡’|‚z{tt”“›yfl{||‚|utsltt{edkSKJlksuzt{{tJHFtll\[[‹’Škk]›˘›„„‹‹‹||lldś››Š}{zm{ttddcb[U{||z‚l‹’Š”“›{||b[Ud\\VTLf]c\[[b[UUMRj]\‚|u{tt‘Ś…‚|uredsre|…„’„Š„{||„Š„uzt”š”kd\kd\„„™š¤Š}{{t|tsl{u{‘Ś…lritlllld{ttzllyle|tslttsŚ”•lldekd‹‹„{{Ś‹“yl„]cdultuztult{{{||tt{¦§¨…‹‹”››uzt…‹‹¦§¨Ś‹“¨©´ś¤¦lrimtt…‹’Ś‹“‹‹‹„„‹‹‹|„…“Ś””››|„…ŁśĄ¨©´¤¤ť‹„„ś¤¦“““¦§¨··Ä‹…’ŠŠ}{{{u{{{|…‹‹”››“““µ¶·Š}{tt}||“Ś”}{tt}„„Š“Ś”‹‹„‹‹‹“Ś”‹…’…‹‹|‚zś¤¦mttddctzl{{ultf]c||UUYlddś¤¦|„……‹‹rfk‹…’mttf]cd\\edkŁ››”››{u{||||››”“““lld“Ś”’ŚŚµ¶·’ŚŚ„„™š¤‚|uŁśĄŚ‹“‹„„”››„„Šmtt„Š„f]c‹…’Ś‹“’ŚŚ’…‹„Š}„„Š‹‹„‹‹„˛¬µ‹„„ttslri„„Š||llk|ttsred{{tŠ}{{t|tll‹„„\[[{{tkd\‹„‹ek]fkk˘—ŤFD;3+*Ś”•VTLb[Ulrisreldd||[TTJHFd\\\[[||sre{zm|ztl‚utztlztllld””‹…‹‹“Ś””››ult|„…uzt‹‹„{u{uztult||tt{llk„Š„lektlld\\[TT\[[[[TŚ”•ś››„„ŠbVUztlb[Uttsf]cf]c{||Š}[[TVZTŚ”•|‚z…‹‹tzl|‚z{tt{u{{zmrg]“Ś”ztfkd\dc\{{tultlrikk][TT„Š„’ŚŚtts|„„Šdc\ek]\[[mwiWUzlltsl’ŚŚlldldd|„…Ś”•lri””‹|„…tsl‹’Š‚utŠ}|‹„‹Ł››srekk]kd\ekd‚v{bVZdc\}tygb[U||redlldlekult|‚ztts{{t{{t}„„Š”“›{{{{]cd{{”“›tt{{||™š¤|‚z{{›˘›Ś”•tt{‹…’ŁśĄ…‹‹{{Şł·…‹š‹‹„‹‹„”››Ś‹“Š}|“Ś”¨©´…‹‹™š¤‹„‹š””‹‹‹{||‹’ŠedkUUY{{¦§¨tt{š””ultŚ”•‹‹‹¦§¨ŁśĄ¤¤ťuzt’ŚŚultŁśĄ‹…’’ŚŚ{||{{tldd„Š}{{tred’…‹ztl”››”š”…‹‹š””tsltts{tt{u{}Štslu{{„„‹’Šlks„„mtt}Š]cdtts‚ut{{„„|‚z”“›Ł››rfk‹‹‹’…‹ś››‚|u’ŚŚ“““¤¤ť™š¤„„Š‹’Š™š¤tt{‹„‹“““{u{„„ŠŚ”•lks‹…’Ś‹“Ł››”š”„„‹‹„Ś‹“’ŚŚŁśĄttstllulttts’…‹f]cz‚llri{u{‹„„ś››‹‹„‚uttts’ŚŚ|„…]cd‹‹‹{u{{{tllk””‹SKJ*)(|‚zd\\\UZ[[TJHF„„ultddc|‚zsle‚ut‹’Š|‚z””‹“““‚v{ultlldzll|‚z“““kd\„„™š¤‹‹‹ś››Ś”•{{t‚v{}…„’kk]f]czll¦§¨ddcnult…‹’›˘›ult“Ś”ŁśĄ”š”tt{kd\{{f]cult\[b{||\[[„Š„llk“““ś¤¦tt{dkV]bZ{u{|‚zslesleztl‘Ś…ekdlri{||[TT{zmsle‚wl}Š}|”“›{||“Ś”‚wl||dc\Š~‹‚wlŠŠ}‚nŠŠ}kk]›˘›tsl„„lri‰v…‹’|‚ztsl‘}Š}ztlcbV|‚zd\\‚utultŠ}edk{{ttlltslb[Utlltll||mtt{{tuztkk]lld{{tlks{{‹‹‹}Š…‹‹{{{{tt{„„||Ś‹“™š¤™š¤„„ŠŚ”•‹‹‹‹‹‹¨©´™š¤Ś”•…‹’¨©´¨©´¦§¨›˘›…‹štll‹‹„™š¤ŁśĄ¦§¨ŁśĄ¦§¨Ś”•„„{{tš”””“›{{«˛«mtt|¨©´{{}™š¤”š”ztl{u{‹„„ŁśĄ¦§¨›”›µ¶·Ł››Š}‹„„„„Šttstsl{tt||…„’„„|‚z‹„„{||Ś‹“ztlult„„Š‹‹‹nv‚{||lri‹„‹„„Š[[T{||{{ŚŚšf]c„Š„[[T„„{{t˛¬µlritsl‹‹‹tt{”“›‚|uš””‹‹„“Ś”}Š›˘›””‹…‹‹™š¤„„Š”“›‹‹‹|‚z“““™š¤{{“Ś”||{||{||sle{u{{u{j]\j]\¨©´Ś‹“ś››‚v{{{t””‹‹„‹”“›¤¤ťŠ}’ŚŚ“Ś”tll|uztuzt‹„‹„Š„{||””‹D;9*)(f]cVTLlriu{{sre{u{ztlVTLttsddc[TTuztlri‹’Štzl‹„‹ŁśĄuzt””‹lriult|‚z{tt¦§¨“Ś”„„”š”{{t’ŚŚ”››{||d\\llklri|tts‚v{{tt‹…’Ś”•‹‹„||›”›ultultŠ}„Š„uzt”“›JHF[[T‚utlritlldc\”“›tt{]bZkd\tsl{u{red‹„„slelddtslŠ}sle\[[{{t‹’ŠbVU{{tztfŚ‹“‘…„rfkldd‹‹„sreŠ~‹r]g{|||{u{lri›˘›„„|„…lek[TTb[Utsl[[Tsle‘…„dc\tllrg]|‚z‚|u{tt{u{kd\{zm[TT||‹„„’ŚŚztltt{uzt„„lri“Ś”„„}tt{‹„‹}‡’“““…‹’Ś”•{{…„’|„…”“›|„…edk„„Ś—Łś¤¦{{{{„„Š|„……‹’‹‹‹ś¤¦“““…‹’‹’Š”š”¦§¨¨©´}ŠŁśĄ·¶Ńś¤¦Ś”•„„Š”››}tzl„„Š{{lks{u{Ś”•Š}¦§¨‹‹‹tts„Š„{u{llk‹„‹‚v{µ¶·¦§¨{u{tll{u{tll|{ttultllkttsu{{‹’Š¦§¨””‹¨©´|„…{u{lks†~‘edk›”›„Š„“““„„Š„„Šlks{{lksb[Uyle’ŚŚ””‹“““››”|››”¦§¨“““{tt’ŚŚ‚ut„Š„Ś‹“|||‚z“““‹‹‹Şł·…‹‹„„tt{|„…”“›‹„‹™š¤tll‹„„tts{{ttsl‹„„‹’Š‹„„“““Ś”•ś››š…Ž‚u’ŚŚŠ}}|„…|’ŚŚ{tt’ŚŚ||tts„„{||{tttslfkk””‹MRK*)(leksre]bZ{tt„Š„lddkd\d\\UTSUMR{{tuztmttdc\{zm‚v‚tll“““ldd|„…SKJu{{|„…|„…‚|uŞł·Ś”•‚u‹‹„™š¤‹„‹Ś‹“„„¦§¨kk]\[blksŚ”•edkldd…‹’bVU„„Š””‹{tt‹‹„{zm{{{u{{u{tll|tzl””‹|„…””‹[[TbVUlri“Ś”Ł››FD;ttsredkd\b[Ud\\{zmVTL›˘›|[TTllk||{||b[U{ttŠ}|sle’ŚŚ||kd\lld‚n{{tlld‹‹„{||Ś‹“|„…“““}lri|‹„‹’ŚŚttsb[U‹’Šek]ztlrg]‹„„‚uztf[TTtts‹‹„‚v‚zllkd\Ś”•llkuztddc‚|u{tttt{tsl™š¤ś››“““™š¤™š¤…‹š|„…Ś”•ŚŚšttsfkk}{u{{{›”›{{}‡’Ś”•|„…|„……‹’}‡’mtt|„…¨©´tts··Ä™š¤…‹’›˘›‹„„‹‹‹‹„‹“““ś››¨©´ttsrfkŁśĄŁ››‹„„“Ś”“Ś””š”‹‹„‹‹„{u{zll{||‹’Š‚wlś¤¦|‚z„„uztlkslri|‚zttsf]clekekd„Š„|‚zŚ”•™š¤|„…lkslriultlksdc\tsl|„…‹‹„Š}UUY{{}Š›”›š””kd\””‹›”›ś››‹„‹‹„„¦§¨“Ś”sle””‹ult{{t{{||‹‹„””‹‹‹‹{u{{{™š¤„„Š{||Ś”•“Ś”f]crfkŠ}|lriztl‹„„‹„‹›˘›‹‹„tt{Š~‹|ddcŠŠ}””‹||{u{ttsŚ”•‹„‹”š”‹„„ultddc„„{ttultsre\[[||JHF*)(llklldkd\lld‚u‹„‹ddcd\\UTS{u{ddcttszllddc{zmtll{||tts‚|u„Š„„Š„”š”ś¤¦‹’Š}lkssretsl’ŚŚlri“Ś”j]\j]\¤¤ť”š”{||lek}ŠŠŠ}{||[[Tf]c“Ś”|‚zzllkd\ttstsl„„‹‹‹lri’ŚŚ>EC|‚zŚ”•{u{uztztlŠ}’ŚŚ{{t{{tsle‹„„bVZu{{ldd{{tlld|‚zlriVTLŁśĄVTLultkd\||j]\||]cd‚v{VTLdc\dc\„„tzl{ttuzt’ŚŚ…‹’‹„‹yle{{tllk‚ut||ŠŠ}llktsl‹‹‹tllztl“Ś”{{tek]sle|‚ut}ldd‹„„‹’Š|‹‹‹lld}“““‹„‹{||“Ś”mtt{{{{lks…‹’|„…tt{”“›{||„„Š{{™š¤Ś”•ŚŚš|„…}‡’}‡’|‚z…‹’Ś”•tts™š¤“““ś¤¦Ś”•”››lksnv‚mtt“““|‚z{{™š¤}|}‹‹‹mttztl’ŚŚult“Ś”Ś”•{u{|¨©´“““||{{t“Ś”||llkddctts|Ś”•’ŚŚ‚v{lks{u{{{t„„Ś”•{u{{{…‹’ultlksUMR™š¤”››‹’Š|„…lri|‚z]bZUMRd\\b[U‹‹‹llk‹„„”š”|‚z{zm‹„„›”›}ldd’ŚŚŠ}|„„{ttŁśĄ›˘›sre›”›“Ś”¦§¨‚v{Ś—Ł‹‹„“““||llkd\\{ttsre|›”›ś››“““‹„„}{{kd\ldd„„›˘›||›”›“Ś”‰|vŠ}ś››|ddc\[[d\\[TT\UZ[[T}¤¤ť74,74,lddVTLb[U‹‹„uztdc\ddc{u{u{{dc\d\\tsl]bZddcredlritllsle|ekd™š¤|lekŞł·”“›lek„„Š˛˛¬ultu{{b[U¦§¨tlllri‹‹„{{tt{Ś”•‹‹„SKJUTS{u{{tt””‹’ŚŚtsllldtt{yl„ttsztltll|kk]\[[ddc„Š}¦§¨}ŠultttsŠ}|‚zj]\‚|uztlu{{tll|tts„„d\\fkk{tt“Ś”ult{||Ś‹“„„|“Ś”{zm|„…lksdc\Š}|Ś”•ztf{u{“Ś”“Ś”¦§¨tts‚utult[TTek]||ztl{ttkd\ztl„„”š”››”{tt{zm‚|uultldduztŚ”•{{|{{t‹„‹uztllk‹‹‹…„’ultf]c|„…nv‚fkk{||Ś—ŁŚŚš{{ŁśĄ“Ś”ś¤¦u{{Ś‹“Ś”•…‹‹|„…|„…|„…}Š”››tts„„Š™š¤‹„‹||{{Ś—Łmtt””‹„Š„™š¤”››™š¤dc\{{|{tt¤¤ť“““„„Šµ¶·ult¨©´ś››ŁśĄzlltllllk”“›ttsu{{‹‹‹”“›”››ekd”“›}tzl}lldtts…‹‹f]crfkŚ‹“\UZd\\\UZ‹…’|‚ztsl‹’Š‹„„uzt]cd|„…lks[[Tš””{u{‹„„„Š„¦§¨µ¶·”“›‹„„|uzt˛˛¬{tttts{||{tt‹‹„Š}¦§¨Ś‹“”››‹„„Ś”•”››„„Š›”›{u{bVU|”š”‰v{||™š¤“““‚|u”“›ult¦§¨ŠŠ}„Š„|‚z…‹‹ult”“›{||}kd\‚|u„„|„…Ś”•lrif]c|„…tt{˛««JHF3+*bVZllkj]\tll]cdlld]cdult{{tUTS“““[[TlriVTL‚|u„„Šlksd\\j]\ttsś¤¦‹‹„›˘›™š¤lddldd”››‹‹‹ldd…‹‹‚ut””‹“Ś”››”d\\uztttsedk‘Ś…lek„„“Ś”{u{|‚v{‹’Š|„…{{tslellkVZTlri|‚zz‚lddc™š¤ttstll|„…š””u{{‘Ś…sreb[U{ttŠ}sled\\tts„Š„{ttldd\[b››”ldd{zmtt{„vŚ™š¤tzl‹„‹f]cdc\lri‚|ukk]{yfd\\llkf]c{{tŠ}‹’Štlltll{u{‹‹„…‹‹‘Ś…””‹‚utj]\zll|„…‹’Šsle{{t””‹›”›‚v{ś››{{„„‹„„tsl„Š„‹‹‹‹„„”š”{{„„“Ś”¨©´Ś”•Ś—ŁŚ‹“‹„‹”“›‹‹‹¨©´™š¤Şł·”“›ŚŚš|„…ś¤¦|„…Ś‹“|‚zŚ—Ł¦§¨…‹‹ŁśĄ™š¤||ś››„„Šlks™š¤››”„Š„ś§˛{||red}Š‹„‹„„‹‹‹{tt”››‹‹‹ultŚ‹“··Ä|ldd‹„„Ś‹“tt{sleuzt‹„‹|fkk}…‹‹}lld{||{{‹’Š…‹‹„„{u{MSSf]cUTS”“›f]cmtt{{|™š¤Ś”•‹‹‹u{{edkedktsl||}“Ś”””‹ŠŠ}‚wl“““›”›{||”š”‹„„‹‹„„Š„ult}bVU[[T}tts]bZŚ‹“„„Š}|{||“Ś”‚v{{tt¦§¨«˛«‹’Štsl¨©´…‹‹“Ś”Ś”•Ś‹“{tt[[Ttsl‹‹‹„„ŠŠ}|sle‰v||ultuztŚ”•uzt|tllUUYddc\[[Ł››:97&&red{zmJHFVTLMRK‚u\[[[TTVTLJHFVTLtslsle[TTllddc\””‹i\Vtsltts“““„„lriś¤¦Ł››\[bddc||ultś››{tt||“““|Š}™š¤{{lksSKJedk{{}Šlld‹‹‹sle„„]cd‹’ŠbVZUTSVTLdkVfkkFD;„Š„aWM]bZVTLSKJ||uzt‹„„lri’ŚŚldd’ŚŚ“Ś”ldd}tts{ttddctll||redf]cŠ}zlld\\tzl„„{ttuztdkVVTLŠŠ}JHFredf]cult{||tll“Ś”{u{’…‹lek„„{tt{||‚|u‹„„tll||ldd|‚zŠ}tts‚ut{ttf]c‚|u‹’Š››”{|||‚zŠ}||„…‚v{™š¤…„’‹…’…„’}‡’lks{u{ŚŚš™š¤™š¤|„…Ś‹“›ť˛¦§¨…„’tt{ś¤¦}‡’Şł·…‹’‹„‹{||ś¤¦›ť˛›ť˛ś¤¦›˘›¨©´Ś”•Ś”•Ł››«˛«…‹‹‹‹‹‹…š{{‚v{‹‹‹ult«˛«ś¤¦™š¤“Ś”|¨©´ŁśĄrfk”“›ŁśĄ„„Š}Š„„Š…‹’‚|u{||{{}{tt{{››”ŁśĄ›˘›ś¤¦”››¨©´|„…|‚zd\\“““{{]bZ}lld}ś¤¦|{{JHFult”š”‹‹‹tt{…„’‹„‹””‹tzl{||{tt¦§¨”š”’…‹|„„ŠŚ”•“Ś”|„…lldldd|„…›”›||Ś”•|‚z„„Š‹„‹™š¤š””sre|{yff]c‹’ŠŚ”•|„…}{{‹„„lriVTLek]}‹„‹llkcbVldd[[Ttlledk\[buztztl[TTUTSedk””‹:97&&\[[SKJVTLz‚lVZTek]FD;ultd\\|‚z‹‹‹lldsre’ŚŚsle…‹‹kd\jcV‹’Š|llk‹’Šlld\[[„Š}uzt„„„Š„“Ś””š”‹…’‹…’Şł·Ł››{tttsl{||›”›tllf]ctlllldŚ”•Ś‹“‚ut”š””››\[[ultSKJ{{{zm[[TVZTlddJHFu{{lddVTLtlllldd\\tsltsl‚v{‹’Šztllrillkttsj]\lriUTSb[UlddŠ}ldd}ultzllf]ckd\lritzluzt››”‚wllddtts|‚utreddc\‚uttts{{“““Ś”•‹’Š||Š}‚wl{{t{{tddctlllriŠŠ}redddc{{tztltsluzt|„…‹„‹”š”u{{„Š„}Š„Š„’ŚŚ…„’{{{{‹…’™š¤u{{ŚŚš{{”››…‹’Ś—Ł{{{{Ś”•…‹’“Ś”Ś”•¨©´™š¤…‹‹Ś”•™š¤Ł››‹‹‹™š¤edkś¤¦›˘›¦§¨™š¤”››‹„„›”›”››ś›››˘›¦§¨‰‘~ŚŚšŁśĄµ¶·¨©´‹„„¦§¨¦§¨™š¤‹…’„Š„|„…||“Ś”tt{Ś‹“‘Ś…“Ś”Ś”•‹‹„‹…’”››lrimttŚ”•‹’Šekd{u{rfklks\[buzt’ŚŚ“Ś”u{{Ś”•…‹‹f]c[TT„Š}“Ś”ult”“›ś¤¦‹’Š‹’Š‘…„{|||‚ztts“Ś”ult‹’Š“Ś”}‹„‹|‚zb[UttsŁśĄ‹„„{||{tt‹‹‹}}”“›‚|u|‚z„Š„Ś”•‹„‹«˛«“Ś”ldd\[[‚|u]bZkk]sleŠ}ldd{||„Š„{{t{tt››”‹‹‹|„…|‚ztlllek{||JHFŁ››JHF3+*edkek]lldb[Udc\lld\UZVTLVTL[TTlddlld{{ttllldd|Š}yle¤¤ť‹‹‹{||{{t„„Š|„…{u{‹’Š”“›„„‹„‹›˘›”››{u{{{šŤŚ›˘›fkkr]Z{{s_q‹…’rfklek™š¤lld”››‹‹„uzt‚v{‚uldd‹’Š|MRK]bZVZ[llklld‚utekd‹„„ddcztl]bZUMRztfdc\Š}JHF\[[f]c|Š}{||j]\tllkd\d\\…‹’||{ttttslks„„Š|ś¤¦Š}ŁśĄŠ}|lldllkultlddlld””‹{tt‚v{››”‹‹„“““rg]’…‹’ŚŚ{tt{ttlldf]c{{ttllllklddred|{{t›˘›¤¤ťś¤¦“““”š”””‹™š¤u{{…‹‹Ś”•…‹’„„Š…‹’™š¤ś¤¦Ś—Łmtt™š¤‹…’”“›{{lks›ť˛ś§˛ś§˛ś¤¦”››Łť˛{{{||lri‹‹„sre…‹’u{{…‹‹|„…|‚z|‚zŚ”•””‹‹…’ultś¤¦“““Şł·”››ŚŚštts“Ś”™š¤„Š}„„Š}‹„‹“Ś”Š}u{{ztl{{t”“›ttsj]\š””uzt‚|ubVZmttŚ”•VZ[|‚z…‹‹tts{{‚|uf]c‹…’”“›””‹ŚŚštllekdUTSlks†~‘[[T{{tlks{{t¦§¨””‹¦§¨’ŚŚtll|Ł››‘…„ldd„Š„tt{Ś”•‹‹‹Łť˛‹„‹}›”›ult…‹‹“Ś”edk›”›tt{{{t‚|u|„Š„|„…‹„„{||lldlksultb[Ulld{{t[[Trfkult’…‹|lld””‹”š”„Š„‹‹‹ekd‹‹„[TTtslddc˛˛¬FD;*)(ultddcSKJD;9JHFcbVf]cSKJ[TTldd\[[tslŚ”•[[Trfk„Š„Š}|lld{zm‹’Šuzt{{tlri„Š„„„’ŚŚŚ‹“„Š„{tt’ŚŚ\[[‹„„{{f]c«˛«„Š„…‹‹{||Š}„„‹‹‹ultŠ}bVZ„„ŠbVU…‹’š””””‹{{t›˘›Žˇ›ult]bZultldd[[Tlddlld“““[TT‚|ub[Ulld‚|u{ttek]ddcddcVTLSKJFD;kk]ult{{tddcuztVTLtllbVZ{||[TTtslldd¦§¨lritllŠ}|„„{{t||bVUttsredredzll‹‹‹{{t|‚z{{tztl|„…|‚z‚utś¤¦kd\…‹‹ztl‹„‹edk|‚z…‹‹lld‹„„‹„‹‹„„”››Ś‹“uzt|„…{{Ś”•}‡’¨©´ś¤¦™š¤›ť˛ś¤¦™š¤}Š‹„‹„†™}|’{{{{Ś—Łś¤¦|„……‹šf]ctt{ultŚ”•…‹’‹‹„‹’Š„„Š{||¨©´«˛«‹’Š…‹‹mttŠ~‹…„’{{Š}””‹ś¤¦|„…Ś‹““Ś”‹„„Ś”•„Š}||„Š„…‹’{tt‹’Š{{Ś‹“d\\{||f]c‚v{r]g{{‚wl{|||‚z]cd|‚z|‚z„Š„{{|‚z{||f]c™š¤tsl||„…lld‹‹„†~‘‹’ŠŁśĄ„Š„||{{lld…‹‹‹„‹‹‹„||“““Š}||Ś‹“tsl‹‹‹™š¤ldd„„Š’ŚŚrfk“Ś”}ldd…‹‹{u{|„…›”›„„tt{||«˛«lri}Š™š¤Ś”•{||{||Ś‹“d\\kd\tsl\UZlddultu{{uzt|‚z’…‹’…‹‹’Š„„‹’ŠŠ}|f]cVZT\UZ¦§¨UMRlddVTLFD;FD;‹‹„[[T‚ut[TTfkk}[TT[[T‹‹„lek[[T„„ztfVTLcbVdc\‹‹„tslfkk“““|‚zmttek]’…‹||tzl“““{{tttsś››¤¤ť’…‹tt{ddc‹‹„}š””’…‹‹„„Ś”•¦§¨VTL\UZ””‹”š”|„…‹‹‹”š”Şł·lriedkdc\|‚zztlttstllekd‹„„SKJ‹‹„ttskk]|uztlldSKJ‚|utsltlld\\f]ckjV|SKJb[Uztluztulttsl‘Ś…‹’Š|‚zsle{tt‹‹‹‹‹„Š}lks[[Tkd\red‹„„|kk]u{{‘Ś…lddllk{{sledc\f]c„„š””Š}ult”››‹’Štllztl||llk{||{{„„}Šmtt™š¤}|’{{ŚŚš™š¤‹…’nv‚ŽŁ}‡’ult{{™š¤›ť˛}|’{{}‡’Ś”•|„…Ś‹“Ś‹“™š¤|„…ŚŚš¦§¨”š”…‹‹Ś—Ł”š”|„…tzl|„…Ś”•|‚zult||‹’Š””‹“Ś”„Š„¦§¨lks{tt…‹‹„Š„{||›”›Ś‹““Ś”o€w|„…{ttsle|„…‹’Š‹‹‹ult¦§¨‹’Šredekd…‹‹ś¤¦|‚z]cd|„…mtttslmttedkŚ‹“‹‹„uztcbV\[[››”ś§˛|„…™š¤‹„„||f]cŠ}|ś››ś¤¦š””‚v{š””[TT{{””‹”››Ś”•tllŠ}{{d\\}Š}{{t{||ddcddc…‹’“Ś”rfktsluztddcult¦§¨llk‹‹‹”š””“›‹‹‹dc\››”‚|uUMR}tsl{||tsld\\ttsddcu{{{u{{ttlekVZTddc˛««D;9*)(dc\VTLFD;D;9ek]kk]bVUult{{tlksd\\lrilriVTLlks‚|uj]\cbVlldVZTuztMRK„„u{{{ttŚ”•lriś¤¦u{{‚u{tt“““‹‹‹mtt˛˛¬tts|mttf]c™š¤tsl‹„„ult„Š„Ś”•ŠŠ}”“›|ulttts]bZ„„Š„„{ttultztl{{tztl]bZ“Ś”{zmlri\UZ„Š}{u{Š}|d\\uzt}Š|Š}|sreś››‘}f]c‚v‚{{tlddSKJ‹„„ddc‚v‚ek]VTL[TTdc\llkddc\[b„„||”š”tsllldredUTSlldkd\„„redVTL{||[[TFD;llklddtsltsl{{f]cfkktsl‹„‹||llkultlrifkk„„Šmtt|„…‹’Š|„…{{…„’Ś”•”“›ś§˛Źˇˇmk…}|’Ś—Ł{{lks{tt‹…š|„…¨©´Ś”•…‹‹”“›™š¤Ś—Ł¨©´‹„‹Ś”•‹„‹Ś‹“¦§¨|‚z‹‹‹lri|„…Ś‹“{u{}‡’’ŚŚ{{t||‚z™š¤]cdlks…‹‹Š}ś››{tt™š¤Ś‹“ŚŚš…‹‹lek››”…„’Şł·‹’Š¤¤ť{{{u{„„›˘›mtt™š¤{||VTL|‚z]bZtsl„„Šult‹’Šdc\‹‹„”š”™š¤™š¤|„…‹…’”š”’ŚŚ‚v‚{{ult¦§¨‹’Šś››{u{||tsllek¦§¨Š}„„“Ś”{u{{tt}„„Š{u{sle“Ś”‚v{f]c{{t}„„||lriztledk{{|„…››”™š¤“““¦§¨sle‘Ś…{u{d\\{||‹‹„mtttslultdc\|‚z{{kd\ldd\[[tt{\[[¦§¨SKJ&&j]\Š}f]cVTLJHF]bZzlltll]bZllklld››”tzlsleuztultVTLtll]bZ[[Tu{{tzl”š”llk|‚z‹’Š|‚zŚ”•{{td\\˛˛¬{||Ś”•ekd‹’Šlld{{f]cedkš””lldbVU“Ś”lddult[[Ttt{SKJ{ttlddu{{lriUTSdc\rfk|tsl{{ttslzll|‚z||{ttttslldddcMRKf]clkstsl‘Ś…ekd|‘…„{{ldddc\{u{FD;Q?@ult}Šdc\||‚z{{t†~‘„Š„mttlldultŠ}|‚z{zmf]cuztŠŠ}{||UTSylerfk{ttdc\sle{||VTLtzlbVUlddllkdc\ldd||ztfllkldd}u{{mtttt{uzt…‹’nv‚ŚŚšedklkstt{¨©´ś¤¦Ś”•›ť˛ś§˛“Ś”¨©´lks}‡’}‡’|„…u{{¦§¨„„ŠŁśĄ™š¤™š¤ŁśĄś››|„…|„…ś››ś››ś¤¦›˘›{{u{{ultyl„ttsµ¶·‹„‹Ś”•\[[lkstsl…‹‹llk‹‹‹lri…‹‹{{””‹{||›”›„Š„„„Š{{¦§¨“Ś”ŁśĄ„Š„ldd|‚zlks}mttlrirfk\UZd\\\[b‹’Š{{‹‹„››”tslmttlkslks„„{tt{tt|„…¦§¨’ŚŚ’ŚŚś¤¦Š}Ś‹“””‹||™š¤Ł››””‹{||’…‹{{ultult{{|‚z‹„„ś››|‚z™š¤{{t{{||””‹|‚z||{||ś››‹’Šś¤¦‹’Š}Š„„Š’ŚŚ{{tddc{tt{{kd\lri|lld{tt„„tts„„ztlfkk]cdllk””‹bVU-1+ldd{{tF=CsletllSKJ{zmzllldd\UZslelldddcd\\„„‹„„r]ZŠ}„Š}|„…JHF{zmfkku{{‹’Š„Š}lriuzt}|“““”š”tt{kd\{||VZTlksllk“““‹’Š›˘›[TT|uzt„Š„Š}›”›lddtlllriUUYVZTVZTUTS‹‹„‹‹‹{{tslettskd\„„VTLkd\tsl‹’Š…‹‹[[T\UZ‹’Š‰|vkd\|{{tsle||SKJ””‹f]csre{tt{{ult|rg]‹’Š„Š}lddtslbVUlri‹„„‚v{d\\UTSslekk]||”š”‹‹‹{{tŠ}|{ttttsek]{||ztlttslddjV[\[[\UZ{ttult‹‹‹|{{{||fkk“““Łť˛„„Š…‹’{{nv‚{||u{{{{„†™Ś—Łś¤¦}‡’Ś—Ł{{{{yl„{{…‹’Ś”•™š¤™š¤ttsŠ~‹ś§˛ŚŚšŞł·™š¤Ł››‹’Štzl›˘›lldŞł·Şł·lrimtt™š¤tll¦§¨ztlŚ‹“Ś”•}‹‹‹zll|‹‹‹“Ś”™š¤{{””‹”“›‹‹‹bVZ|„…‹‹„‹„„{tt{{[[Ttll…‹’|‚zŚŚš„Š„[[T„„„„Š‹‹„ttsŚ”•|‚z]cduzt{{t{{UMR|„…d\\{zm}‹„„…‹‹|‹„„„„sleldd‹„„”“››”›””‹¦§¨}“Ś”¦§¨{u{{u{…‹‹Ś”•””‹}„Š„|‚z‹‹‹”“›‹„„ddc{||„Š„{{ult‹’Š’ŚŚ|‚z“““kd\“““››”„„Šš””redŠ}|tzl“““sle[[T|‚z]bZb[U[TT\[[UTSf]c¦§¨FD;*)(f]c‚|uSKJ]bZlddJHFddclldddc\[[“~tzlekd{||ult“Ś”“Ś”tzlu{{Ś‹“llklldtt{ekd›˘›lkszlltt{uzt‚u‹’Š}|’””‹‹’ŠtsltllVTL{tt‹’Šztl…‹‹uztVTLlri‹‹„|‹‹‹‹„‹{tt]bZJHFb[U]cd]bZmtt{tt{zm‹‹‹[[Tlld{u{sreult{||]bZttslld[TTcbVVTLb[U””‹[TT{zmi\VbVZtll}sletlledkUMRek]kk]””‹VTLlddUTS“Ś”‹„‹‚utultkd\{||“Ś”cbV{tt|‚z‹‹‹””‹tllbVZuzttsl{|||lld‰vtsllksbVZ{||ulttll{{ultmttfkk„Š„™š¤‹‹‹“““Ś—Ł{{lksŽˇ›mtt‹…š…„’Ś”•…‹šŚ—Ł|„…„„Š…„’…‹š~’“ekdŚ”•}Š›”›ŚŚš…„’Ł››‹„‹™š¤›˘›“““›”›”š”||””‹Şł·Şł·‹‹‹{{‹’Š‹‹‹‘…„™š¤Ś”•{{š””¦§¨“Ś”››”ldd‹‹‹ŁśĄŚŚš{{™š¤Š}|‚zŚ”•ztl„„{u{{||’…‹{{Ś”•›”›‹’Š‚utf]c™š¤“Ś”„„lriUUYmttUTSdc\]cdtts{{ekdlek‹„‹lekŚ”•››”ttstzl‚wlŠ~‹›”›‹‹‹”“›lksś§˛|„…ŁśĄ{{tsl{{™š¤‹‹„¦§¨Š~‹‹‹„u{{‹‹„}}‹‹‹|‚|u{||tt{fkk„Š„Š}|ultlri{{t‚|u}„„}||””‹‘Ś…ztl„„tslVTL{ttultfkkUTS¦§¨MRK*)({tti\Vkd\FD;bVUPF=dc\UMRdc\sle„Š}tsl{u{ttstll›˘›jcV‚|utyg„„|u{{d\\mttekd„Š„}Š}|„…}Šuzt|„…|‚z””‹b[UddctllŠ}ŠŠ}\[[‹…’{zmj]\„Š„’ŚŚ‹„„[TT’ŚŚtlltts…‹‹Ś”•u{{lrillk›”›tllztld\\‚v{|„…ztlVTLttstzl{{{||„„Š[[Tb[U{{tŠŠ}\[[VTLJHFlddiq]d\\VTLlld]bZSKJJHF||||f]c„Š}}ddcd\\tll‚|u”“›“““lldŁ››‹’Š{u{’ŚŚŚ‹“|mtttsl{||Ś”•mtt|mwtts‹„‹[TTtll|‚z„Š„|ddcMSSlek™š¤Ś‹“lks|„…}‡’…„’|„…{{‹‹‹Ś”•Ś”•™š¤„„…‹’¨©´{{Ś—Łnv‚Ś”•…‹‹“““Łť˛”››ŚŚš””‹{u{{{¦§¨}‹„„‹‹‹|‚zś¤¦ś¤¦»ÂÇ‹„‹lks\[b›”›{tt„„ŠŚ”•Ś”•]bZ‹„‹‹„„””‹ult’ŚŚ„†™{{tś¤¦””‹Ś”•„Š}tts„„Šultś¤¦‹„„{||¦§¨”š”Şł·„„Š„„ŁśĄ{{{{tŚ‹“JHF\[[LKRMRKVTL\[bJHFu{{u{{redŁśĄŠ~‹|‚z“Ś”tts¦§¨›”›¨©´˛««”“›””‹”“›Ś”•Ś”•‰v||Şł·ttstt{…‹‹‹…’ultś››“““}“““™š¤||ekd…‹‹ddcedk‹„‹ldd{zmmttultdc\|llk‹„‹‹„‹‹„„{{››”‹„„sle‹’Šdc\„„{tt]bZ]bZVZTŁ››b[U*)(f]ckk]Š}|FD;UMR{tt[[TVTLSKJVTLj]\VTL{u{||tlllldkk]ztl‹‹„‹‹‹”š”tslmtt\UZ„Š„Ś”•{u{‹‹‹™š¤{{«˛«›˘›{||‹‹„{{t„„‚utekdbVZUMR™š¤‹‹„{u{{||‚|u‹‹„lek‘Ś…””‹{{uzt{{tekdJHFUMRldd|‚z‰|vf]c‹‹„{||ztl{ttVZ[‰‘~”››{{ttll{tt[[Tkd\}FD;VZTd\\lddb[UtlllldlddJHFultekd‚u””‹„„dc\tsl||dc\“Ś”¦§¨{{tkk]{tt|‘Ś…››”ultredtt{|‚ztsl‹‹„Ś‹“š””{{tzllLKRmtt}bVU{{lri“““uztmtt{{tt{}|’{||Ś”•{{|„……‹šŚ—Ł™š¤{{|„……‹’ś§˛·¶Ń¨©´”“›{{ś¤¦ś¤¦|„…}‡’“““¦§¨ś¤¦Ś‹“¦§¨‹‹‹¨©´Ł›››˘›Ś”•™š¤””‹‹‹‹|‚zfkkf]clksŚ—Łzll‹„‹‚v‚¬¶Ăš””lldred|||„„Šś››Ś‹“Ś”•Ś”•ś››Ś”•¦§¨lld|„…{tt”››‹’Š{u{„„Š„Š„{||uzt|‚z{tttt{JHF„„Š†~‘}ŠŚ”•…‹’zlluztlriVZTlrillkŠ}|llk„„Š{u{›”›‚|uztl}ult|™š¤¦§¨¦§¨‘Ś…”››™š¤”“›}Šf]clld}{{‹„„‹‹‹„Š„ldd|„…llktts…‹’ekdŁśĄ‚v‚tll‹„„||{ttleksletll‹„„‹„„||JHF{||zllkd\JHFUTSlek‚utfkk\[[ddc‘}JHFSKJbVZkk]b[UPF=3+*FD;[TTD;9JHFlddtsldc\{ttdc\‚ut{u{{|||¤¤ť|ttslddddcult[TT|„…™š¤“Ś”¬¶Ă¨©´ś¤¦Ś”•‰‘~iq]„Š„tllb[UddcUUYf]c{tt|‚zddc{u{dc\‚v{tslult„„rg]Ś”•|‚zekd[TTlks‘…„{||lek”“›||b[Uš””›”›[[TŚ”•UTS{ttrfksresle”››j]\ttsUUYuzttllVTLleksre‚ut‚wl\[b|“““ddcultlld‹‹„||\[[{{ŁśĄ””‹‹‹„‹„‹{{tš””{{tlksredultś››Ś”•Ł››{||tllmttrg]ttstt{{u{ult{u{””‹…‹‹{{…‹‹…‹‹Ś—ŁŚ”•u{{{{Ś”•Ś—ŁŚ‹“…‹šŚŚšŚ”•…‹šŚ”•™š¤Ś—Ł»ÂÇ”››™š¤ś¤¦…‹‹Ś”•‹„‹™š¤¦§¨š””™š¤¦§¨™š¤›˘››”›‹„‹tzlŚ”•”›››˘›Ś”•u{{yl„MSSuzt{{t”“›“““Ś”•„Š„}}‹’Š„Š}”“›™š¤tts™š¤”“››˘›|„…‹„‹|‚z\[b›”›u{{{{t“Ś”Ś—Ł|„…[TT„„Šmtt\[[{{UTSultŚ”•“Ś”™š¤|‚zlddllk{{Ś”•llk‚|u‚v{Ś”•ttstt{ultztl‚v{“Ś”„„›”›”››Şł·¦§¨‹…’›˘›„„|„…\UZ}Šrfk’ŚŚ‹„„ldd’ŚŚŚ”•„Š„‹„‹||”››llkmtt}„„Šmttu{{ultttsŚŚš‰|v{{‹„‹zllSKJd\\lriu{{ek]„Š„|‚zsleztl[TTVZTllk¦§¨:97*)(u{{SKJJHFSKJ3+*SKJD;9F=Cf]crfkVTL|{tt‹„‹“~ddcsrejcVlldlld”››edk[TT„„mtt„„‹u…‹„‹lri„„ek]lri”š”«˛«|„„ztl‹„„{tt}|u{{[TTd\\VTL{{tult››”‹„„Ś‹“u{{u{{ttsfkkUMRb[Ulld{tt\UZŠŠ}VTL’ŚŚ‚v{„Š„‹‹„ult||redlks”š”‹’Ši\V[[T‹’Štyg‹’Šlddult‚|u‚u„„f]c|‚ztlltslVZ[„Š„tzl[[T{u{ult‹„‹“““‚|u¦§¨|tts””‹ŁśĄŁśĄ”››””‹”››{{t{u{VTLlri“Ś”{u{“Ś”…‹‹›”›ddc’ŚŚultkd\u{{Ś”•™š¤ŚŚš‹‹‹…‹š…‹šmtt{{|„…„„Š|„…ŚŚš{{Ś”•™š¤ś§˛…‹‹‹‹‹|„…¨©´™š¤™š¤Ś‹“{{tŠ}†~‘“Ś”‹‹‹|„…’ŚŚŞł·š””ś¤¦ś¤¦‹‹‹‹’Š”››\[[tt{{||}Š|Ś”•‹’ŠŚ”•Ś”•ś››™š¤‹‹‹‹„‹ddc}Š›˘›}‡’™š¤Ś”•}„Š„‹’Š„„ŠUTSVTLb[UŚ”•lriuzttt{lri[TTultultult{{™š¤Ś”•tlllrilks|‚zlks“Ś”‚utf]c{{ultŠŠ}tts{||{ttŠ~‹||‚v{Ł››tzllkssreUTSddcnVZ[lksŚ‹“||ldd„„|||uzt„„›”›{{{u{Ś”•„„…„’”››„„}{||ś››‹’Š‹‹„‹‹‹sle[TT\[b]bZsletslVTLekdztl‹u…[TTu{{llk˛««UMR*)(\[[rg]bVUVTLVTLkd\tts|rfkŠ~‹„„tzl|||[TTtt{‹‹‹kd\VTL{{„Š„tsl‚|u„„f]c[[T{{”“›ttsmttek]{{tuztlriVTLlek‹„„ttssle‹„‹„„Šttsuztkk]r]Z“Ś”¦§¨Š}|kd\f]cJHFddcfkkf]cUMR{u{lldult[TT””‹[TTrfk{{td\\‹‹‹|™‹†ult¨©´”š”lks‚|u“““|„…tlllldkd\{u{|‚z‚ut‹‹„‹…štslb[Uddctsluzt”š”‚|u}Š‚v‚{{š””tllś››‹„„””‹tts“Ś”’ŚŚŞł·››”{||‹„„tts‚ut‹’Šzll}Š{{ldd{u{‹„‹‹‹‹}Šllk‚|u|„…Ś—Łś¤¦Ś”•™š¤}‡’{{{{}‡’|„…mtt…„’Ś”•}‡’™š¤„„”“›„„Š|„…Ś”•Ś”•Ś”•™š¤ddcŚ”•ttsŚ‹“ult¦§¨ś››‹…’‹‹‹|‚z””‹|”“›Ś”•ŁśĄ™š¤lkslks”››Ś”•‹’ŠŚ”•{{‹‹‹‹u…uzttll‹‹‹…„’Ś”•mtt\[b„„Šmttmtttt{ultlks‹’Š[TTuztVTLddc„„fkk{tt†~‘™š¤„„Šlddyl„{{ttslri{{‹‹‹|„…ś¤¦ztlš””ult|‚zŠ}|ŁśĄ”š”{{t{u{{u{‹‹„Ś”•tts{||lri„„tt{ddcu{{\UZ‹„‹tsl{ttŠŠ}ult}¨©´}{ttŚ”•{{tt{…‹‹llk{||ddcf]crfk||’ŚŚ››”Š}|tslbVUf]c‚|u\UZ{zm|tts[[Ttsld\\|„…{||¤¤ťMRK:97{ttdc\D;9SKJVTLVTLf]c\UZbVZ‚v{uzt{||slekd\ekdlkstzlŠ}uztlrifkk„„||tts||\[[ekdtll\[[\[[mtt‰v{ttVTLdc\rfklddtll‹„„{u{|„…tts|UTS{{t‚v{¤¤ťtllbVUVTL\[bttsult\[bllkŠ}{{ttllddc“““|UTS|‚zVTL|‚zultrfkult¦§¨„Š}¦§¨i\VŚ”•|„…{{ttt{‚utlriztllriu{{lddś¤¦lj|„…‹„‹„Š„{||{tt„„‹„‹{u{‹‹‹Š}„Š}lddŠ}{{t‹…’}„„‚|uttskd\tts‹„‹Ś”•‹‹‹}tts|‚z‹‹‹lks…‹‹{{|‚z|edklri|„…„Š„…‹’|„……„’ŚŚš}‡’ŚŚš|„…Ś—Ł|„…”››ś¤¦”“›¬¶Ă¦§¨…‹š¦§¨ś§˛ś§˛›”›µ¶·¦§¨Ś”•ś¤¦“Ś”™š¤}ŠŁśĄ’ŚŚ›˘›”š”ś››“““lri“““ultttsd\\{||„„Š‹’Šś¤¦¤¤ťf]c’ŚŚ|„…tt{¨©´}ś¤¦Ś”•u{{Ś”•…‹’ś¤¦lks|„…mttlld[TTekd|„…”››||{{“““‹’Š“““{{tekdŁ›››”›„„Š‹‹„…‹šek]ddckd\ult›”›{u{ttsldd›”›¦§¨|“Ś”tlllek|‚zuzt|„…sre‹„‹{u{[TTtslultult{{t|||‚z’ŚŚ“Ś”Ś”•}‹‹‹tt{lksmtt{{{{„„Šllk{{tts‹‹„ś››””‹tsl{{tŠ}rfkVTLtllVTL]bZ{||||tllf]c[[Tddc„„MSS*)(tslb[U[[TaWMJHFSKJuztVTL[TTultddcdc\{zmlld„„ŠŚ”•cbVUTScbVŠ}|\UZ{ttultš””ś¤¦„Š}u{{tll|„…tts„Š„ztl{{tdc\tt{{tt{{tekd““““Ś”Ś‹“\[[srekd\|‰|v’ŚŚšŤŚ{u{r]g|‚zddc„„Šlks‹„‹‹„„lldyl„d\\tts„Š„tlltll[[T[[TŠ}|{ttlri|‚zVTLrfk‘Ś…tllŚ‹“sreldd{ttUTSkd\…‹‹UTS]bZ›˘›’ŚŚu{{‹„‹uzttlllld{{sle\[[|„Š„‹’Šuzt””‹”š”‹‹‹f]c|„…ttsddclekś››”››|„…‹„„{u{ttsttskd\edklldŚ‹“‹‹‹{||{{\[b|„……‹‹…‹’{{tt{Ś—ŁŚ”•ś¤¦›ť˛{{Ś”•{{Ś—ŁŚ—Ł™š¤lksś§˛…‹‹ŁśĄ›˘›Ś”•ś››„„Ś”•„Š„”“›Ś”•ś››}…‹‹Ś”•…‹‹¦§¨ś››™š¤“Ś”\UZ]cdldd|‚zŚ‹“|”š”tt{‹…’¦§¨||™š¤‹’Š›ť˛¦§¨lriedk\UZ‹‹‹ttsttsmtt]bZlri|u{{\[[›”›“Ś”|‚zkd\ldd‚u”š”||SKJtt{Ś”•u{{‹„‹“Ś”ult“““ŁśĄulttt{Ś”•|‹„„“““¦§¨¦§¨¤¤ťš””{|||„…ult]bZ}UUY]cdldd{{ś››{{t|‚z‹‹‹””‹‹…’”››„„Šlek…‹‹{{|„…lks|‚zuztulttt{tts}‚ut||dc\‚|urfk‚v{{||{tt|‚z]bZUTSsle[TTllkUTStt{Ł››LKRD;9lldkd\[TTVTLPF=VTLVTLf]cultf]cddc{{tdc\{u{kd\‹’Šlrilldtslkd\VZTred“Ś”{u{«˛«uztu{{|lddŚ”•ldd{tt…‹‹]bZMSSlddkd\‹‹„|{u{…‹’lks|‚zdc\Š}lddŠ}‹„‹Š}lriUUY|‚z{{:97lksult|‚zult„„››”{{td\\mtt{{tllk“Ś”rfk[[Tdc\Š}|‹„„Š}|‹‹‹{||„„‹‹„‚u{{tsle|„…|„…lek›˘›”š”””‹ś¤¦¦§¨||Ś”•}tll{{t|‚z‚|u‹‹‹{{tlld|‚zuztlddŚ‹“„Š}‹‹„‹„„¨©´’ŚŚŚ”•‹‹„lks|„…]bZUTS{u{{||tts„„{||mtt\[b|„……‹’…‹‹|„……‹’Ś—ŁŚ—Ł™š¤¬¶Ă™š¤|„…~’“„†™|„…{u{{{Ś—Ł”››¨©´|„…™š¤Ś”•™š¤¨©´|„…™š¤u{{‹…’’ŚŚekd|„…ś¤¦‹‹‹tllmttd\\lksŚ”•‹‹„Łť˛rfk„Š„Ś”•„„‹„„“Ś”„„ś¤¦}…‹‹Ś”•{{rfku{{llkekdldd‹‹‹¦§¨””‹ztltt{ekd„„Š{{tŠ}|tll|‚z|‚zmttrfk||„…fkk{||ddcultult‹‹‹™š¤rfk™š¤{{Š}„„”š”””‹“Ś”„Š„Ś”•ś››‹’ŠŚ‹“„„”“›{{}Š[[T…‹’‹„„{u{‚u{||””‹edktzlult{tt|„…{{tts{{u{{|„…‹’Š“Ś”lldŠ}|{{tddc‚|uJHFJHFlddttsult‹‹„{{tlritsl[TTllkdc\ddc””‹FD;:97UTS]bZd\\VTLSKJrg]lriyle{{tekdlrilldkk]]bZ‹„„edktsl””‹uzt{||edkŠ}{u{|{tttslŚ”•|lld…‹‹‹‹‹{tt|mtt{{t{||[[T››”tts‹‹‹\[[Ś”•|‚zŁ››‹’Š“““š”””››{{ś››\[[”“›ekdUTSf]cUTS”š”|„…‚v‚[[Tlks{ttlks[[T}ŠSKJr]gSKJUMRkd\ŠŠ}b[Uultekdllk”š”aWMŠ}||›˘›…‹‹{{Š}¨©´ś¤¦¦§¨‹’Šś››“Ś”{u{zll‹„„uzt}|‚zldd‹‹„tsl“““lddlek||‹‹‹{ttuzt||uzt„„llktt{|‚z{{”“›„„…‹’{{t‹„‹mtt|„…ś§˛”››ś§˛Ś”•lks|„…ś§˛™š¤··ÄŞł·…„’{{Ś”•…‹’{{{{‰Šˇtts“Ś”{{Š~‹…‹’¦§¨Ś”•··Ä‹‹„\[[”“›tllf]cekd|„…››”|„…™š¤‹…’}Šu{{tt{{u{{{tts{u{lritts“Ś”tt{mtt{{mtt‹‹„™š¤lekrfk“““u{{\[[|ŚŚšztl‹’Šdc\lldkd\|lldu{{‹‹„d\\||“Ś”ult{{Ś”•tllF=CŠ}‹…’’…‹‘}zŠ~‹}{tt‹‹‹‘Ś…|Š}ś››„Š„{{llk|‚zŚ‹“uzt{u{‹„‹ś¤¦‹‹„|„……‹‹‹„‹mtt…‹‹|„…”“›”››}Šllk{{Ś‹“ś¤¦”››™š¤…‹’…‹‹|”››’ŚŚ“““rg]VTLFD;[TTUTSekdlddztlllkllkdc\[[TUMRztlUTS””‹:97:97sreb[UlddSKJsreD;9lddSKJldd{||lld‹‹„srezllf]cŚ”•sle‚ut‚uultlld{tt‹„„””‹||]bZlri||tsl|„…Ś”•’ŚŚ‚ut‹’Š[[T[[T[[Ttsltsl™š¤Ś”•‹’Šś››{{tldd}ttsttsŠ~‹uzt|„…‹‹„MSS\[[[TT‹„‹]bZ[TTi\V|{u{{{t„„||{ttsrej]\leklddcbV‹’Šrg]{{t{tttll„„tyg‚|uttslld„„mttdc\UTS‹‹‹›˘›˛˛¬‘Ś…ŁśĄś¤¦‹„‹‹’Š‹’Š””‹“““f]c‚ut|‚z„„{tt‚|u„„Š“““{||{||ddc„„ultedk{{|‚zlksŚŚš‹‹‹ś››|„…}‡’ś¤¦|„…™š¤|„…|„…Ś”•…„’ś§˛^fs…„’·¶Ń…‹’Ś‹“ś§˛”“›„Š„„„{{{{Ś”•”››{{Ś”•›˘›™š¤Ł››¨©´|ultŠ}“Ś”™š¤tsllks…‹’”š”‹’ŠŚŚš„„Šu{{mttmttlksŚ”•Ś‹“ddc{||}mttlks…‹’™š¤Ś”•‹‹‹lrimttŠ}|lritsl‹‹„lri|‹„‹”“›Ś”•{{t›”›“““„„„„sre¦§¨{{tred„Š„lld]bZ\[bUMR{{{{red‚v{“Ś”™š¤Š}{u{‘Ś…||‹„‹uzt‹‹‹™š¤tsl|„…]bZŚ‹“||…‹‹tll¨©´‹’Š™š¤tt{‹’Šmtt‚v{uzt„„}›˘›lks„„mttuztekd…‹‹llk‹‹„tlltzlek][[Tlldsletts„Š„‚v{|ddcekdtslztlultdc\,55||FD;74,{{tlrif]c{zmlriFD;\[[VTL{||‹„‹|‚zsle|‚zttsjV[tslrg]tslslej]\sle||lekllk{{ttzl“““llddc\|„…{||“““ek]”››b[U{ttlri‰vlri\[[¦§¨Ś”•ekd…‹‹uzt‚|u‹‹„tt{{{„„lri|„…kd\UTS\UZdc\[TTlldbVU{{t\[[„„ŠlldVZTultyle‹„„}„„ŠcbVkk]lri{zm‹„„zll[TTsreztlf]c]bZ|„…UTSlri„Š„]bZ‹„„‹‹„ztl{||«˛«“Ś”““““““‹’Štsl||‹‹„d\\‹‹‹{ttmtt{u{””‹’…‹tt{‹‹‹ś››‹„‹}Š]cdtts{{lks||}{tt™š¤‰Šˇ…‹‹Ś”•}‡’|„…}‡’Ś—Ł{{|„…Ś”•}‡’¨©´™š¤Ś—Ł›ť˛‹‹‹‹„‹}Š…‹š­Ŕ¶ś¤¦™š¤Ś‹“™š¤µ¶·{{›”›|‚zŚŚš“Ś”ult”š”mtttts“““uzt„Š„}‡’edk|‚zmttUTS\[b]bZŚ”•dc\tsl{{nv‚]cdŚ—Ł“““…‹’‹„„d\\\[[|‚z“““‹‹„„„Š{u{tllj]\”“›|„…Ł››ldddc\|„…mtt|‚z}‚v{ŁśĄlks™š¤Š}‚v‚{{‚wltt{‹‹‹yl„“Ś”‚v{ŠŠ}‚utŠ}„„ś¤¦‹’Š„Š„™š¤Ś”•™š¤””‹llktll…„’ulttt{‹‹„…‹’“~tzlŠ}™š¤„Š„|„…}Šnv‚ś§˛„Š„“Ś”ddcmttlksd\\lrilddd\\ekd{tt{{t‹„„ddc{||Š}{tttzltts{zmj]\\UZUTSUTS””‹JHF74,lridkVSKJVTLJHFbVZVTLbVUtllŚ‹“u{{d\\srelksztl„„kk]tslztlddclri{tt||””‹‹‹‹”š”Ś‹“ztlfkk{||tzl}]bZmtt{u{llk|‚z‹’ŠFD;MSSlriś››lri]bZ{{tll‹„‹”››lkslddllk„„ddctll\[bultuzt\[b}tslŠ}‹’Šlks]bZ„„ŠUMR„„||„„b[U„„ultŁ››rg]LKR{ttkk]UTSlddVTL[TTUMR‹„‹lriś››ś››‚u{u{”“›lld‹„‹Ś”•„Š„‹’Š‘Ś…{||{tt‹„„Şł·š””™š¤|‘Ś…‹„„kd\tzl…‹‹„„…„’\[bek]tt{“Ś”Ś‹“{{u{{™š¤|„…ŚŚšmttŚ—Ł…‹’¬¶Ă™š¤Ś—ŁŚ—ŁŚ”•…‹‹™š¤}ŠŚ—Ł”“›Şł·”››}™š¤™š¤™š¤Ś‹“Ś‹“Şł·“Ś”“Ś”{{|‚zŁśĄ‹…’ulttt{tt{Ś”•„„‹„„UTSultlksu{{}‡’|„…lksekd]bZ]bZtsl}””‹|„…mk…Ś”•”“›”“›\[b\[[kk]|‚zultztl‘…„tlllri|‚zddcultttsek]]cdMRK‹‹‹}ŠUMR‚v{ś¤¦Ś”•‹‹‹Š~‹{{‹„‹ult””‹Łť˛‚v{llk‹„„ŁśĄš””ś››„„Š¦§¨‹‹‹¦§¨Ś”•Ś”•Ś”•|‚zmttmttf]c|„…ek]\[bultllkttsŁśĄ‹‹‹|„…{{…‹‹}‡’„„Ś”•{{lksVZTJHF{ttultUTSu{{tlllld{{tedkŚ‹“||sletsl{||kk]SKJSKJaWM|„…š””ekd*)(kd\kk]bVUVTL:97D;9\UZbVU‹„„llk]bZtsl„Š}f]ckd\mttcbV‹„‹ldd\[[‹’Šztlztllldmtt’ŚŚŚ”•‹‹„cbV|dc\„„Šb[Ulld‹‹„‹„„|„…]bZ]cdekdJHFu{{MRKVZ[llkkd\edk{||{{Ś”•|„…„Š„lddldd{{lks|‚zllk‘Ś…tslztl‚utUMRjcV„„j]\lddbVZ{|||‚z‹‹„‹‹‹››”‚|uf]crfkrg]\[[ldddc\{||mtt”“›|‚z{{t‹„„[TT\[[\[btsltts|||{||”š”lek|‹„„™š¤red¦§¨‹„„lldŁ››mttu{{uzt{u{{{lkstsl}Š{{”››u{{{{fkkmttu{{|„…mttmtt}‡’†~‘ś§˛Ś—Ł›ť˛{||“Ś”†~‘†~‘‹’Š”››µ¶·{u{|„…nv‚{u{|„…“““{|||„…¨©´š””u{{˛¬µŁśĄ›”›|„…Ś”•ttsult{u{mtt}|’mttfkkŚ”•|„…mtt|‚z|„…Ś”•“““ult”››ś¤¦mtt…‹‹„„ŠŚŚšleklldllk{||VTLŠ}UTS[TTlldVTL{||‚utJHFtllJHFtslkd\¦§¨lks¦§¨›˘›tsl‚u}ŠJHFleksleŚ”•™š¤}ŠŚŚš“Ś”’…‹‹„‹‘Ś…“““”š”‹„‹Ś”•¨©´ttsuztŚ”•lri\[blksu{{tsl\[b}f]c||Š~‹tt{{||ŽŁ|„…”“›tts{tt{||mtt|„…uztlldf]clri‹’Šlld{{tztl]cd\[[redVTL[[T|‚zrg]FD;[[Tdc\SKJ””‹:97*)(UTSVTLaWMVTLSKJJHFf]ckk]‹„‹‹„‹llkSKJlrikd\zllrfkd\\lrilriVTL}Šyle‚|ubVUmtt{zmŚ”•{{tkd\tts{{t{tt||‚z||ldd‹’Š‹‹‹„Š„lrilksekdmtttzlult||{{lri‹„‹mtt›”›…‹’„„‹‹‹}tt{|‚z„Š„redrg]››”lrifkk{{t„„Šlddsle‚|utsllriŚ”•Š}|„„Š}|D;9||…‹‹lldulttt{[[TŚ‹“lddttslrid\\b[UJHFd\\lldtt{„„“““„„„„”››{tt”“›uztkd\{{f]ctsl”“›{{t{u{{ttult{{mtt||{{tt{]bZ]cd{{mttmttŚ”•mtt{{nv‚…‹’…„’ś§˛™š¤™š¤™š¤mtt{{Ś—Ł|„…”››¨©´lks„„{{”“›“Ś”¨©´„„Š”“›ś¤¦}lrif]c‹„‹{u{[TT¨©´edklekuzt…‹‹lks]bZlrimttmttmtt~’“‹’ŠŚ”•Ś‹“u{{„„Šmtt„„ŠŚŚš{{{u{„„Š||‚z‹’Štllkk]lddb[U||”š”{{tultlekdc\MRKllkrfkf]c’ŚŚ‹’Š“““‹‹‹ś››’ŚŚf]cUMRtll{{”“›™š¤¦§¨„Š„||‹„„Ś”•‹„„‹‹„‘…„¨©´”“›ultuztŚ”•||””‹}mtt‹’ŠlksVTL\[[u{{tslultttsult{{{{edk}mttVZ[„„Štts‹‹‹™š¤{{uzt\[[tlltsl\[btts[TTztlVZTkd\VTLb[UyleUTS[TTµ¶·JHF>ECSKJVTLJHF74,[TTrfkŠ}b[U}f]cllklld{||UMR\[[VZTi\V]bZlriekdVTL””‹|‚ztll|‚z‹’Šfkk‹‹„tzl‹‹„‹’Š¦§¨””‹fkk[[Trg]ekd{{™š¤tll…‹’‹’Š¦§¨„„||{u{g\rUTSedkkd\u{{Ś”•Ś”•‹‹„mttŚ‹“‹’ŠmttSKJult|‚z{u{Ł››ddcd\\{u{lddsleldd|‚z]cdred|„…cbVd\\f]c”“›Ś”•š””„Š„|‚zmttd\\\[[„„‚utttsu{{uztuzt“Ś”‹‹„‹’Š¦§¨”š”Ś”•””‹Ś‹“„„Ś‹“ttsult|‚z{{t„„Š|||lri}mtt|‚z“Ś”lkskd\{{‹„‹¨©´Ś”•Ś—Ł¬¶Ă…‹’|„…{{ś§˛Ś—Łlks…„’„Š„™š¤¦§¨Ś”•|„…™š¤”“›}Š‹…’{{ś§˛™š¤”“›‹’Š{{uztš””“““™š¤”“›Ł››tsl|„…Ś‹“llktt{„„Š|‚z[[Tmttu{{|„…Ś—Ł|„…Ś”•|„…‹‹„”“›…‹’Ś”•u{{lek|„…lkslrimttu{{lld‹„‹|‚z¨©´„Š}lrib[Uekdr]g\[[VTLf]cŠ}{||f]cmttult“““|{u{f]c™š¤Ś‹“||tyg{tt’…‹„Š}”š”lekrfk“Ś”’ŚŚś››¦§¨{tt}„„Š|‚zŚ”•„Š„¨©´“““|‚z„Š„”››{||llkllk{u{”“›tts{{{{lksŚ”•ttstllŚ”•}‡’uzt{{’ŚŚ…‹‹\[[d\\ek]d\\edkllklddtsllri[[TVTLb[Uultlddu{{¦§¨UMR*)(aWMVTLd\\VTL[[TD;9[TTb[U{u{]bZ{{tttsztlSKJlld’ŚŚ||tsltsluztddc‚|u{zm‹‹‹ekdkd\ddc‹‹„\[[lldtts‹„„tygŚ”•b[UŠŠ}sle\[[|‚z”“›™š¤…‹‹¸Áąlri››”Ś‹“|„…uzt]cdlri{{|‚z]bZf]c{{lrimttŚ‹“b[Ud\\\[[||lldlld{{lldtslsleekd|‚zldddc\tslj]\VTL‚v{u{{„„‘Ś……‹‹MRKVZT|uztsreŠ}„„|‚z¦§¨‹’ŠŚ‹“‹„„¦§¨Ś”•„„|‚z””‹ŁśĄ{||||{{t‹„„tsl|ś››{{››”‹…’ultmttVZTtt{{{|„…™š¤}Š…‹‹}‡’™š¤Ś”•}‡’ś¤¦Ś—Ł‹…š}‡’†~‘|„…lri‹‹‹Ś—Ł¨©´‹‹‹ś§˛|‚z“Ś”Ś”•ŚŚš}Š„„Ś‹“¤¤ť‹‹‹Şł·™š¤ultult|„…‹…’{{‹…’…‹‹‹„‹Ś”•lldu{{uzttsl}‡’|„…ś››™š¤ś¤¦nv‚Ś”•‹‹‹ś¤¦ś¤¦{{„„Šmtt{u{„Š„ttsekd„„Š}ldd„„Š“““””‹‹‹„ddckd\Ś”•uzt{{SKJttsUMRdc\D;9{ttMRKsle{{}Š{{tll{{t}™š¤”š”lrid\\kd\„„{tt|ś››…‹‹}Š}‹„‹{{t“““¨©´™š¤{u{Şł·}Š|u{{mttu{{tll…‹‹lks|„…ŚŚš{{f]c{||{tt{{{{lrilks„„tsl{ttlld{{tmttultkd\rfk{{]bZkk]tllVTLUTS]bZ˛˛¬]bZ:97Š}VTLtzli\VJHFi\VUMRVTL‹…’\[[\[[mttn‰v|uzttll“Ś”Š}|bVU„Š„‹‹„¤¤ťultlld]bZedk|„…sre{ttkd\bVUf]cŠ}ś¤¦”š”|‚z[TTtll‹„„ś¤¦‹’Š[[Tllkd\\||}ś¤¦”š”u{{edk„Š„‹’ŠVTL\[b\[bVTLdc\{||||ztlttsred]bZek]cbV…‹’››”’ŚŚllk]cdedkd\\lld]bZkk]tslUTS[[Tedk{||lriddcu{{mttsrei\V„„„„ŠŚ‹“Ś‹“”››˛˛¬¦§¨{||uzt„„Š{||{{{{‹‹„‹’ŠŚ‹“UTS||‹‹‹|„…|„…ttstt{tt{ś››…‹’}tllŚ—Ł|„…u{{}‡’{{™š¤ś§˛Ś—ŁŚ—Ł¨©´¬¶Ăś§˛…‹š‹„„mtt“Ś”Ś”•‹‹‹ś§˛]cdś¤¦‹…’|„…Š~‹‹‹‹{||™š¤„Š„™š¤µ¶·™š¤™š¤™š¤„„Šś¤¦™š¤…‹š‹…’‹’Š”“›ŚŚšlriŞł·]cdu{{]cd…‹š~’“|„…‹‹„„Š„u{{mtt}…„’mtt{u{“““cbV]cdf]cSKJtts‹’Š‹’Štllztlddc„„ttsekdlrilksSKJ]cd|„…[TTlriddc[[T{u{lksyl„‹‹‹Ś”•Ś”•tts“““„„‹„„zll‹„‹“Ś”›˘›{||””‹|‚z™š¤¦§¨„Š„tslś¤¦›˘›{{‹‹‹{{„Š„|„…‹„„ŚŚš{tt…‹‹}‡’“Ś”tt{ŚŚš‹‹‹›”›lri|„…]bZmtttt{tll„„ddcuztbVU\[[…‹‹tsl|‚z‹‹‹srecbVyfdlddred[[T¦§¨JHF*)(kd\VTLek]VTLMRKD;9{{t[TTlddJHFVTL\[[tt{{u{{||zll‹‹„Š}›”›”››ekd‹’Š|“““””‹tts}tsllekkd\VZT\[[{ttSKJ{{tzll’ŚŚ‚|u|‚ztsltlluzt{tt„Š}‚u||Ś”•””‹Ś”•\[bcbVn…fkkbVZSKJz‚l„„Šttstllkd\Š}VTL|‚z„„lek[TTtsld\\]bZ‹’Š¨©´ult¤¤ť”“›[TT„„ŠUMRultrfklri]bZUMR|„…lriVZT{tt‹‹‹‹‹‹{{|‚z™š¤›˘›‘Ś…Ś‹“|‚ztsl’ŚŚult…‹‹||[[Tfkkuzt}Štts„Š„‹„„„„{||Ś‹“”š”Ś‹“’ŚŚ‹‹‹…‹’{{mtt{{Ś‹“nv‚Ś”•…‹’…‹šś§˛|„…›ť˛{{“““™š¤¦§¨u{{f]cŚ—Ł‹‹‹{u{”“›…‹‹ŁśĄ‹„„}Š‹„‹™š¤uzt™š¤edkŚ”•™š¤ś¤¦¦§¨…„’ś¤¦µ¶·Ś”•’ŚŚ…‹‹]cd|‚zVZ[mtt]cdś§˛‹’ŠŚ”•ddcuztŚ”•fkklksŚ”•Ś”•lksUTSSKJtsl‹’Š{{t]cd{{tuztŚ‹“’…‹|‚z’ŚŚŚ‹“Ś”•tts||fkktt{lrif]ctts„„[TT[[TVTL{u{ttsmttś¤¦Ś”•”š”tzl{tt||‹„„Š}”››„Š„‹‹‹Ś”•‹‹‹¦§¨“““‹’Š™š¤„Š„‹‹‹‹„‹‹„„™š¤Ś”•‹„‹{u{{u{{||u{{{{lkslksttsf]c]cdlks|„…\[b|„…ttstsl{tt|tll{||uztlld|‚z[[TVTLJHFlld[[T]bZult˛˛¬UTS*)(dc\[[TJHFaWMD;9D;9jV[FD;JHF\[[b[Uf]cult‹‹„d\\lek}tt{ultiq][[TŠŠ}z‚lŚ”•|ek]‹‹„u{{}‚uttzl|Š}rg]j]\Š}‘…„zlllddek]mtt{{t‹‹„ttslri{u{ś¤¦|tll{{||lldMRKSKJF=C„Š„{{trfk””‹r]Z’ŚŚtllbVU]bZekdsle{tttll‚uekdtlltll››”…‹‹‚v{ult{u{\[[ultfkk>B9tll|„…‹’ŠcbVekd””‹u{{‹„„||{{ś››|„Š„™š¤ttszlllddmtttslttstt{„„ś››››”{{t…‹‹tts|„…{tt™š¤mttlriuzt|„…\[b}‡’…‹’…„’…„’Ś”•Ś”•}‡’Ś—Ł…‹šś¤¦™š¤{{¦§¨Ś—Ł…‹‹„„Ś”•Şł·‹‹‹™š¤Ś”•Ś‹““Ś”™š¤™š¤”››”››“Ś”™š¤›”›™š¤†~‘™š¤u{{lks“Ś”…‹‹‹’Škd\f]c|‚z|„…mttVZTnv‚|„……‹’llk„„u{{…‹‹Ś”•ult…‹š}f]c¤¤ť{|||‚zllk|‚z{{t]bZsle||„„””‹”“›dc\||\[[{tt\[b[TTŠ}tzl|„…VTLek]JHF{u{”››Ś”•Ś”•¨©´{{¦§¨„„š””{ttś››‹’Šuzt‹‹‹tslŠ}Š~‹tll|„…ztl|„…]bZ{||„„Š|„…‹’ŠŚ”•u{{‹„‹{{Ś”•…‹’ŚŚš…„’“““{ttu{{mtt]cd…‹‹{{||‹’Šb[Uekd{ttfkkZbN|‚z\UZekdSKJVTLldd[[Tdc\VTL¦§¨:97*)(slejcVD;93+*JHF74,JHF[TTult}‚|ulldttsŚ”•ult“Ś”||ult[[TttsUTS[[Tek]””‹„Š„„Š„Ś‹“„„Š“““š””ddc{{…‹‹|‚z‚|uult‹„‹‹„‹ult„„”››ultlks“Ś”uzt\UZlritslek]{u{tsllri]cd?;C{tt[[T‹’Šsle{tt‚|ulriJHFddcdc\ddcd\\tll‚uVTL[TTttsd\\ultttsb[Uult[TTUMR[TT‹’Šlri{||ttsekdfkk›˘›Š}|}““““““}tll›˘›llk··Ä“““„„Š“Ś”mtt”š”uzt¦§¨‹‹‹ztl{|||‚z‚uŚ”•{{‹„„…‹‹tslś››™š¤mtt{{|„……‹’Ś—Ł™š¤Şł·Ś”•}‡’|„…ś§˛Şł·Źˇˇ}}‹…’™š¤„„Š¬¶ĂŁśĄ¦§¨Şł·ś¤¦ś§˛›˘›™š¤Ś‹“ś§˛|„…ŁśĄ‚v‚¦§¨™š¤™š¤lks…„’ś¤¦]cduztmttu{{{{tts|„…Ś”•fkkmtt|„…Ś”•{{‹‹‹edk]bZlks}|’‹‹„}Šrfk{{t…‹’’tsl‹’Š]bZ[[TUTSŠ~‹u{{‚|u„„Šekd[[Tdc\u{{VZ[lrilekuztuzttsllrilriultd\\|„…‹’Štt{”“›”››¦§¨Ś”•¦§¨mw””‹‹‹„tslVTL{{™š¤{||”››‹‹‹„„”“›}tslllk„Š„“““”“›„„lriult™š¤{{‹„‹}tt{„„lks]bZ{{{u{{||‹‹„f]cdc\SKJ„„Štsl|llk[TT[[TztlVTLsrett{d\\¤¤ťJHF*)(j]\cbVJHFSKJF=CF=C[[T[[TbVU}{{t||˛««’ŚŚ{u{tlllekllktll{zmdc\kd\{{t{{tlri]bZ”“›‹‹‹™š¤„„“““‚wl””‹…‹’}||red|„…}Šsle‹’Š„„ŠŁśĄ…„’Ś”•ś¤¦”››SKJlektllŠ~‹‹’ŠŠ}\[bultleklritsld\\’ŚŚ{ttddc‚v{mtt„„“““tllb[U“Ś”d\\‹‹‹kd\b[UbVZdc\lddF=Cf]clekŚ”•mttf]cmttttsu{{…‹‹lri“Ś”Š}|„„lldtsl…‹‹“Ś”„Š„Ś”•‹…š{u{˛˛¬fkkŚ‹“uzt››”„„‹’Š”š””š”f]c|{ttlld”››„Š„…‹’{{|„…{{…‹šś¤¦ś§˛ś§˛}‡’}‡’|„…Ś—Łś§˛tt{™š¤{{t“““„Š„…‹‹¬¶Ăś››‹‹„…„’ŁśĄ¨©´“Ś”lks„„Š…‹’lekŁ››™š¤Ś‹“Š~‹„„Šmttś§˛Ś”•“Ś”lddmttUTS”š”|„…mtt”“›|‚zś¤¦Ś—Łtt{{||…‹‹…‹‹{{lks{{t‹…’tll‹‹‹“““¤¤ťkk]uztVZTddclekbVZtslkd\lksŚ”•VTL]bZtlluzt[TTtll‹’Š]bZekdu{{{{{{“““|‚zlri{{{u{lld››”{u{‚v{’ŚŚekd{{tzll„Š„||Š}|{{ś››„Š„ttsŚ‹“}‡’f]cmttŚ”•f]clri{{mtt]bZedk„†™ŚŚš‹…’mtt‹‹„tt{dc\]cdu{{tts‹’Š‹’Šllk{tt|‚zztl]cdlek[[T{{trg]VTL[[TSKJldd¦§¨\[[*)(sleJHFbVZJHFJHFVTLVTLkd\[TT’ŚŚ{{t„Š„||ttsrfk{{’…‹{{ttslllklri“““””‹llkttsu{{f]cŠŠ}}{{t””‹ek]lksfkkŠ}„„ttstzl„„d\\uzt”“›]cdultttsś››Ś”•d\\…‹‹UUY|||‚zddcdc\UMRdc\mtt‹‹‹rg]lek““““Ś”lddlri{ttjcV¦§¨‹‹„[TTj]\ek][TT{tt}Š|„…llk{tt‚v{}Š|‚ztt{\[[]cd\[[…‹’™š¤„„Š||”“›{||Ś‹“{||tsl|‚ztt{{||ekd“Ś”}ś››|‚z”››sle”“›“““„„„Š„›˘›|„…ekd]bZ|‚z„„dc\…‹‹…‹š…‹’„†™™š¤ś¤¦™š¤Ś—Ł…‹šŚ—ŁŚ—Ł}|’|„…Ś”•{{ś››{{{||‹‹‹{{„„ś››Ś”•Ś”•Ś”•™š¤ś§˛ś¤¦|„…™š¤‹…š‹„„ultŚŚš··ÄŚ—Ł™š¤ś¤¦ś¤¦lks]cdlksmttlri\[b…‹šmttŚ”•mtt„„ult…‹‹ś§˛{{t{{{{t}‹„‹“Ś”tts{{t]bZ[[T|‚zuzt“Ś”“Ś”llk””‹f]c{{]bZek]tsl\[[JHFmttmtt”››|„…{||ddcztl[[T\[[’ŚŚ™š¤”“›Ś‹“¦§¨}lld’ŚŚ„Š„¦§¨{{tlld‘…„›”›”››uztŠŠ}lkslld\[[tsl}‡’uzt|„…{{lks{||VZ[{{||lekŚ‹“lddlri{{[[T{{„„tsl…‹‹{{t]bZ|{u{‹‹‹{zmedkddc[[Tdc\VTLztl\UZldd¦§¨LKR*)(ztf{{t{ttUMRVTLj]\|‚zrg]‚v{f]ckd\tts{u{fkk‚v{„„Štt{slekd\dc\ttsuzt””‹lks”š”{u{tt{’…‹‹‹‹‹„‹{||’ŚŚ”š”Ś”•{tt„„\UZ‚|uf]ckk]{{t””‹{{\[buztś¤¦”š”tslmttlkstsl‹’Š{||SKJ\[[[TT|„…[[Tdc\’ŚŚtllkd\lkskd\‚uttzl‚|u{zm¦§¨tsld\\š””kk]lld{{ultf]c||ult]cdlkslks{||lek›˘›‘Ś……‹’}Šś¤¦‚u··Ä‹‹‹¦§¨ekd‘…„{||ultŁśĄ’ŚŚ””‹Ś”•‹‹‹””‹{{„„”››„„Š“Ś”|‚ztts‹‹‹™š¤{||{||Ś”•{tt„„Šlksś¤¦}|’„„Š…‹’|„…Ś”•}|’…‹šŚ—Ł{{‹’ŠŚ”•™š¤ŚŚš|„…ŁśĄ{u{\[b“““·¶ŃŁśĄ¨©´Ś”•¦§¨ŞÁĹ™š¤¨©´{||‹…’¨©´ś¤¦ś§˛Ś—Łś¤¦Ś”•u{{|„…mtt\[[tts}‡’|„…mtt]cdfkkddcŚ”•„„|„…‹‹„ultlri‚v‚{||d\\[TT”š”kd\kd\fkksre\UZJHFmtttts{{„„ŠVTLb[U‚utmtt\[b\[b|„…{||u{{|[[Tlld}}‡’{{Ś‹“”“›‹„‹‚|u{ttś››{u{|„…‹‹„{tt’ŚŚś››{ttmtt“Ś”‚u”š”ŚŚšnv‚mttmtttsl‚v‚Ś”•ultmtttt{…‹‹”“›‹„‹||uztu{{ultmttUUYult{{t{||ś››]bZsle\[[UTS[[Tllkdc\VTLVTLVTLd\\jV[SKJ¦§¨\[b74,red]bZlddekd[TTSKJ]bZSKJf]cb[Utslddcztl{{rfk‚v‚ult‹’Šdc\kk]{{tkk]dc\ult„Š„{{t‚|ud\\}Š[TTtzllri[[Tekdtsl¦§¨tll„„Štts|‚z|‚zŚ”•fkk}u{{{||uzt]cdJHFlksdc\[[TtllSKJ“Ś”tsl|‚zmtt‘Ś…tll‹„‹VTLsretll|{zmf]cllk{{t{ttUTS‹„„ztl{ttllkf]ctllf]cSKJJHFult„„Šu{{JHFtt{„Š}”››Ś‹“ś¤¦{tt{u{’…‹›”›mtt‚v‚Şł·dc\lek„Š„””‹lldkk]{||edk{{t|„…„Š„™š¤|„…Şł·ult{{mtttts|‚ztt{uzt{{Şł·™š¤Ś”•mk…{{{{™š¤™š¤}Šś¤¦lek„„d\\‹’Š|„…}‹„„f]clksŞł·‹…’‹„‹|‚zŚ”•”“›»ÂÇ|‚z{{t“Ś”„„Šś››Ś”•¨©´Şł·ś¤¦Ś”•fkkVZ[„„Š|„…{{^fs]cdmtt\[b”“›Ś”•”š”ultś¤¦{{™š¤f]c||tsl‹’Šddc’…‹JHF|„…‚u‚utf]cult\[[lkstt{{ttult‹‹‹™š¤Ś—Łnv‚\[[]bZekd]bZJHFddcult‹„‹™š¤…‹’…‹‹¨©´„Š„“Ś”‹„‹kk]|„…{||tll||tslult\[[Ś‹“|SKJf]cŚ—Ł|„…Ś”•{||tslŚ”•”š”…‹‹mttlks{{“Ś”“““mtttslult”š”yl„\UZtsluztultuzt||ddcd\\kd\UTStslVTL[TTlld]bZrg]d\\ś¤¦LKR*)(bVUVTL74,JHFJHFf]clldUMR{tt|‚z|uztb[U}Š“Ś”‹„‹{u{ztl{{tkk]b[U„Š„[[T{{tdc\‚v{Ś”•‚ut{{{tt{{tlricbV|‚zlek||tts{tttslult„„…‹‹{u{{u{tts|‚zmttUTS\[bUMRd\\ekdVTL[[TbVZult‹‹„{{srered[TTbVUf]cSKJ‘Ś…””‹sletsl{zm¦§¨u{{}[TTSKJ||bVZlddllk{u{SKJf]clkstt{MSS“““‹‹‹‹‹‹{u{„„Š|”“›™š¤‚|u‹’Šddc”››lks„„‹…’¦§¨tslult{{tŁśĄ‹’Š“““…‹‹›˘›Ś‹“{||{{{{\[btt{Ś”•{{‹„‹™š¤™š¤™š¤Ś‹“mtt}‡’}‡’lksmk…†~‘tts„„Š{{t}ttsu{{“Ś”‹…’™š¤ś¤¦|„…tsl‹„„]cdu{{ś¤¦…‹’{tt‹‹‹lks‹„‹™š¤…‹‹ś§˛Ś”•‹…šś¤¦]cdUTS}Šnv‚mttVZ[\[b\[b|„…}\[[|„…}ŠŚ”•|„…‹…’{{{u{””‹MRK{{™š¤f]cllkkd\{{lksŚ‹“„„lksmtt|‚z…‹’‹…’^fs\[[mttu{{{{t|‚zVTLtsltslVTLfkk…‹‹{{ś››‹…’›”›ult‹‹„‚u¤¤ť‹’Š“Ś”„„Š‹„„j]\…‹‹u{{|Ś”•f]cultLKR„„…‹‹}lddttsŚ”•}ŠŚ‹“…‹’™š¤…‹‹lekuzt{u{|„…lksmttlri|„…lriuztlekultd\\dc\UMRek]sle[TT]bZSKJ\[b[TT¦§¨MSS-1+VTL[TTPF=UTSddc\[[lld‚utred|‚z|‚z„„||u{{{ttbVZlek{zmj]\VTLmttdc\tzl|„…‹‹„{||lek}‹…’{{t’ŚŚ{{t\[[Š}UMR}tt{|‚z{{fkkš””„„™š¤‹…’{{™š¤|‚z“““ŚŚš‚wlVTLtsl[TTlks„vŚSKJ|‚z„„Šddc{||}lddj]\tts‰|vJHF[TT‹‹„‚|urfk{{tult’ŚŚsle„„ttstll{tt…„’MSSf]cult„„Š\[bldd{ttŚ‹“ultf]clekś¤¦Ś‹“‹’Š|‚z™š¤”››‹…’{||Ś‹“‹‹„„Š„||™š¤}Ś”•…‹‹lld|„……„’uzt{||mttedk|‚zś§˛™š¤ś¤¦™š¤™š¤¦§¨¦§¨›ť˛‰Šˇ|„…‰Šˇ{{mttŚ”•‹„„uztŚ”•“““›”›ś››ŁśĄŚ—Ł‹‹„llk‹‹„”š”ult|„…™š¤ś¤¦|‚zf]cf]c{{™š¤}‡’¨©´”››ŚŚšmtt]cd\[[ldd|„…Ś”•mtt{{VZ[lks{{lksmtt{{lek\[blks{u{Ś‹“{ttSKJ{u{tll{u{VZ[‹‹„tt{llkddclddrfk|„…„„{{tt{edk|„……‹šmtt‹‹‹]cd]cdlld{||{ttultŚ”•„„Š„Š„{{]cd{{t{tt¤¤ť„„‹‹„ś››u{{u{{‹„‹Ś‹“|‚z[TTtt{{{|„…u{{‹‹‹ekd{{t{||tllfkk{u{VZT|„…‹…š{||ddc|„…ult…‹‹ldd{tt|‚zekdddcUMRztlfkk‘Ś…‹„„SKJVTLdc\D;9JHFlldVTLldd¦§¨JHF,55sled\\:97JHFredbVUlri{u{tllUTSVTLlriultf]cult‹„‹ult‹‹„“Ś”]bZ{{„Š„tsl]bZ„Š„‚|uf]clekultdc\””‹llk…‹‹VTLVZTlek{{¦§¨›”›UTSd\\…‹‹{||tt{}Š™š¤”š”‹„„Ś”•ult‘Ś…‹‹„{{tJHF„„f]c„Š„ult{tt›”›sleztl‹„„rfkŁ››redrr]slettsšŤŚ›˘›“Ś”™š¤{||‘Ś…{{rfk{zm\UZJHFddc{{\UZLKRŠ}„„ŁśĄ‹„‹{u{ldd’…‹Ś”•‹’Š|‚zmtt‹‹‹||™š¤lks”››‹‹‹‚ut‚|u‹„„{||{ttŚ”•‹’ŠŚ”•“““[[Tmk…uzt“Ś”lks{{…‹šś§˛··ÄŚ—Ł¨©´™š¤™š¤™š¤}‡’†~‘mtt‹„‹{{t{{tŚ”•{{“““¨©´¨©´™š¤µ¶·}Šš””™š¤]cd{||Ś”•{{„„Šult{{‹…’Ś”•…‹‹{{ttstt{{||]cd…‹‹tts]cd|‚zŚ”•n…mttlkslks™š¤”››ŚŚšultu{{}}ŠŠ}‹‹„‹„‹uztg\rŚ”•Ś”•š””}”“›edk||f]c|„…{{|„…lks\[blksŚ—Łnv‚›˘›|‚z{{“Ś”‹„‹Š}|tll…‹’“Ś””“›”“›…„’tsl‘…„tslult…‹‹ś¤¦’ŚŚtt{}ŠŚ”•mtt„Š„…‹’“~™š¤mttfkk‹„‹}‹…’ttsfkkttsu{{{{{{\[[mttmttUMRllk}ŠmttuztUTSfkkUTSSKJ|‚ztsl[TTSKJ[[Trg]aWMlrilddcbVult¦§¨LKR,55‚wl[TT\UZddcJHFtll[[Tultllk]bZtzl{ttult[TT”“›tsl„„Š‹’Š||SKJmttŚ”•|‚zttsek]Ś”•lddś››llkd\\{||d\\mttJHFVZTbVZlks’…‹mtt|„…„Š}Ś‹“„„Š}Š{{‹’Šu{{lks™š¤{ttsle[[TUMR?;Cf]cSKJ„Š}lekttstt{„„Šf]c|UMRkk]ztlŠ}|VTLuzt…„’”š”f]c||VTL‹„„…‹‹lddldd[[Tekdd\\mttlks\[b{|||„…lksldd{{‹„‹ttsŠ}|‚zu{{{{‹’Š‹„‹||…‹‹››”|„…|}tll‹‹„Š}Ś”•‹’Š||„Š„tll{{‹„‹”“›{{ś¤¦…‹‹Ś‹“…„’ś§˛¨©´Ś—Ł·¶Ń™š¤…„’‰Šˇ„†™u{{b[Ulld{{||Ł››ŁśĄ”››‹„‹¦§¨ultŠ~‹¦§¨|‚z|„…™š¤¦§¨ś¤¦„„¨©´Łť˛mtt™š¤lks”“›lddŚ”•mttś¤¦“““Ś—Ł|„…{{nv‚ś¤¦]cd|„…\[b|‚zlek\UZlks‹„‹ŚŚšlek‹’Š„„’‘~}„„…‹‹Š}lks„„Š„„ŠŠ}…„’lks{||{{LKR…‹š{{\[b~’“|„…Ś”•mtt„„Šd\\…‹‹ŁśĄŚ”•”“›”š”‹…’Ś”•lriŠŠ}‹‹„”“›’ŚŚ¦§¨š””{{t‹…’|„…|„…lks{u{™š¤ś¤¦Ś—Ł|„…tllf]cfkk“Ś”lriu{{ultu{{{{|||„…mttlksŚ‹“lks…‹’„„…‹‹lks]cddc\\[[dc\[TTultddcsre{ttlrikd\ztlVTL¦§¨MSS:97tzlŠŠ}ultSKJVTLVZTVTL[TT[[Tf]c‚utllkŚ‹“dc\lekb[Utts}tt{|||„…mtt|‚zuztlld|f]clksult‹„„ultś››ś¤¦|‚zddc“Ś”Ś”•{ttJHFtsl‚|u|„…u{{„„|„…ttstt{…‹’}tlld\\iq]lriUMR|„…d\\llktlllri\UZ[TTsleŠ}\[[ultŠ}’ŚŚztl¦§¨‹„„”š”\[[||]cdJHF[TTVZTVTL\[[ekdSKJ^fsmttSKJdc\ldd„„Š“Ś”„„Š™š¤ult‹‹‹“Ś””š”}|}„„Š„„{||’ŚŚ…‹‹uztllklldtll›˘›{||{{tzlltts\[b}ultŽŁu{{Ś”•ulttt{™š¤„†™„„Š‹…š…‹’ŚŚš™š¤Ś—Ł“Ś”lek{u{›”›}“Ś”{u{µ¶·›˘›‹„„“Ś”™š¤¨©´Şł·ś§˛›˘›|„…ś¤¦‚v{ŁśĄ}Ś—ŁŚ”•…„’…‹‹”“›|„…ś¤¦lri¨©´{{|„…Ś—Łś¤¦}‡’mttlektt{‹’Š‚v‚”››ŚŚš„„Š„„Š[TT„Š„{{t‹‹‹{{t{{t„Š„ztl]bZ‹…’{{||ŚŚštts{||JHFVZ[lksn…MSSmttmtt{||fkk\[[™š¤ś¤¦Ś‹“‹‹‹›”›|„…“Ś”‹’Šldd„„‹‹‹‹…’Ś”•””‹“““Š}|‹„‹nv‚ultdc\™š¤tt{edkUUY{||„„ŚŚš{{mtt]cd\[b^fs‹’Š…„’mttmttmttf]cmtttsl„Š„ekduztUTS|‚utleklrid\\f]ccbVlddSKJlldUMRr]ZVTLµ¶·OS`)+2‹’Š|llkFD;[[TSKJFD;SKJVZTUMRJHFJHFtsllldredSKJ{||‹„‹UTS\[b¨©´ekd›˘›|‚z|„…tts{||„„mtt‹…’{||lri™š¤ś››]cd‚v‚uzt‹’Šztl[TTztltts™š¤\[btsl{{…‹‹{u{UTS‹‹„„„|„…]bZ{{JHFddcultŠ}|\[[d\\srelri{ttŠ}|rfksrebVZdc\edksleddcu{{\[[ekdf]c\UZ|„…d\\|‚z[[T\[[\[b™š¤d\\{{td\\ŁśĄ‹„‹¨©´Ś”•¦§¨||lritts‹„‹…‹‹}‹‹‹„„{tt¦§¨ś¤¦||||„…””‹›˘›‹‹‹…‹’’ŚŚttsUUY{{ŚŚš™š¤ś¤¦Ś”•}‡’ŚŚš¬¶Ă†~‘„„ŠŚ—Łś››¨©´…„’Ś—Łuzt¦§¨…‹’›”›tt{†~‘‹„‹{tt{||‹„‹™š¤™š¤{tt…‹‹}‡’Ś”•„„’ŚŚ“““‹…’™š¤ŽŁŚ”•lksś¤¦Ś”•…‹‹]cdlriddcult|„…uztŚ”•|„…¬¶ĂŚ‹“™š¤„„“““‹„‹ddcultult[TTtllekdiq]]bZ„Š„ekdkd\{{\[[ekdf]c™š¤„„{u{lksmtttt{|„…|„…n…Žˇ›ek]|„…„Š„lksuzt“Ś””››“Ś”mtt{{lks{{š””ś››†~‘‘Ś…“““‹‹„“““tllŚ”•„„Š’ŚŚ}Š|„…{{lksŚ”•ddc{u{{{tult|„…mtt|„…{{lksfkk\[b]cd\[b]cdfkkddcuzt]cdlri|‚z{||[TTb[Ukd\sleb[UyleyfdllkJHFaWMlriś¤¦OS`*)(tts}{ttd\\sre{{tb[UVTL74,JHFFD;UTSVZTkd\redjV[{u{ekdmtt{{tult{{t‹’Š|‚zu{{lkslri\UZuzt}[TT„„Ś‹“lri]cdddc{||UTStt{„„Š›˘›|„…tts{u{|„…››”uztultUTSlddztl|‚zek]{{:97f]c\[[{ttlld”“›{u{|‚z“Ś”{tt„„rfk{tt‹„„sref]cUMR[[TlriJHF||\[b{{„„™š¤Ś”•ult]bZult}||mtt’ŚŚ„„ŠŚŚšekdtt{ŁśĄ”“›Şł·“Ś”„Š„{||{||ś¤¦‹„„ŠŠ}{{tŞł·‹„‹”š”}u{{„„Š|„…’ŚŚ{{ultmk…}Šś§˛ś¤¦~’“ś¤¦ult›ť˛ś¤¦Ś—ŁŚ—Ł…‹šŚ—Ł„„Š|„…“Ś”tllś¤¦ś››ŚŚš}‡’š””µ¶·“Ś”“““›”›‹…’›”›ś¤¦|„…«˛«Ś—ŁŚ‹“¦§¨™š¤lks™š¤™š¤Ś—ŁŚ”•…‹’¨©´Źˇˇ…‹‹“““{ttź±ŻVZ[{{]cdmttUUY…‹‹„Š„ult”“›yl„Ś‹“f]cf]c‚wlddcJHF[[T|edk’ŚŚ„Š„ulttt{š””edkmttŠ}]cdMRK{{|„…OS`lriŚ”•]bZLKR{{lksuztyl„™š¤“Ś”“Ś”™š¤…‹‹…‹‹‘Ś…‹‹‹}‹’Šš””››”‹„„Ś‹“…‹’edkttslekmttfkk„„Ś‹“{||…‹’|„…„„\[[f]c\[b]cd{{lks|„…Ś”•}‡’‹„„…‹‹||„…lksVZT…‹‹‹’Šf]ckd\b[Uf]c[[Trg]red{{tekd]bZtsl¨©´JHF,55mttlldbVUFD;b[Uz‚lekd[[Tekdlri›˘›SKJlld„Š„}{u{{u{d\\UTS…„’lks|‚zlrimttu{{mttllk\[[llk\[[ldd{tt{||lri{{„„Šulttsl{{mtt|{||}}ult„„Š{{ttsdc\{{t{{t„Š„[[TlksJHFJHFd\\„„Š|‚z{{‚|uŚ‹“tsl[TTrfkVTLrfkdc\FD;sleekd[TTkk]|„…lld}{u{JHF{{\[[UUY]bZ{u{SKJllk„Š„zlllek{||„„Š‹‹‹||„……‹‹…„’‹’Š}‹„„Ś”•lld›”›‹‹„“Ś”lriŠ}ldd|‚z{{Ś”•llk“Ś”lks‹’Šlekmtt“Ś”ś¤¦Ś‹“{{|„…Ś—ŁŚ”•ś§˛‰Šˇ™š¤{{™š¤ \ No newline at end of file diff --git a/libraries/ode-0.9/drawstuff/textures/sky.ppm b/libraries/ode-0.9/drawstuff/textures/sky.ppm new file mode 100644 index 0000000000..8b541b10af --- /dev/null +++ b/libraries/ode-0.9/drawstuff/textures/sky.ppm @@ -0,0 +1,5 @@ +P6 +# Created by Paint Shop Pro +128 128 +255 +ľçýĂéţËî˙Îď˙Ćé˙Âç˙şç˙·ĺ˙˛ŕ˙°Ýţµŕ˙ąĺţĂë˙Íđ˙Ďđ˙ĐíűŃîüĎďţÇě˙˝ćü´ŕů´âüąĺ˙şć˙ąĺ˙µâ˙±Ţý«Ůú¦×ř§ŮüŞÜ˙¶âýÉî˙Đń˙Úőüâúţëýýíýüď˙ţěţ˙ěţ˙ăü˙Űř˙Ęí˙Äé˙­Ű˙ŁÔüŁŘ˙¤Úţ§Üü±ăţ°ă˙¤Ű˙ ŐýźÔţ Ő˙źÔţźŐ˙›Ô˙šŐ˙™×ţ×˙”Ńý™Ň˙šÓţ›ŐýˇŮţĄÚü­Ţü°ßů»ĺű˝čű˝ćü»ç˙¸ĺ˙®Ţ˙§Ű˙ťÓ˙šÓ˙•Đü•Đü—Ňţ“Ňţ‘Đű›Óř§Ůúľč˙Äę˙Ěđ˙Ćî˙şć˙¦×ř Öú“Ó˙‹Íý„Çü€Ä˙}Ă˙}Ă˙~Ä˙Ćţ€ÇýÉýČ˙Ć˙Č˙Ć˙€Ä˙Ĺ˙Ĺ˙Ć˙€Ĺţ~Ä˙}Ä˙Ć˙…Č˙ŚË˙ŤĚ˙„Çü…Ę˙Í˙‹Ě˙ŽÍ˙‘Đ˙Î˙™Ô˙ ×ţ±â˙´áţ¸ä˙Âę˙Ăč˙»ăý·ŕü®Üý©ŮýĄÖ÷©Ö÷ŻŰřÂë˙Ęđ˙Çë˙ĆéýËî˙Éî˙Ěđ˙Ćď˙żé˙şć˙»ç˙Ľč˙»ç˙ąĺ˙µä˙˛ŕ˙¨ŮúŁŐř Ôů˘Öý˛ßüÄę˙Ëđ˙Řö˙Ţů˙éţ˙ęţýěţţí˙˙ęţ˙×ő˙Îđü˝ăö·áů®Űú¬Ůúłŕ˙˝ç˙Âë˙Đô˙Ďô˙Ľé˙łŕ˙­Űü®Üţ¨Ú˙ŁŘ˙źŐ˙‘ÎúŽÍůŹĎű‘Îű•Ďý–ŃýÓýť×ý ŘýŞÜý¬Ýű¸ć˙»ç˙¶âý˛á˙¬Ýţ ÔűťŇüĐ˙•ĎýÍú‘Îű”Ńţ‘Ń˙‘ŃýŇř Ôů·ä˙Ŕé˙Çď˙Ŕě˙¸ć˙ĄŮţźÖý‘Ń˙ŠĚţ…Č˙}Áţyżý{Ŕ˙}Ă˙€Ć˙Č˙Ćý‚É˙Ç˙}Ă˙zŔüĹ˙Ĺ˙Ĺ˙~Ä˙|ÂýzŔűzÂýĆ˙…Č˙ŠÉţŠÉţ…Ćţ†É˙ŚĎ˙ŹÎ˙ŹÍţŹÍţŹÍţ”ĎűŇú¨Ý˙°Ţ˙˛ŕ˙·ă˙¸áý±Ýú®Űú¤Öů Ňő¤Ö÷­ŰüłßüĂé˙Ćě˙Ľâůşŕ÷Ăé˙Ĺí˙Čđ˙Ăí˙Ľć˙şäý˝ç˙˝ç˙Ľć˙·ăţłâ˙®ß˙¨Úý˘ÖűźŐűźÔü±ŢýŔč˙Çí˙Ôô˙Űř˙ĺý˙čţüě˙˙í˙˙ë˙ţ×ř˙Íó˙ľä÷ąăůµáüµáüÁë˙Íň˙Ňó˙Ú÷ýŘö˙Ćď˙Áé˙¸âűłßü®ÜţĄŮ˙ ×˙‘ÎűŤËúŽÎţÎý”Ń˙•Ň˙–Ó˙›Ö˙śÖüĄŰ˙¨Ýýłä˙·ć˙łâ˙ŞŰü¦ŘűźÔüŃü•Ďý’ĎţŽĚű‘Ďţ”Ň˙‘Ń˙’Ň˙ŇúťÓů˛ŕ˙şç˙˝é˙¸ć˙łă˙ĄŮ˙ ×˙ŽÎţ‰Ëý…Č˙~Â˙zŔţzż˙|Â˙Ĺ˙Ćţ€Ĺţ€Ç˙~Ä˙{Á˙yżý~Ä˙~Ä˙~Ä˙~Ä˙|Âý{ÁüxŔűĆ˙…Č˙‰ČýŠÉţŠË˙ŠÍ˙ŚĎ˙ŹÎ˙ŹĚűÍü‘Îý“Îú—Đű¤Ú˙ŁŘ˙ĄÚ˙®ŕ˙±ß˙ŞÚ˙ĄŮţšŃř—Îő˘Öű´â˙»ç˙Éí˙Čî˙ąáűłÜřłŕý·ä˙şç˙·ă˙˛Ţűąăü»ăýĽć˙˝ç˙¶ă˙®ß˙ŞÜ˙ˇ×ýťÔűšÔü›Őý«Ý˙¸ĺ˙Ŕę˙Íň˙Óő˙Ú÷ýßűţé˙˙ç˙ýé˙ýá˙˙Řú˙ÉíűĆëűÉî˙Ęď˙Ôő˙Ú÷˙Ůőůŕőöß÷÷Úö˙×ő˙Ďđ˙Éě˙ąâţŞÜ˙ˇÖ˙’Đ˙ŹÎ˙‹Ě˙ŽÍ˙Ď˙ŹĎ˙Đţ”Ó˙‘Đű›ÖţžŘţ¨Ţ˙Şß˙ĄŮţˇ×ýźÖýÓ˙“ĐýŹÍţŽÍ˙ŽÍ˙ŹÎ˙ŹÎ˙ŤĎ˙ŹĎ˙’Ďü–ĎúŁ×ţ¨Ú˙¨Řü¤ŘýĄŮ˙žŐţ—Ňţ‹Ęý†ČüĹ˙Ă˙|Â˙yľ˙zż˙}Ă˙~Ä˙‚Ç˙Ç˙xżýv˝ýuĽüwľţzÁ˙zÁ˙zÁ˙zÂýyÁüwżů€Ĺţ„ÇüÇüŠË˙ŚĎ˙ŠÍ˙Ęţ‘Îű•Îů”Íř–Ďú“Éő“ĘóťÔý›Ń˙žÔ˙©Ý˙¬Ý˙Ł×˙ ŐýŃü•ĐúźŐű±â˙Ľé˙Ěđ˙Ëđ˙Ľĺ˙´ŕý°ßý±ß˙´â˙´ß˙±Ýúşäýąáű»ĺţşć˙´ă˙¬Ţ˙¨Ü˙žŐüŇúŃü›Ô˙ĄŮţ˛á˙¸ĺ˙Ćě˙Ëď˙ŐóýÜů˙ç˙˙äţýć˙üć˙˙ßţ˙ĐńúÎîůĐňţŇó˙Úú˙Ýř˙ÝöúĺűůćűüßřýÚőüÚř˙Őö˙Âę˙Żß˙ŁŘ˙‘Ď˙‹Í˙…Čý‹Í˙ŽÍ˙ŤĚ˙ŤÍýĐţŹÍü—Ô˙šŐýˇŰ˙¤Ü˙žŐüˇŘ˙ť×˙“Đý‘ĎţĎ˙Ď˙Ď˙ŹÎ˙ŽÍ˙ŚÎ˙ŚÎ˙ŹÍü”ĎűžÓý ŐýˇŐüźÔüˇÖ˙™Ňý”ĎűŚË˙…Ćü‚Äţ~Â˙{Á˙zż˙zż˙}Ă˙Ĺ˙‚Č˙É˙wľüuĽüt»űt»űyŔ˙zÁ˙yŔ˙xżýwżú{Ăý‚Çţ„Çü†ĹúÉ˙ŚĎ˙‰Ě˙‡Éű•ĐúśÓúťŇúźÔü™Îö™ÎöˇŘ˙”Ěű–ĎüšĐüžÓý™Ňý“Îú“Ó˙”Ň˙šŐ˙ŞŢ˙˛ă˙Ăč˙Ĺí˙ľę˙¸ä˙®Üý¬Úű®Üý˛Ţű±ÝúłÜř·ßů¸ä˙´áţ®ß˙ŁŮ˙ ×˙śŐ˙›Ô˙›Ö˙ťÖ˙źÔü¨Úý­Ţ˙µáü˝ĺţËď˙ĐňţÚ÷ýŰ÷űŕúűí˙˙í˙˙ćűüĺý˙ăţ˙ßü˙Űů˙Űřţßű˙ä˙˙äţ˙ăřűŕřüŢů˙Úř˙Íó˙±â˙ˇŐüÎýŹÎ˙†É˙‡ÉýŚÎ˙ŠĚ˙‰Ë˙ŠĚ˙‹Í˙ŹĎ˙‘Ďţ“Đü’Ďű•Đü”Ďű’ĎüŹĎýŹĎ˙ŚÎ˙ŚÎ˙ŚÎ˙ŚÎ˙ŽÍ˙ŤĎ˙ŤĎ˙Ď˙‘Ď˙”Îü•Îű–Ďü•Îű—ĐýÓ˙•Ň˙ŽÍ˙ŠË˙‚Äţ~Â˙~Ä˙zŔţyżý~Ä˙|Â˙|ŔýĹ˙{Â˙xż˙wľţv˝ýwľţv˝ýwľüzÂýÇ˙Č˙†Éţ…Čý…Äů„ĹűŠÍ˙ŠÍ˙Đ˙˘Ů˙Şß˙µă˙¸ç˙˛ă˙¬Ţ˙ Ôű•Îű•Îű–Ěř™Ďű—Ňţ‘ÎűŇ˙’Ň˙–Ó˙ŁŘ˙©Űţ¸âűżč˙»ç˙µáţ®Űú±Ţűłŕýłßú˛Ţůµáü´Ýůµáţ˛ßţŞÜ˙ťÔűť×˙™Ô˙›Ö˙źŘ˙ž×˙ťÔű˘Řü§ÜţŻŢü¶âýČě˙Ěď˙×ő˙Űř˙Ýůüęýűîţűëţüę˙˙č˙˙ă˙˙Ţű˙Ú÷ýŢű˙ć˙˙ĺ˙˙ăřýß÷űÜ÷˙Úř˙Îô˙łä˙˘ÖýÍüŽÍ˙†ÉţĘţ‰Ë˙‡Ęţ†Éý„ÇűŠÍ˙ŤĎ˙ŽÎţŹÍüŹÍüÍúÍúŹÍüŹĎ˙ŹÎ˙‹Í˙‰Ě˙‰Ë˙‹Ě˙ŹÎ˙Ď˙Ď˙Ď˙Î˙‘Îý“Íý’Ěú‘Ëů”ÎüšÔ˙š×˙ŹÎ˙‹Ě˙Ĺ˙Ä˙~Ä˙|Âţ{Áý~Ä˙}Ă˙}ÁţĹ˙~Ä˙|Â˙zŔţw˝űyżýxľüxľü|ÂţÇ˙ČţË˙†Éţ‚Ăů„Ĺý‹Î˙ŠÍ˙‘Ďţ¨Ţ˙´ç˙Áí˙Äđ˙ľë˙µä˙¤Öű§Ý˙¦Ý˙śŃűĎř”ŃţĐ˙ŠĐ˙ŚĎ˙ŤĚ˙“ĚůÍő¬Ýý¸ç˙˝é˙Ľć˙ĽäýżĺüÂę˙˝ç˙˝ç˙¸ä˙¸ä˙°Ţ˙«Üý˘ŘţšÓţ–Ńý•ĐüÓ˙źŘ˙źŐ˙ť×˙ ×ţ¤Ú˙©ŰţŻÝ˙ľç˙Ăč˙Ňó˙Ůö˙Ýř˙ăřűçűúéţ˙éţ˙äý˙áúţÝůýŢúţŕü˙áý˙ßř˙ÚőţŰö˙Űů˙Őö˙Ĺî˙µä˙«ß˙“ĐýŚĚüŚÍ˙ŹÎ˙‰ËýŠÍ˙‰Ě˙„ÇüĆű†Çý…Çű‡ĆůŠÉüŹÍ˙Î˙ŹÎ˙ŤĎ˙ŚÎ˙…Çů†Čú‰Ë˙ŤĚ˙ŽË˙ŹĚ˙ŹÍ˙Î˙ŹÎ˙‘Ď˙‘Ď˙‘Ď˙“Đ˙–Đ˙™Ń˙™Ó˙ŹÎ˙ŚÎ˙…ČýĆ˙€Ç˙~Ä˙~Ä˙Ç˙Ĺ˙‚Ç˙‚Č˙Ĺ˙|Âţ{Áý|Â˙|Â˙zŔüzŔü~Ä˙Ę˙†Í˙ŽŃ˙ŤĐ˙‹Ě˙ŚÍ˙ŤĐ˙ŤÎ˙’Ďü«Ý˙¸ç˙Ěń˙Ňř˙Ďř˙Čđ˙µâ˙©Ţ˙¨Ţ˙›Đř—Î÷“ĐýĐ˙Í˙†Í˙É˙Ěţ•ÎűŁŮű¬ßţşć˙żčţÇęýËď˙Ěď˙Ăě˙Ĺď˙şč˙ąć˙«Üý§Ű˙ťÔý”ĎűÍú”Ďű–ŃýťÓ˙žÓýśÖţť×˙˘Ů˙¤Ř˙§×˙®ŮűµŢüÇę˙Îí˙×ó˙Űö˙Ţů˙Ü÷ţŰ÷űŰ÷űŰ÷űßřüäüţéţ˙ĺúýÝôú×ô˙Öó˙Ňó˙Ëď˙»ćů«ÜúĄÚü•ĐüÎý‘Đ˙Î˙ŽÍ˙ŤĎ˙ŤĎ˙ŚĎ˙‡Ę˙†Éţ‡Ę˙ŠĚ˙ŚË˙ŹÍ˙Ď˙Ď˙ŤĎ˙ŚÎ˙‹Í˙‹Í˙ŽÍ˙ŹĚ˙ŹĚ˙Ě˙ĚţŹÍ˙ŹÎ˙ŹÎ˙ŹÎ˙‘Ď˙“Ď˙”Îţ—ĎţŇ˙Ď˙ŽĐ˙Ë˙‚ÇţČţ~Ĺý~Ä˙}Ăţyżú}Âý‚Ç˙Ć˙Ć˙Ć˙€Ä˙~Â˙Ă˙Ä˙Ć˙‚Çţ„Ë˙‡ĘţË˙‰Ę˙‡Č˙†Č˙‡Čţ“Îú©Úú´ŕůĆčňÍîőŇô˙Ěń˙ĽäţŞŕ˙©ß˙›Ňů–Íö‘ÎýŽÎţ†Ë˙…Ę˙†ÇýŹËý•ÎűŁŘúŞÝüąĺţŔéýČěüËď˙Éě˙żčţÂě˙ąç˙¸ç˙«Ý˙©Ý˙śŐ˙‘ÎúŹĚů”Îü–Ńý›ŃýžÓýť×ýžŘ˙¤Ű˙¤Ů˙¦×˙ŞÖů±ÜüÄč˙Ęę˙Öó˙Ű÷˙Ýů˙Ů÷˙ŘöţŰř˙ŰřţŰ÷űâúţçü˙ĺúűŢöúÓň˙Đń˙Éî˙Äęýµâů¨ŮůźÔö•Îů”Îü’ĎţÍüŹÍţŽÍ˙ŤĎ˙ŤĐ˙…Čý…Čý‡Ę˙ŽĎ˙ŤĎ˙ŚËţŹÎ˙Ď˙ŤĎ˙ŚÎ˙Ň˙ŹŃ˙ŽÍ˙Í˙‘Î˙Î˙Î˙ŽÍ˙ŽÍ˙ŽÍ˙ŽÍ˙Î˙Ěţ’Ěü™Ń˙›Ő˙Ď˙ŽĐ˙Ë˙Č˙‚É˙€Ć˙€Ć˙}Ăţzżú{Ŕů€ĹţČ˙„É˙…Ç˙Ĺ˙Ă˙‚ÄţĆ˙Ć˙Ćý…Ë˙†ÉýË˙ŚĎ˙ŠĚ˙„Ć˙…ČýŹĚůˇÖřŞŰů˝ăđĆčňÍň˙Ěň˙żç˙°ä˙©Ţ˙Ńü”ÎüŽÍ˙ŤĚ˙‡ÉýŠÉü‹Éú–Đ˙žÔ˙°Ţ˙´á˙şäúżęűÇî˙Äí˙Ăë˙ľč˙ľč˙»é˙łä˙ĄŮţ˘Řţ—Ňü“Ňţ’Ńý™Ö˙›Ö˙śŇţťÔýˇ×ý¤Ú˙¤Ü˙ŁŮýŁ×üŞŰü°ßýĽäţŔĺ˙Éě˙Ôô˙ÓóţĐňţÎďţÍî˙ÍîýÔô˙Üů˙ßú˙äüţŢúţÍó˙Ĺî˙¸âű˛ßü¬Ü˙ĄÖţťŃůžÓűˇÖţ˘×˙śŇ˙•Íü’Ďţ‘Ď˙ŤĚ˙‰Čű‡Éý‰Ëý‹Ď˙ŠÍ˙ŽÎţŹĎ˙ŹĎ˙ŹĎ˙ŹÎ˙ŤĚ˙ŽÍ˙ŹÎ˙Î˙Î˙ŽĐ˙ŽĐ˙ŹŃ˙‘Đ˙‘Î˙Í˙•Î˙•Íţ–Ďü›Ô˙™Ô˙ŽÍ˙ŠÉţË˙Ć˙€Ä˙Ç˙‚Ç˙€ÂüÂů‚Ĺü„É˙‡É˙…Ćţ…ĆüŠÉţŠÉţ…ĆüĆý‚Ç˙Č˙„Ĺű‡Čţ…Čý‡Ě˙‡Î˙€Çý„ĘţŤĎ˙–Ő˙›Ř˙©Űü°ßýµä˙´ă˙·ć˙Şß˙¤Ů˙•Đü“ĐýŤĚ˙Ęţ‰Ë˙ŚË˙ŽĚýŇ˙žÔ˙˛ŕ˙¶ă˙ąćűżęűÂëýĆď˙Ćî˙żé˙»ç˙»é˙´â˙¦Řý˘Öý™Óű—Ô˙•Ňţś×˙ž×˙žŐü Öü¤Řý§Ű˙¦Ü˙¤Řý¤Řý®ß˙łŕ˙ĽäţżäţĆé˙Ńń˙ŃńţÍî˙Ěí˙ČëţČëţŃń˙Úö˙Ü÷˙ŕůţÜů˙Ëń˙żčüłÝöŻÜů¬Ü˙©Ú˙¤Ř˙ĄŮ˙¦Ú˙¦Ű˙ Ö˙—Ďţ”Îţ“Đ˙ŹÍţŤËü‹ĘýŤÍýŹĎ˙ŽÍ˙ŹÍüŽÎüŽÎüŽÎţ‹Í˙ŽÍ˙ŽÍ˙ŹÎ˙‘Ď˙Î˙ŤĚ˙ŽÍ˙‘Đ˙’Đ˙‘Í˙‘Í˙”Îţ–Ěú™ĎűźÖýśÖţŹÍţŽĚ˙ŤÎ˙„Ć˙Ć˙‚Ç˙‚Ç˙ĂýÄűĆý†Ë˙†Č˙„Ĺý†ÇýŽÍ˙ŽÍ˙‰Ę˙†É˙Č˙„É˙…Ćü†ČüĆúË˙‡Í˙‚Čü†ÉýŤÍý’Ďű–Ńý˘Řü¤ŮűĄÚüĄÚü«ŕ˙•Îű•Ďý‘ÎýŚĘű‡Éý‡Ę˙‡Ę˙‹Í˙Î˙–Ó˙›Ô˙­Ý˙±â˙şę˙ľě˙Ľé˙Ľč˙ľę˙¶âýłßřłßř·ä˙ŞŘü¦ÖüźÓúźÖýžŐü˘ŘţŁŮý§Ůú¨Űú¨ŮúŞŰüŞŰü«Üý­Ţ˙±ß˙µâ˙żč˙Âę˙Ăč˙Čë˙ÇęţĹčţĹç˙Ăç˙Ăç˙Éé˙Ńđ˙Ňď˙ŐńýŐő˙Äęýąâř˛Üő±ŢűŻÝ˙­ß˙Żá˙­ß˙¬Ţ˙«ß˙ Ő˙™Íü›Ń˙žÔ˙ Ö˙ Ö˙źŐ˙źŐ˙›ŃýÎú“Íű‘Ďţ‘ĎţĐ˙ŽĐ˙‹Í˙‹Í˙ŽÍ˙ŹÍţĚţÎ˙Îý‘ÎýÍü™Ń˙žÔ˙ Ő˙¤Ř˙ŞÜ˙«ÜýĄ×úśÓü—Đű”ÎţŤĘ˙ŚË˙…Č˙…Č˙…Č˙…Čý„Çü†Éţ‡Ę˙†Çý‡ÉýŤĚ˙ŤĚ˙ŤÎ˙ŚÍ˙„Ć˙‚ÄţÄúŠÉţŠÉţĘţ‰ČýŚËţŽĚý‘Îý”Íú•Îů™Ô˙—Ô˙”Ńý’Ďű’ĎűŹÉůÍüŹÍţŠÉü†Éţ‰Ě˙‡Ę˙ŚÎ˙ŹÎ˙“Đ˙—Ń˙¦×˙¬Ţ˙·é˙Ľě˙¸ćţ¶âý·ă˙´ŕű˛Ţ÷łßřąä˙®Úý«Ůý¤ÖůŁ×üŁ×ü§Ůú¨Űú«Üú®Ýů°Ýü±Ţý±Ţý˛ß˙´á˙˛ßţµáţľç˙Áč˙Áć˙Çë˙Çę˙Ćč˙Ĺé˙Ĺé˙Ĺé˙ĹčţÎď˙Ďî˙ŃîţŃň˙Ĺë˙»äú˛ÜőŻŰř«Ůű®Ţ˙®Ţ˙¬Ü˙«Ý˙«Ý˙¦Ú˙źŇý˘ÖţĄŮ˙¦Ú˙«Ü˙¬Ý˙ŞŢ˙ĄŮ˙ˇŇú“Ě÷‘ÎűÎýŹĎ˙ŚÎ˙‹Í˙‹Í˙ŽÍ˙ŹÍţĚţ‘Îý’Ďţ’Ěú’ĚúťÓ˙ŁŘ˙§Ř˙®ß˙łá˙łŕý­ÜúŁ×üźÓú—ÍűŹËýÎ˙ŠË˙‰Ę˙‰Ě˙‰Ě˙†ÉţË˙ŠÍ˙ŠĚ˙‰Ë˙ŤĚ˙ŚË˙ŤÎ˙‹Ě˙Ĺ˙Äţ‚Ăů‹Ę˙ŤĚ˙ŹÎ˙ŽÍ˙ŽĚýŹÍţ‘Îý”Íú•Îű‘ĎţĐ˙‘Ń˙Đ˙ŽÎţ‡Ćű†Ĺú…Ćü†Çý…Čý…Čý‹Î˙ŹŃ˙ŹĎ˙ŚĘůŤĘ÷™Îř Öü®ă˙±ć˙¬Ýý­Űý®Üţ¶â˙ąĺ˙»ç˙˝ć˙¶ß˙´ß˙±Ţý°ßýµä˙¶äţ¸ćţ˝ę˙˝ę˙Áë˙Áé˙żç˙˝ä˙żć˙żç˙˝ç˙Ľäţ˝ä˙żç˙ĂéţÄčţÄčţĹé˙Ćę˙Çë˙Ćę˙Íđ˙Ďó˙ÎďţÎň˙Ĺî˙Ŕč˙łßú˛Ţű´á˙µă˙±ß˙ŻÝţ°ßý°ßý±ß˙ŻÜűµáţ¸ä˙»ĺýĽćţÁë˙Ăí˙˝ç˙¶ŕřźŐűšŐ˙–Ó˙‘Ń˙ŤĎ˙ŚÎ˙ŚÎ˙ŹÎ˙Î˙‘Îý”Îü—ŇţśŇţśÓü¦×˙«Ű˙µâ˙˝ç˙Âč˙Čě˙Ćě˙ąĺţ´ŕý¨ŮúťŇü›Ô˙ŹÍţŽĚ˙ŽÍ˙‹Í˙†ČúŠÎ˙‰ÍţĘţĘţ‹Í˙ŚÍ˙‹Ě˙‡Č˙ÄüŠË˙†É˙‰Ě˙‰Ě˙ŤĎ˙Ď˙‘Ď˙’Đ˙’Î˙ŹÍţÎ˙ŤĎ˙ŚĎ˙ŚĎ˙ŚĎ˙‰Ě˙†Çý‡Čţ…Č˙„Çţ‰Ě˙ŤĐ˙ŚÎ˙ŤĚ˙ŹÍţŠČ÷ĹňÎúžŐţ¦Ü˙¦Üţ¤Ůű¦ÖúŞŘüąć˙»é˙ľę˙żč˙ąâ˙¶ßýłßü·ăţĽč˙Ŕí˙ĽéţÄď˙Ćń˙Ăě˙Âç˙Ŕĺ˙Ŕĺ˙Ĺę˙Âç˙żç˙ľć˙ľć˙żç˙Éď˙Čî˙Çí˙Čí˙Éí˙Čí˙Éî˙Ëđ˙Íň˙Îň˙Ěň˙Ăě˙Ŕč˙´ŕű˛Ţű´á˙±Ţ˙±Ţ˙¶ă˙ąć˙»é˙»é˙Ľé˙ĽĺűľçűĘď˙Éî˙Ďô˙Đő˙ÇěüÁčů«ŕ˙›Ö˙Ő˙‘Ń˙ŠĚţŚĎ˙ŚĎ˙Ď˙’Đ˙’Ďţ–ÎýśŐ˙žŐţźŐű«Ű˙ŻÝţąăüČî˙Îń˙Îď˙Ęí˙Ćě˙Âë˙˛ŢűŁŐúźÔü“ÍűŽĚýŽÍ˙ŤĚ˙ŽĐ˙‹Í˙ŠÎ˙Ěý‡Ëü†Čü‡Čţ‹Ę˙‰Čţ‡ĆüŚÍ˙ŠÍ˙ŚĎ˙ŤĐ˙Ď˙Î˙Ěţ’Î˙‘Ď˙ŽÍ˙Ď˙ŤĎ˙‹Í˙‹Í˙ŽĐ˙ŤÎ˙Í˙„É˙‚Ç˙‰Ě˙ŽĎ˙ŚÍ˙ŹÎ˙‘Ď˙“Đ˙ÍúŹĚů‘Îű•ĐüÓűšÔúśÓú Ôü§×˙µâ˙¸ĺ˙Áî˙ľć˙Áé˙Âę˙Äě˙Çđ˙Éď˙Ëń˙Ćě˙Éđ˙Ęď˙Çě˙ÄčţĹčüČë˙Éě˙Íđ˙Éî˙ÁĺűÁĺűĆě˙ĆíţĆíüÇîýĘď˙Ęí˙ČěüĘîüËńţËó˙ĆîřÄěřĂě˙Ăí˙şć˙¶âýłŕ˙´á˙˛Ţű¶âý»ĺţĽĺűĹď˙Îó˙ŃóýĐňűŐôůŘőűÝü˙Ţý˙ŐöýÎđů˛ă˙™Óű•ĐúŤÍýŚËţ†Éţ‡Ęţ‹Í˙‘Ď˙”ÎţŃţšÓţ ŐýĄŮţ·ä˙ąĺţÄęýÖö˙Ů÷˙Ü÷˙Ýř˙Űř˙×÷˙Çě˙±Ţű«ÜýšĐü“ÍűŹÍţŤÍýŤĎ˙ŽĐ˙ŠĚţË˙‰Ě˙‹Î˙†ÇýÇü‰ČýÎ˙’Đ˙‘Ó˙ŹÎ˙ŽĚý’Ěú–Ďü•Îű”ÎüÎ˙‹Í˙‹Î˙ŤĎ˙‹Ęý‡ĆůÇüŠÉţ‚Č˙Ç˙Č˙†É˙‹Ě˙ŽÍ˙‘Ďţ”Ń˙Ó˙—Ňü•ŇţŹĎ˙ŹÍüŽÍů‘Îú–ŃýťÓ˙˘Ő˙®Üţ°ÝúşçüÁę˙Äí˙Ăě˙ÄęýĘď˙Íň˙Ęď˙Éě˙Éě˙ÇěţÉî˙ČëţĘîţĎđ˙ĎďţÍíüÍîýËďýÉíýĆëýĆě˙ĆíţĘď˙Ěď˙Íî˙ËěýËď˙Îó˙Îő˙ĹďýÂěüżčţ˝ç˙µáü¶âýĽč˙µáţ´ÝůşâűżčţĂéüČěüÖö˙ßü˙ŕű˙ĺţ˙äý˙ć˙˙ä˙˙Űů˙Ňóü°ßýĎö’ËöŠĘú†Čú…Čý‡Ę˙ŽÍ˙‘Îý”Îţ›Ô˙›Ô˙¤Ř˙¬Ţ˙şč˙Ŕę˙Îň˙Ýú˙ŕů˙âúţćűţé˙ýç˙˙Řř˙ŔćýµáţˇŐüĎřÍüŤÍűŠĚü‰ËýŠĚ˙ŠÍ˙ŠÍ˙‰Ě˙ŚÎ˙ŠÉţŚËţŐ˙™Ô˙ŃüťÔű Öú¦Öú¦×řŁÓ÷ Ň÷–ĎúÎ˙ŤĎ˙ŽĐ˙ŠÍ˙ĆúÄú…Ćü€Ć˙‚Č˙„É˙…Ç˙‹Ę˙ŹÎ˙’Ńý–Ó˙™Ôţ™Ôţ—Ô˙Ď˙ŽÎţŽĚűĎű–Ó˙žÔ˙˘Ő˙«Ű˙®Ýů·äůżčüÄí˙ĂěţĹëţÍň˙Íň˙Ęí˙Ęí˙Ëî˙Éî˙Éî˙Ëď˙ĚđţĐňţŃńţÖö˙Öö˙ĐňţĚíüËď˙Ćě˙Ćě˙Éî˙Ëî˙Ěí˙Ëě˙Ěí˙Ěń˙Ěń˙ĂěţŔéűżç˙ľč˙·ăţµáü¶â˙·ăţ¸âű˝ćüÁęţÉî˙ĚíţŘő˙Ţů˙âű˙č˙˙ŕřüßřýŢů˙Úř˙Ôňü·ä˙ťŇú•ÎůŠĘú…Çů†Ě˙‰Ď˙Ď˙Íü•Íü™Ň˙™Ň˙¦Ú˙­ß˙ąç˙ŔëţŃó˙ßú˙ăü˙éţ˙ě˙˙í˙üě˙˙ŕü˙Çë˙Ľć˙Ł×üšŃú“ĐýŹĎý‹ÍýĘü‹Í˙‹Î˙ŠÍ˙‡Ę˙ŤĎ˙ŠÉüŤËüšÔ˙žŐţžÔú¬Ţ˙łä˙ąĺ˙·ă˙ŻŰřŞŘůśŃů’ĎüŹĎ˙ŤĐ˙‰Ď˙„Ęţ„Çü‚Ĺü~Ä˙Ĺ˙€Ĺ˙Ăý„ĹűÇü•Ó˙š×˙ś×˙ťÖ˙ťŘ˙ŤĎ˙ŚÎ˙ŽÎţ‘Ń˙™Ö˙źŐ˙ˇÔ˙ŻÝ˙˛ßü¸âřşă÷Ĺî˙Éď˙ĹęúĘîţĘîţĆéüÉě˙Đń˙Îď˙Ńó˙Ôö˙Öö˙×ő˙Ů÷˙Ţű˙áţ˙ŕţ˙×÷˙ÇëůČě˙Ĺë˙Ĺé˙Çę˙ÉéţÉéţĚď˙Ëî˙Éî˙Áçúľäů˝ç˙»ĺţ¶ßűµáü˝é˙Áë˙Äě˙Çí˙Čî˙Ňö˙Öö˙×ô˙ÔđüÖńüŕř˙ář˙Ýő˙Űö˙Úö˙Őň˙»č˙žŇů–ÍôŹÎúĐ˙Ó˙’Ő˙•Ô˙‘Îý“Íý‘Éř”Íú¦Ű˙­ß˙¸äýÂë˙Ňô˙Ţúţäý˙ë˙˙ě˙ýî˙ůě˙ýĺţ˙Îď˙Ăé˙«ÜüˇŐúš×˙–Ő˙ŤĎ˙ŹÎ˙ŽÍ˙‹Í˙‹Í˙‹Î˙ŤĐ˙ŚËţŽĚűśÖţ¨Ü˙©Řô˝çýĘđ˙Ôő˙Óó˙Ďđ˙Ćę˙°ßýźÖ˙–Ó˙ŠÍ˙‰Ď˙‡Ě˙„É˙|Ăű|Ä˙}Ĺ˙Ĺ˙}Ăţ~Ăü€ĹüŹĐ˙—Ö˙™×˙™Ó˙’ĎţŠÎ˙ŠÎ˙ŽÎţŽÎü™Ó˙ŁŘ˙¨Ů˙´ŕýşäýĽĺű˝ĺţÄę˙ĆëţĘëúÎď˙Íń˙ÄéüÇęţŃđ˙Óđ˙ÚőţÜ÷ţŘőűŰřţÜůýç˙˙ç˙˙ŕý˙Űů˙ÉíýĂç˙Äč˙ÁçţŔäúÇě˙Ěń˙Íň˙Ëď˙ĘîüËěűĆéüľĺ˙ľĺ˙şâüşäýÁë˙Čń˙Ćď˙ĆíţĘń˙Îň˙Ö÷˙ĎďúĐń˙Ďó˙×÷˙ŕü˙Ţů˙Ţů˙Úö˙Öôţąĺ˙ŁŐú™Íô’Í÷‘Îú’Ň˙ŽĐ˙‘Ń˙ŽĚýŽĚý’Ěü”ÎüˇŘ˙ĄŮţ¶ă˙Âě˙Ôő˙ßú˙ĺý˙ě˙˙éüúđ˙üđ˙˙čý˙Řô˙Ńň˙»ä˙«Üü›Őýš×˙Đ˙Î˙ŹÍţÎ˙Ď˙ŽŃ˙ŠĐ˙‹Í˙ĎűźŐű·ć˙¶âűÇî˙Ó÷˙âý˙ăü˙Ýř˙Óđţ·áů¦Ü˙šŐ˙ŚĚü‹Í˙Ë˙„Çü~Ăü|Ä˙|Ä˙|Ä˙|Ă˙yÁüwżůÄýĆý†Ĺű‹Čţ‹Éü‰ÍüŚÎţĐ˙Îý—ĐýĄŮ˙­Ţ˙¶âý»ĺýĹë˙Éď˙Čë˙ËěýŇđűŇň˙Îď˙Ëî˙Ěď˙Óň˙×ô˙Ţőűĺý˙ă˙˙ĺ˙˙ć˙˙č˙˙ç˙˙äý˙Ţű˙Îď˙żäţ˝ä˙ľč˙żé˙żé˙ľčţÄí˙ĂéüĹęüĚđţËđ˙Ĺę˙Äé˙ÁçţÂč˙Éď˙Ćě˙ÂčűĂěţČň˙Éđ˙ĐňţËď˙Ăě˙Áę˙Ęď˙Îď˙×óţŰö˙ŰřţŮöţĘó˙µâ˙ŞŰűźŐůśÔů‘ĎřŽÍř‘ĎţŹÍţŹËýÍü’ĎüśŐ˙ˇÖţ˛á˙»ç˙Îň˙ÖóűÝöűéţ˙ë˙ţí˙˙í˙˙éü˙Ţö˙Řő˙Çí˙ąĺ˙ŁŮýť×˙ŽÍů“Đ˙‘Ëů–Đţ—Ń˙ŽÎüŤĚ˙‘Ń˙”ŃýźÓř»ç˙Çí˙Řú˙ŕţ˙ć˙˙č˙˙äý˙Ű÷˙Äę˙¬Ţ˙˘Řţ“Ń˙ŤĎ˙‡Éý†ÉţČ˙|Ä˙{Ăţ{Ăţ|Ă˙wżútĽ÷zŔű}ÂűÂúÇý‰ČýĚűŠĚüŽÎţŹÍüŃţ§Ű˙°á˙»ä˙żç˙Ęđ˙Ęđ˙Íî˙ĐđýŮő˙×ő˙ÎîýÎď˙Ëď˙ĎďţÔń˙ăú˙č˙˙ć˙˙â˙˙âţ˙ę˙˙ę˙˙ćţ˙ßú˙Đđ˙ľć˙ąĺ˙ąĺ˙Ľč˙»ç˙·ăţĽć˙żčüÄęýËđ˙Ęď˙Çë˙Çë˙ĂčűĂéüÉď˙ĹëţŔćůÂëýČń˙Ĺď˙ČíýÇí˙ľč˙»ĺţĆę˙Ëě˙ÖňýÜ÷˙ßú˙Ýř˙Îó˙ľč˙¶äţ«ŢýĄÚúśÖü™Ôü—Ô˙‘Í˙ŽĘüŹËýŹĚű™ŇýžÓűŻÝţąĺ˙Ęď˙ÔňüŮôűćţ˙ę˙˙ě˙˙í˙˙čý˙ß÷˙Ű÷˙Ęď˙ľč˙©Ţţ˘Úý”Ďů”Ńţ“ÎúťÓ˙źŐ˙•Đü‘Îű—Ô˙™ÔţžŇ÷˝é˙Ëđ˙Ýű˙ŕý˙âű˙äý˙Üř˙Őő˙Äě˙˛ă˙ŞŢ˙Ö˙ŹŃ˙‡ÉýË˙…Ę˙|Ŕý|Âţ~Ä˙~Ä˙v˝űsşřuĽúzŔţ€Ä˙Ă˙„ÇţŠĚü‹ËűŤËúŹĚůžÔ˙©Űţ±ß˙˝ĺ˙Ăé˙Ěď˙Ëď˙Úö˙áü˙č˙˙âű˙Ţú˙Öö˙ĐňţÎîűÔňýŕůţć˙˙ĺ˙˙Ýůüßřüě˙˙ë˙ţęţ˙äű˙ŐńýŔéýµăű­Ú÷°Ýü°Ü˙­Ůü¶á˙Âě˙Čń˙Íô˙Ěň˙Ôô˙Őő˙Đń˙Ěđ˙Ěń˙Ćě˙ľçűĽĺűżé˙˝ç˙·ăţłŕ˙®ß˙ŻÝţ˝ĺ˙ĂçýÓďűŰö˙áú˙ÜřüĎí÷ÎđüĚň˙Äď˙»č˙Żŕţ§ÜţźÖ˙•Ďý‘ËűŽÍ˙ŚĚü“ĐüšÔüŞÜ˙´ă˙ŔéýŇô˙Řö˙ßű˙ĺţ˙č˙˙ę˙˙ćţ˙ßřýÚ÷˙ĘîüĹëţ»é˙˛ä˙¦ÜţźŮ˙ Őý«Ý˙®Ţ˙ŞÜ˙ĄŮţ¤Ű˙ˇŘ˙źÓř˝é˙Ńň˙Ů÷˙ÓńüĐđýĎđ˙Ćě˙Ŕé˙µâ˙Żß˙«Ý˙”Ň˙ŚÍ˙Äú„Çţ€Ĺţ}żű€ÂţÇ˙Ĺ˙xż˙wľţv˝ýwľü}Ă˙~Ä˙Č˙ŽÎţŹĎý”Ńţ–ŃýźÖ˙­Ţ˙łŕ˙Äę˙Éî˙Ďđ˙Öôţäý˙č˙˙ě˙˙ě˙˙ë˙˙Úö˙ÓńűÓńűŘöţÚóřŕůţáý˙Ű÷úŕřüęţýě˙ýě˙˙ëţ˙ß÷˙Îó˙Ĺî˙˝ĺţĽĺ˙ąâ˙¶ß˙»â˙Ĺé˙ĘîţÓő˙ÓôýÚ÷˙Űů˙Őő˙ĐňţĘîţÇí˙ÁçţłÝö´Ţ÷˛ßüŻÝ˙ ÔűˇŐüŁ×ü±ŢýżäţŃíűŮô˙âű˙ŕůţŰ÷űÚ÷űÚůţÔö˙Íń˙ľčţłáűĄ×üšĐţ”Ěű“Ó˙Đ˙“Đý—Ňü¤Ůű­ŢţşäüĚđ˙Ńó˙Úř˙â˙˙ć˙˙č˙˙ćţ˙ÝöúÚóřÔňüĐňţÉď˙ľčţłâţ¬ŕ˙®Ţ˙˛Ţűłßúµáţ´â˙©Ű˙ˇŐüśŇř¸ć˙Ćě˙Ĺčţşŕ÷µăű˛áýŞß˙˘Řü›ÓřˇŘ˙žŐţŤĘ˙É˙„Ĺý„Ć˙‚Ç˙…Ć˙„Ć˙€Ĺ˙~Ä˙zÁ˙xżýwľüzÁ˙Ĺ˙Ĺ˙Č˙‘Ďţ”Ň˙•Ň˙—ŇţˇÖţ°Ţ˙¶á˙Äę˙Ęď˙Öř˙Öôüćţ˙éţ˙î˙˙ë˙˙çü˙Űö˙ÖóűŐňř×ôúßřüŰôůÜřüä˙˙ç˙˙ë˙ţě˙ýě˙˙ě˙˙ŕř˙ÎđüËď˙ĆëţÄč˙Âĺ˙Áä˙Ćč˙Ëě˙ŃńţÖôüŃď÷ŮöüŰů˙ŃńüĎńýĘîţÇí˙Ĺë˙ąăüµŢú±ŢýŞÚţˇŐüźÔü Ôű°Ýţ˝âýŇď˙×ó˙ŰöýÝř˙Ýöúâţ˙ßű˙Ů÷˙Öö˙Éď˙Áë˙¬ÝţťÓ˙–Îý‘Ď˙“Ó˙Ő˙Óű˘×ů©ÚúşäüÉíýÎďţŘö˙Üů˙ä˙˙č˙˙č˙˙áůűÝöúÚ÷˙ÓóţČíýĆě˙˛ŕř¨Úű®ÜţĽĺ˙ąăü¶ßűĽé˙Ą×üžŇůťÓůŻá˙˝ć˙ąâţ±Ţű¨ÝýˇŮüžŮ˙šŘ˙’Ďű•Ň˙—Ń˙‰Čţ†Ç˙‰Ę˙Ë˙†É˙„Ĺý„Ĺý‚ÄţÄý}Ăţ}Ăţ€Ć˙‚Č˙…Ę˙Č˙‰Ę˙’Ďţ•Ň˙Ň˙™Ňý ÔűŻÜý¶ßűĂčűÉíýÔőţŰú˙ë˙˙í˙˙ó˙ýîüýěű˙âů˙ßřýáúţäţ˙ç˙˙ĺţ˙áý˙ŕü˙äý˙éýüęţýë˙˙ĺü˙Ůő˙×ő˙×ő˙Öó˙Ôô˙Ôó˙Ôô˙Öó˙Úô˙Ýő˙ßöţÜőüÔňüÔňüĘę÷ČéřÄçúÇí˙Ĺî˙Ŕé˙şć˙¶ă˙¶ä˙«Ý˙Ł×ţ˘Öý°Ýţżç˙Ńň˙Ůö˙Űů˙Üú˙Ţů˙áú˙ŕůţŕű˙Ýú˙Ňó˙Éď˙´ă˙˘×˙›Ô˙‘Îű”ŃýÓű›Ňů¨Úű°ßű˝ćüÉíýÎđüŘö˙Üů˙ŕüýăýţćţţę˙˙č˙˙ä˙˙ŕý˙Ôö˙Ěđ˙şŕő±ÝřŻŰö·ßř¸ŕú¶ă˙®ß˙ ŐýźÖýźÔüťŃřˇŐü˘Ů˙ž×˙•Ô˙‘Ń˙ŚĐ˙ŤÓ˙ŽŃ˙‹Í˙‹Ę˙„Ĺý…Ć˙‹Ě˙ŠÍ˙„Çü†Çý†ÇýĆý‚Ĺü€ĹţĆţČ˙Ę˙†Ë˙‡Ę˙‹Ě˙“Đ˙–Ó˙šÓ˙›Ńý Ôű°Ýü·áúĹčűËěűÖôţÝú˙ë˙˙î˙˙ô˙ţňüýďý˙éü˙ĺý˙ç˙˙é˙˙č˙˙ç˙˙âţ˙Ýúţáý˙éţ˙ë˙ţčý˙ŕůţŐň˙Úö˙Úö˙Úö˙Řö˙×ő˙×ő˙Úö˙Ü÷˙ßöţáőţÝôüÔô˙Óó˙ĘëúĆęúĹęýĂě˙Âě˙˝é˙»ç˙şć˙ąć˙Żŕ˙ŞÜ˙ŞÜ˙µâ˙żç˙Đń˙Öő˙×÷˙×÷˙Üř˙Ü÷ţßř˙ŕű˙Ţů˙Ňó˙Ëđ˙¶ă˙˘×˙›Ô˙™Ô˙šŐ˙›ŐűžÔř«Üü˛áűľçűËěýÎîűŘô˙Űřţŕüýáűüăűűčýţéţ˙ĺţ˙ŕű˙Őő˙Ďđ˙Áćůąăű¶ŕů¸âú¸âűłá˙¨Ü˙śÖţť×˙źÖýÍő™Ďű™Ó˙•Ň˙ŹĎ˙ŤĎ˙‡Í˙‹Ń˙ŠĐ˙‡Ę˙†Çý…Ćţ…Ćţ‹Ě˙ŠÍ˙„ÇüŤĎ˙ŤĎ˙Ęţ„ÇüÉý…Ë˙Éý†ÉţŠĚ˙ŤĚ˙‘Ď˙•ĎýŇ˙ťÓ˙źÔ˙§Ř˙·ă˙˝ĺ˙ČěüÎđüŮ÷˙Űřţę˙˙í˙˙÷˙˙ř˙˙ö˙˙ň˙˙ď˙˙ě˙˙ě˙ţčýţćţ˙ŕü˙Űřüŕü˙č˙˙ç˙˙ßřý×ôüÍî˙Óđ˙Őń˙Ů÷˙Űů˙Ýü˙ÝüţÜúüŢúţŕů˙ă÷˙Ýô˙Ňö˙Ńň˙Ęí˙ÄéűÂčűĂě˙Ŕę˙ąĺţşć˙ľë˙˝çý¸äý˛á˙­Ţü´áţ»ăýÄçűÉęýĘí˙Éî˙Đđ˙ÓńüŘô˙ÚőţŘóüŇň˙Ëî˙´áţ˘×˙ž×˙śÖţžŐüˇ×ű§Ůú¶ă˙»ç˙Çě˙ĐđýÔđüŰöýáú˙äţ˙ĺý˙çüýéýţęţ˙äű˙ßř˙×ő˙Ňň˙Đó˙Čî˙Äí˙şć˙µâ˙˘ŘüźŮ˙–Ő˙”Ó˙ ×˙śÓü“Ń˙‹Ę˙‰Čý†Čú‰ËýŚÎ˙ŚÎ˙‡ĘţË˙†É˙‡Č˙†Ç˙Ë˙‰Ě˙ĚýŤĎ˙ŤĎ˙Ęţ„Çű†ÉýŠÍ˙Ë˙ŠĚ˙ŤÍýŹÍţ“Đ˙–Đţ™Ń˙ťÓ˙ Ő˙¬Ü˙¸ä˙żç˙ÉíýĎńýŮ÷˙Úůţč˙˙í˙˙÷˙˙ř˙˙ö˙˙ó˙˙ď˙˙í˙˙ëţúęţ˙ĺý˙ßűţŰřüßűţç˙˙äüţÚőüŐóýĚď˙Ďî˙Óđ˙Ů÷˙Űů˙ŰýţÜţýÚúůÜřüáů˙âř˙Űő˙Îó˙Íđ˙Čí˙ÁçúľäůÁę˙żé˙¸ĺü¸ĺüĽćü˝ćř»ĺű¶ĺ˙˛áý¶âý¸âűżâřÁäřÄéüĹęýËě˙Ňď˙Řô˙ÖńüŐđűŇďýÉě˙±Ţű ÖüťÖ˙ˇŘ˙ŁŮ˙§Üţ¬ßţĽč˙Áë˙Ěď˙Őóţ×óţŕů˙ĺü˙é˙˙ë˙˙éýţĺůúäřůŢőűÜőüŮ÷˙Őő˙×ú˙Ěń˙Čî˙¸äý±ŕţšÔú—Ô˙“Ó˙ĐţśÖţžŐţ—Ő˙ŠË˙‰Ë˙‰Čű‹ËűŹĎ˙ŽÎţĘüŤĎ˙‰Ę˙„Çţ„ÇţŠÍ˙ŚĎ˙ŠÎ˙‘Ď˙Î˙ŽÎţŽÍ˙ŚÎ˙ŚÎ˙ŤĎ˙ŚÎ˙ŽÍ˙Ď˙‘Ď˙•ĐúŃüźÖý Öü«Üýľç˙Çí˙Ňń˙Őň˙Űö˙áú˙ë˙˙ď˙˙÷˙˙ö˙üô˙űń˙˙î˙˙č˙˙ç˙˙âţ˙ŢúűÜřůßůúăűýâúţŢ÷üŘô˙Ňń˙Éě˙Đń˙Ńó˙Ňô˙Ő÷˙Řú˙Ő÷˙Őö˙×ő˙ŘöţÜů˙Űů˙Îó˙Čď˙ÁçúĽĺůÁë˙Ľč˙şć˙·ä˙µâ˙°ßý«Ţű¶é˙´ĺ˙˛áý´ŕűşă˙şâüşâü»ĺţ»ä˙Čě˙Íđ˙Đó˙Îő˙Éň˙Ŕď˙ąé˙ŞÜýˇÖţ¤Ů˙©Ý˙ŞÝü°ßű·ăüÇí˙Ěđ˙Řö˙Üőüßřýč˙˙éţ˙čýţéţ˙ę˙˙ćűţáůýÝöýŰö˙Ű÷˙Úö˙Ňň˙ĎńýĂęű¶âýŻÝţźÔţšĐţ”Îü•ĎýžŐţžŐü™Ň˙•Ďý’ĎţÎ˙ŹĚ˙ŤĚ˙ŤĚ˙ŤĚ˙Î˙‘Í˙ŠĘú‰ËűŤĎ˙ŽĐ˙ŤĎ˙’Î˙‘Í˙ŹÍţŤÍý‹Í˙‹Í˙ŤĎ˙ŚÎ˙ŤĚ˙ŹÎ˙Î˙”Ďů—ĐűžÓű Ôů°Ţ˙Ľć˙Ćę˙Đď˙Őň˙Ţö˙ĺý˙ěţţď˙ţö˙˙ř˙üő˙üń˙˙í˙ţćţţäý˙á˙˙ßűüÝúřâúúçüýĺý˙ŕů˙×ô˙Ńđ˙Ćé˙ĘëúÍďűŃň˙Ôő˙Ńň˙ÉíýËď˙ÎđüŇňýÖ÷˙Ő÷˙Ëň˙Ćě˙ľçű»ĺű˝é˙şç˙¸ĺ˙µá˙´ŕ˙®ß˙©ß˙¬â˙¬ßţ¬Ýý´ŕýµŢü¶ßý¸áýąĺ˙»ç˙Ĺé˙Ëî˙Ëń˙Ăđ˙Ŕď˙¸ę˙±ä˙ĄÚü˘×˙¤Ů˙ŞÜ˙«Ţýµăý˝ç˙Ęď˙Ďđ˙ÚőţÝöúáůűę˙˙éţ˙ęţ˙ęţ˙ę˙˙ćţ˙äý˙ŮôýŘóüŮő˙Řö˙Ňň˙ÎňţÄęý¶ă˙±ß˙ŁÖ˙›Ďţ”Ěű•ÎűžŐţ ÖüźÔüšĐü–Ďü’Î˙ŹĚ˙ŹÎ˙ŹÎ˙ŹÍ˙‘Îý“ÍűŤĚřŹÎú’Ň˙‘Ń˙ŹÎ˙’Î˙’Î˙Î˙Î˙Ď˙ŽĐ˙ŤĎ˙ŚÎ˙ŤĚ˙ŹĚ˙Î˙•Đü™Ň˙źÔţ˘Öýµă˙Ŕę˙Čě˙Ňň˙×ő˙ăü˙ě˙˙îţţďýýôţýř˙ţ÷˙ýô˙˙ď˙ţçüýăű˙ŕü˙ßűüâüýç˙˙éţ˙ăű˙Ţ÷üŐóţĎďţĆéýĐń˙ĎńýÉíýČí˙Çí˙Ăé˙»äúżĺüĂéţČî˙Ćď˙ľč˙¸äýłßúŻÝ÷ŻŢüŻŕ˙¬ÝţŞÚţ©ŮýŁ×üžÔřťŐúŁŮ˙ĄŮ˙¤ÖűŁÓ÷¬Ůú±Üüşă˙˝ç˙ĘëţÎď˙Čí˙»ĺűąĺţŻŕţĄ×řśĐőŁ×˙¤×˙¦Űý«Ýţ»č˙Áí˙Íň˙Ňó˙Űö˙äüţčý˙ë˙ţęţýí˙˙ěţ˙ë˙˙ĺţ˙áü˙ŐńýĐíűÍî˙Îď˙Çě˙Áęţ¶âý­Ţ˙ŞÜ˙ Ő˙žÔ˙šĐüťŇú©Ţ˙Żá˙¬Ýţ¤Řý ŐýšÓ˙–Đ˙ŹËýŹËýÍü•ÎűŃţ›Őýť×˙ťŘ˙šŐ˙“Đ˙”Î˙”Î˙’Î˙’Đ˙“Ó˙”Ô˙ŽĐ˙ŹÎ˙ŹÎ˙’Đ˙“Ń˙Ň˙ťŐ˙¨Ý˙©Ý˙łá˙żé˙Čí˙ŃńüÖôüăü˙ęý˙ń˙˙ő˙˙ö˙˙ö˙ü÷˙˙ő˙˙ń˙˙ě˙˙ę˙˙âű˙ßřüáúţç˙˙éţ˙äü˙ßřýÖóűŇđűĘëúÍďűÍîýČí˙Äí˙şć˙łŕ˙¬Úü©Úű«ÜýŻÝţŻÝţ¬ÝţŞŰü­Ţ˙ŞÜý¨ÚýŞß˙©Ţ˙§Ý˙ĄŰ˙žÖűťÔű•Ď÷—ŇţšÔ˙śÖ˙ťÓ˙«Ý˙łá˙ľč˙Ĺę˙Ďđ˙Íđ˙Çí˙·ă˙´á˙¦×˙ťŃůšĎůźÖ˙śÓú ÖúĄÚü´ă˙şć˙Ěń˙Ôő˙Ü÷˙čý˙ë˙˙ëţüí˙ţď˙ţî˙˙ë˙˙Ü÷˙×óţÍî˙Äçű˝ĺţ»ĺţ°Üů®ÜýŁ×üˇÖţ ×˙ťÓ˙ Ö˙˘Öý¨Úý¸ç˙˝ë˙şć˙´áţ®ß˙¨Ü˙¤Ů˙ťÖ˙ťÖ˙ťÓ˙žÓűŁŘ˙«Ý˙¬Ü˙¨Ü˙¤Ů˙śŇţ”Îţ”Îţ’Ďţ‘Ď˙‘Ń˙’Ň˙ŤĎ˙ŽÍ˙Î˙“Ń˙“Ń˙–Đţ™Ń˙§Ü˙ŞŢ˙łá˙˝ç˙ĆëţŇňýŘöţĺţ˙ęţ˙ń˙˙ő˙˙ö˙˙÷˙˙÷˙˙ő˙˙ň˙˙ě˙˙ę˙˙äü˙ŕřüáůýéţ˙éţ˙ĺý˙ŕůţŘőýŐóűÎđúĐňţĐń˙Çí˙Ăí˙¶ĺ˙®ß˙¤Őý Öüˇ×ýŁ×ţŁ×ţ˘Öý˘ÖýŞŢ˙«ß˙©Ý˙©ß˙Şŕ˙¨ŕ˙ĄÝ˙ťÔűžŐţ—Đý“Đ˙”Đ˙•Ó˙—Ń˙§Ü˙±á˙ľč˙Ćě˙Îň˙Ęđ˙Äě˙¶â˙±Ţ˙źŇ˙ÎüŃţšŐ˙—ŇúśÔů˘×ů±â˙¸ć˙Ęď˙Ňó˙Ü÷˙čý˙ë˙˙ëţüî˙˙ď˙ţí˙˙ę˙˙Ű÷˙×ô˙Ęí˙Áçţąĺ˙¶ă˙©Úű¤ŘýťÔűžÔ˙ž×˙žÔ˙ ×˙§Ůü­Ţţżě˙Äď˙Äí˙˝ç˙¶äţ®ß˙ŞÜ˙ Ő˙ ×˙źÔüŁ×ü¨Ü˙´â˙łŕ˙­Ţ˙«Ý˙ Őý–Đ˙•Ď˙‘ÎýŹÍüŹĎ˙ŹĎ˙ŽÎţŤÍýŽĚ˙Î˙‘Ď˙“Íý—ĎţźÔţĄŮ˙˛ŕ˙şäúĂčúŃňűŮřýë˙˙î˙˙ô˙˙ô˙˙ö˙˙÷˙˙÷˙˙ň˙˙đ˙˙ë˙˙ęţ˙ăřýăřýĺú˙čý˙çü˙ĺý˙ăü˙ÜřüŮöüÚř˙Ôö˙Îň˙ŔéýąĺţŞÜ˙¤Ř˙ž×˙Ň˙—Ń˙”Ďű‘ĚřŃţ›Ô˙ŁÚ˙¨Ý˙­ă˙¦Ü˙ˇŘ˙ˇŰ˙ˇÝ˙“ÎöťÓ˙ťÓ˙Ě˙ŤĘ˙Ď˙ŹÍ˙šÓţĄŮ˙´áţ˝ĺ˙żé˙¶ă˙łá˙§Ű˙ Ô˙–Đ˙“Ď˙’Đ˙•Ô˙”ÓţśÔůˇÖř˛ŕ˙ąĺ˙Čí˙Îď˙Ü÷˙čý˙éü˙î˙˙đ˙˙í˙˙í˙˙ăü˙Ú÷˙Ôő˙Áé˙ąĺ˙±ă˙ŞŢ˙—Íů”Ěű•Ď˙—Ń˙™Ó˙ˇŘ˙ĄŰ˙¬Ű÷łáůČďţĚđüÎđüĘîţÄęý´ŕűŻŢü¤Öů ÔůĄ×ü«Ý˙˛â˙şć˙Ľč˙´á˙°Ţ˙¨Ü˙•Ď˙•Ď˙‘ÎýÍüÎ˙ŹĎ˙ŽÎţŽÎţŹÍ˙Î˙‘Í˙“Íű–ĎüťŇü˘Öý®ÝűąăůÂçůĐńúŘ÷üé˙˙í˙˙ô˙˙ô˙˙ő˙˙ô˙˙ő˙˙ń˙˙ď˙˙ë˙˙ę˙˙äůüäůţĺúýçü˙ćűţäý˙äý˙ßű˙Üů˙Űř˙Řř˙Ńő˙Ŕé˙·ăţ¦ŘýžÓý”Ńţ’Ďţ“Đ˙ÍúŤĘ÷”Îü—Đý Ö˙˘Ů˙¦Ű˙ĄŰ˙˘Ů˙ť×ýśŘý”Ď÷šĐüžÔ˙”Đ˙Î˙Ď˙ŹÍ˙šÓ˙ŁŘ˙ŻÝţµáţµăý±ß˙­Ý˙ŁŘ˙ťÓ˙šÓ˙—Ó˙“Ń˙“Ó˙“ŇýžÔúĄ×úłâ˙şć˙Čí˙Îď˙Űö˙âů˙çü˙ě˙˙í˙˙ě˙˙ęý˙ßř˙Ôô˙Ěń˙şć˙˛ŕ˙©Ţ˙¤Ű˙“ËúÍü’Î˙”Ń˙–Ó˙ ×ţ§Ý˙°ßůşäúĚň˙ŇóüŃňűÎďţÉîţ˝ç˙¶äţ§Řů¤Öů§Ůü¬Ţ˙±â˙Ľč˙˝é˙µâ˙°Ţ˙§Ůţ”Ěý”Ěý’ĚüÍüŹÍüŹÍüŽÎţŹÍţŹÍţĚţÍü–Ńű™Ňý Őý¤ŘýŻŢü˝çýĆëýŃńü×őýĺţ˙ëýýń˙˙ň˙˙ń˙˙îüüďýţëýýęţýę˙ţę˙ţí˙˙ě˙˙í˙˙í˙˙ę˙˙ç˙˙ç˙˙ä˙˙ăţ˙Ýú˙Řő˙Ńň˙Ŕĺ˙¶â˙˘ŘţšÓţ’Ďţ–Ô˙Ö˙—Ô˙”ŃţÍú’ÍůťÔýˇÖţźÓú ÖüźÔüŇúÓű—ŇüĎřťÓ˙™Ń˙–Đţ“Íý“Íű–ĎüśÓüžŇůžŇ÷¦Öú¦ÖúĄ×üžÓý™ĎűšŐ˙™Ô˙—ŇţÓ˙ÓýˇŐú§Řůłŕý»ä˙Čí˙Îď˙Úö˙Ţ÷ţâů˙čý˙čý˙çü˙ŢöúÓďúČëţżčţŻÝţĄ×ü›Ô˙™Ó˙Ě˙‘Ď˙’Đ˙”Ń˙Ó˙ˇŮţ©ŢţąćűÇî˙Řř˙ŰřţÜ÷ţ×ő˙Óő˙Çí˙Ľć˙­Úű«Ůű­Ý˙Żŕ˙Żŕ˙µâ˙¶ă˙łá˙®Ţ˙¤Ř˙”Ěű”Ěű“ÍýÍüŹÍüŽĚűŽÎüŹÍţÎ˙’Î˙’Ďţ—Ňü›Ô˙ŁŮ˙¨Ü˙łâ˙ľčţÇě˙ŃńüÖôüăü˙ëýýđ˙˙ń˙˙ď˙ţěüüíýýëýýęţýę˙ţë˙˙ë˙ţëýýë˙ţě˙˙é˙˙ĺţ˙ăü˙ßřýŢů˙Ýř˙×ô˙Ďđ˙Ŕĺ˙¶â˙ŁŮ˙›Ô˙“Đý–Ő˙™Ö˙—Ňü”ĎůÍú“ÎúźÖ˙ŁŘ˙ŁŐú ÔůžŇů›ŐýťŘ˙™ÔüźÖýźÖýťÓ˙šÓţ™Ň˙•Îű—ÍůšĐü™Đů™ĐůŁÓů¦ÖúĄ×úžŇ÷›ĎöžŐüžŐüśÓúťŇúžÓű§×ű¬Úű¶âý˝ĺ˙Ęí˙Ďđ˙Úö˙ßř˙ßř˙ćý˙č˙˙ăű˙ÝöýŇđűÇë˙ľč˙ŞÚţ Ôű–Đţ“Ď˙ŹÍ˙Î˙‘Ď˙“Đý—Ňü˘Řü¬ßţľčţĘď˙Úř˙ÜřüßřýŘöţŐő˙Éí˙˝ĺ˙®Űü¬Úü®Ţ˙®Ţ˙Żß˙˛ŕ˙±ß˙Żß˙«Ý˙ˇ×ýšŇ˙šŇ˙Ň˙•Ň˙‘ĎţÎýŹÍüŹÍţ‘Í˙–Ň˙Ő˙™ÔüžŘ˙¨Ţ˙¬á˙·ć˙Ŕę˙Čí˙ĎďüÔňüŢ÷üęţýě˙űí˙üí˙ţí˙˙ëýýęţýé˙ýč˙ţé˙˙ď˙˙í˙ţě˙ýéţ˙çü˙âű˙Ţ÷üŰôűŢ÷ţâű˙Úö˙Ňń˙Áć˙¶â˙Ł×ţśÓüŐ˙™×˙ťŘ˙™Óř•Ńö—Ňţ›Ô˙ĄÚ˙§Ű˙ŞÚţ¨Ú˙¨Ů˙˘×˙ Ú˙ťÖ˙˘Ú˙ˇ×ű Öü˘Öý˘Öý¤Ř˙śŇţ›Ô˙—Ô˙—Ô˙¨Ř˙˛Ţ˙łá˙®ßý¬Ţů°âý±ăţ´ă˙±Ţ˙˛Ý˙¸ĺ˙ąć˙ľč˙żç˙ÇęţËěýŃďú×ôüÚőţŢů˙ßú˙ßú˙Ţů˙Óó˙Ćě˙Ľč˙¦ŘýťŇü“Í˙Ě˙ŽË˙‘Ď˙‘Îý”ĎűŇúŁŘúłä˙Äí˙Îň˙Ú÷˙ß÷űŕřüŢů˙Űů˙Ěń˙Ăë˙¶ă˙±ß˙ŞÚ˙¨ŘţŞÚţ¬Ü˙¨Ú˙¤Ř˙˘Öý›ŇůźÔüťÔűśÖţťÖ˙–Ńý‘ÎúÍůÍů•ĐüšŐ˙śŐ˙ ×˙ĄÚ˙­ß˙±ß˙żč˙Čî˙Ëđ˙Đń˙Őő˙Ů÷˙ĺţ˙éţ˙éţ˙ę˙ţé˙ýčţüęţüë˙ýë˙ýë˙ýđ˙˙í˙˙éýţŕřüÜřüÔňüŇđúÍíúĎďüĐđ˙Íđ˙Éî˙˝ç˙·ăţŞÝüĄÚüˇ×ýź×üŁŮ˙ˇ×űžÔřź×ú˘Úý©ß˙©ß˙¨Ü˙¦Ú˙¤Ř˙Ł×üŁŮýĄÚú©Űü˛á˙łáű´ŕű»ç˙µáüŞŰű¦ŘűŁŰ˙¤Ţ˙łá˙Äě˙Čî˙ĘîţĘëüĹęúĆëűÉîţÍîýËëřÉđ˙Ćď˙Ćď˙Ĺî˙żčţżĺüĂçýÍî˙Ňň˙Řö˙Řö˙Óő˙Óó˙Ńđ˙Áé˙¸ĺ˙ˇÝ˙™Ř˙ŹĎ˙ŹÍţ“Íý’Ďü•ĐüšŃřźŐűŻŢüąĺ˙Éî˙Ďđ˙Ú÷˙ÚöúÝř˙Úö˙Ů÷˙Ńň˙Čí˙˝ć˙¶á˙¦ÖüˇÔ˙ŁÖ˙źŐ˙ Ö˙źŐ˙ťÓ˙šÓţ Öü ÖüźÖýť×˙–Ńű”ĎůÍů“Îř–ŃűśÖţť×˙ˇŘ˙¦Ú˙­Ý˙°Ýţ˝ç˙ĹëţÉě˙ÎďţŇó˙×÷˙ßű˙äü˙ĺý˙ç˙˙č˙ţć˙üé˙ýęţýë˙ţěţţď˙˙í˙˙éü˙Ţ÷üŰöýÖö˙ÓóţÎďţĚđ˙Íî˙Ěń˙Čî˙˝çý·ăü­Ţü©Üű©Űü¦ŰýŞÜ˙©Űţ¤Ůűž×ő˘Řú¨Ţ˙©Ţ˙¨Ý˙¤Ř˙Ł×ţ¤ŘýĄÚüŞÝüŻŢüµăýşäü˝ćüÂë˙˝ćü°Ţř«ÚřĄŰý¨ŕ˙µâ˙Čî˙Ěď˙ŐóţŐóţĎďüÍďűĐňüÔňúŇď÷ÎđúĘđűČď˙Éď˙Áę˙ľć˙˝ćüĆëţĘîţĎńýĎńýÍó˙Đń˙Íě˙»â˙±ß˙›Ů˙“Ö˙ŽÎţŹÍţ•Íţ”Îü•ĐúśÓú˘Öű˛ßţ»ĺţÉě˙Ďđ˙ÚůţÚőüÜř˙Ű÷˙Ů÷˙Ďđ˙Čëţľć˙¶â˙¨ŘţˇÔ˙ˇŐ˙ˇ×˙źŘ˙›Ô˙›Ń˙śŇ˙˘Řţ˘Řţ ×ţžŘ˙šŐ˙™Ôţ–Ó˙™Ôţ›Ö˙ť×˙ť×˙ĄÚ˙§Ű˙­Ţ˙±Ţýľč˙Çí˙Éě˙ÉęűĚíüĎďüÖóűÚőüÝůýáý˙ă˙˙ç˙˙ć˙˙ĺ˙˙ç˙˙č˙˙ĺřţéü˙çű˙Ţů˙Úř˙Ő÷˙Óő˙ÎďţËď˙Íî˙Ëî˙Ćëýľäůşăů¶ăúµáú¸ć˙˝é˙ľę˙şă˙´âü¬Ţ˙ŞÜ˙¨Ü˙¨Ű˙¤×˙ˇÔ˙ˇÔ˙ĄÖţ©Ű˙Żŕ˙¶â˙ĽćţČî˙Ěń˙Îń˙Ëđ˙Ŕé˙şäý°á˙°á˙Ľč˙Íň˙Óô˙Űů˙Üř˙Űů˙×÷˙×ů˙ßý˙Ţů˙ŢúţŰ÷ű×ő˙Öö˙Îń˙Éí˙żčţÁę˙Äí˙Ćď˙Ćđ˙ÄëüĆëýĂç˙°Űű§Ůú™×˙‘Ô˙ŤÍýŽĚý’Ěü•ĎýšÔü˘Řţ¨Ü˙·ä˙Ľć˙Ęí˙Đđ˙Ú÷ýŰ÷űÚőţÜř˙Ůő˙ÎîűĚíţÁçţąăüŞŘú ÔüžŃţšĎű›Đü›ĐúśŃűˇÖ˙ˇÖţˇÖţ ×˙ťÖ˙ś×˙ś×˙š×˙›Ö˙›Ö˙śÖţśÖţ¤Ů˙§Ű˙®ß˙˛ßţżé˙Éď˙Ëî˙ĘëüĚíţĎďüÔňýŘőýÚ÷˙Ţű˙ßü˙ĺ˙˙âţ˙áý˙âý˙ĺţ˙Ţőűář˙ŕů˙Řô˙ŐóýÔö˙Ňô˙ËďýÉíýĘí˙Íń˙Ëî˙ÄéüĂčűŔéýŔé˙Âë˙Ěň˙Íó˙Äčţ˝ĺţ±â˙­Ý˙©Ú˙¨Ů˙ˇÔ˙ˇÔ˙˘Óţ¦Öţ©Ů˙±ß˙»ä˙ĂéţĎň˙Óô˙Ôô˙Đń˙Éî˙Âë˙¸ć˙µâ˙şäüĚď˙Ňó˙Üř˙Űö˙Úř˙Öö˙×ů˙ŕţ˙áü˙äü˙âúüŰöýÚö˙Ńň˙Ëî˙Ăéţżčţżčţľéüľéüľçůżčü»ăý­ŰüĄÚü—Ö˙“ÔţŹĎ˙ŹÍţ”Î˙—ŇţśÖţĄŰ˙¬Ţ˙¸ä˙żé˙Ěď˙ŃńţÚ÷ýÚöúŮôýŰř˙Ůő˙ŃńüĐń˙Ęî˙Ŕč˙¬Úű¤Ř˙˘Ő˙ËöšÍřžŇúźÓű˘ÖţźÔü ŐýžŐţšÓţś×˙žŮ˙™Ö˙™Ô˙—Ňü›Ô˙ť×˙ˇ×ý¦Ú˙­ŢţŻÜůąăűĹë˙Éî˙Éě˙Ëî˙ĘîţĚíţĎđ˙Ńň˙Öö˙Řů˙Úř˙ÓóţŃńüŇň˙Óô˙Ůö˙Ú÷˙Řő˙Ňň˙ŃńţŇó˙Ńň˙ÉíýĆéüČëţĎđ˙ÎďţÍîýÎďţĎđ˙Ďđ˙Őő˙Ýű˙Ýů˙×ó˙Ňň˙˝ć˙łßüŞÚţ¨Ů˙ Ó˙źŇ˙ˇŇý§×ýŻÝ˙ąĺ˙Áę˙Ďó˙Ůö˙Ű÷˙Ýř˙Űö˙Řő˙Ňó˙Çí˙ĂéţľäůÉęűÎîűŰö˙Űö˙×ó˙×ô˙Őő˙Řö˙Ü÷˙ß÷űŕřüÝöűŘóüÔňýŇň˙Íń˙Çě˙ĆëţĹë˙Ăě˙˝ę˙ąćý­ÚůŁŐú Öü”Ňů’Ńú‘Ďţ“Ń˙–Ň˙–Ńý ×ţŞŢ˙±â˙»ç˙Áé˙Íń˙Ňň˙Ýú˙ßű˙ŕů˙ÝöýŰöýÚ÷˙Ů÷˙Ďó˙ĆíţłßúŞÜýĄŮţťŇúťÔýžŐţťŇüśŃűźÔü ŐýťÔý™ŇýšŐ˙ś×˙–Ó˙–Ńý•Đú›Ô˙źÖ˙¤ŘýŞÜ˙°Ţ˙ŻÜů·áůĆě˙Éí˙ČëţÉě˙ĆéüĆëţÉî˙Íń˙Ôö˙Öř˙Óó˙ÍďűÉíűĘîţĚď˙Îď˙Ďđ˙Ďđ˙ÎďţÎďţÎďţÎďţÉíýÇęýĚď˙Ôô˙Ôô˙Ôô˙Öö˙Ů÷˙Řö˙Úö˙Ýř˙Ţ÷ţÜőüŮő˙Äí˙şäý®ÜţŞÚ˙źŇýźŇýˇŇű«Ůű±ß˙Ľč˙ÂčűŇó˙Ůő˙ÚőţŢ÷ţŕů˙Úö˙×ő˙ĚđţČí˙ĹëţËěýĎěúŮô˙ÚőţÖô˙Őő˙Őő˙ŐóţŮő˙ÜőüŢ÷ţÜ÷ţŘóüŐóý×ő˙ÎîýĘëüĘí˙Îń˙Ěó˙Âď˙Ľč˙ŞŘúźÓúžÖű—Óř“Ńř’Ďű’Ďţ–Đ˙–Ďúˇ×ý­ß˙˛ă˙˝é˙Ŕč˙Îď˙Ňň˙ßü˙âţ˙ăü˙Ţ÷üÝöűÝůýŰřţŐő˙Ěđ˙Ľćţ˛ă˙¬Ţ˙ťÔűťÔýśÓü›ŇűťÔýśŃů›ĐřśÓü›Ô˙šŐ˙™Ô˙•Ň˙–Ńý•ĐüšÓţˇŘ˙Şß˙­ß˙±ŕţ¶ă˙»ĺýÄę˙Çë˙Ëî˙Éě˙ÂćüľäűŔćýÂčýÉî˙Íń˙Íń˙ÇěţÂčűĽĺűĽäţľć˙żčţŔéýĹęüÇěţËď˙Ëď˙Ëď˙Ëî˙Îń˙Đń˙Óó˙Őő˙Řô˙ŮôýŮôűĺţ˙č˙˙čý˙ćűţâű˙ÍńýÄëü´âü¬ÝýžÔú¦Ü˙©Ý˙łä˙˝ë˙Ăî˙Ęď˙ĎďüÔńůŮň÷ăřýäůţářţßř˙ÖôţŃńüĘď˙Îď˙ŃńţÚő˙Úő˙Öó˙Đń˙ĚíţŃń˙Őň˙ŃńţŃó˙Őő˙Öö˙Řö˙Ů÷˙×óţÖňţÔđüŇîüŇň˙Äî˙»ç˙¬Ü˙¤Ů˙¤Ú˙źŐ÷ťÓő™Đ÷—Đű—ĐýťÔű¤Řý­Ţ˙˛ŕ˙˝ć˙Âč˙Îď˙Óó˙Üů˙ç˙˙ç˙˙éţ˙ęý˙éţ˙ç˙˙Ýř˙Řö˙Éď˙şč˙˛á˙¦Ü˙Ąß˙ˇŰ˙śŐ˙—ŇüÍ÷›ĐúžÔ˙›Ô˙—Ń˙–Đţ”Ńţ•Ďý”Ďű™ŇýźÖ˙Şß˙­ß˙łâ˙¸ĺ˙ĽćţÄę˙Ćę˙Čě˙Çë˙Ŕćý˝ĺţ˝ĺţľçýÄęýÉîţÍň˙Ĺë˙Ŕé˙·ăüµáţ˛Ţűµßř·áůżčüÄęýČí˙Ęď˙Ěď˙Ěď˙Ěď˙Íî˙ĎńýÓóţ×óţŮôýÜőüč˙˙ę˙˙čý˙ç˙˙ć˙˙Ôö˙Ëđ˙¶äü¬ÝűťÓůŁŰ˙§Ý˙˛ä˙»é˙Ĺî˙ÉîţĐđýŇď÷Řńöćűţéü˙ćţ˙äý˙Ú÷˙ŐóýĘď˙Đń˙Ôô˙Úö˙Řô˙Ńń˙Íî˙ĆéüÍěţĎďţÍń˙Îň˙Ňó˙Őő˙Ů÷˙Úř˙ÚőţŘóţŐđűŃëřŇďýĹî˙Ľč˙®ŕ˙©ß˙©ß˙ĄÚů¦Ůř ÔůťŇú™ĎűźÔü©Ý˙¬Ýţ°ßýÁé˙Âč˙ÍîýŃńüÚ÷ýç˙˙ę˙˙ëţ˙ěţ˙ěţţë˙˙ĺý˙ßú˙Îň˙ľč˙łŕý¦Ü˙§Ţ˙ĄÜ˙˘Ů˙śÖţťŇüźÔţťÓ˙Ńţ”Îü•Ďý‘Îű’Ěú“Îú™Ň˙ ×˙«Ýţ­Ţţ¶ă˙»é˙ĽćţĂé˙ÄčţĹé˙Ĺé˙Ŕĺ˙˝ć˙Ľĺ˙˝ĺ˙ĂéţÉî˙Ęď˙Ĺë˙Ŕę˙¸ĺ˙±ß˙©ŰüŞŰűŻŢú»č˙ÁęţÇěţĘď˙Ďň˙Íđ˙Ęí˙Ěď˙Íń˙Ôô˙Řö˙Ţů˙ŕü˙ăü˙âű˙áúţć˙˙ĺ˙˙Ůú˙Îň˙´ŕű©Úű›Ô˙śŐ˙ ×ţŞÝü˛áűÂí˙Ěó˙Ňô˙ÓđřÖňöç˙˙ę˙˙é˙˙ç˙˙Ú÷ýŐňúÄéűĚď˙Ôô˙Řö˙Őň˙Îď˙Ęí˙ĂçýĆéýËë˙Őö˙Ôő˙Öô˙Řö˙Ú÷˙Ůöü×ôüÖô˙Ňň˙Íî˙Ďđ˙Ćě˙Ľć˙¨Ú˙¬ŕ˙˛ä˙ľě˙Ŕě˙¶ă˙­Ţ˙Ł×˙§Ű˙ŞÚţ°Ţ˙´áţľć˙ĂéţĚíüĎďúŮöúč˙˙í˙˙ň˙˙ň˙˙ô˙ţô˙ţěţ˙çü˙Ôń˙żĺüµßř­Űü¬Ýý¬Ýţ¨ÚűźÔö§Ü˙ĄÚ˙źŐ˙›Ô˙–Đţ”Îü’Ďü“Íű“ÎúŃţźÖ˙¨Űú­Ţţ´áţ¸ć˙˝ç˙Âč˙ÁçţĹé˙Ĺé˙Ăč˙Ľč˙˝ć˙˝ç˙ÁçüĂčűÂćüŔč˙˝ć˙±ß˙®Üţ¦Ü˙¨Ý˙®á˙»é˙ľč˙ÄéüČí˙Ěď˙Čë˙ĹčţÉî˙Ęď˙ĎńýŃńüŘőýÚ÷ýŮőůŮőůŮőůŢű˙ßü˙Ôń˙Ęëţ´á˙ŞÜ˙•Íţ–Đ˙Đ˙ŁŐú©×ř˝ç˙Ćď˙Ďó˙Řö˙Ýř˙ćţ˙ę˙˙č˙˙äý˙ŘőűÓđřĹęüÉî˙Đń˙Őň˙Ńń˙Îń˙Ěđ˙Âę˙Ĺé˙Ëî˙Őń˙ŐđűÚőüŢů˙áý˙Ţű˙Úř˙Ďó˙Čî˙żé˙Âę˙Ĺčű»ăü¨Řü®Ţ˙µă˙Áę˙ĹëţĽć˙´áţ¬Ţ˙­ß˙ŞŰü´á˙şć˙ľć˙ÄčţÎďţŃńüŰřüé˙˙ďţ˙ő˙˙÷˙˙ř˙ü÷˙űń˙˙ěţ˙Űő˙ÇęţŔĺ˙¸âűąăű˝ç˙»ç˙µáţŞŢ˙¦Ű˙ˇ×˙ž×˙–Đţ‘Îű”Ńţ’Ďţ“Íű—ĐýťÔý§Ůú­Ţţłŕý¶äţ˝ç˙Âč˙ÁçţÄę˙Ĺë˙Ĺę˙Ŕé˙Ŕę˙Ŕč˙ÁçţÁçüŔćýŔę˙Ľč˙±Ţ˙­Űý¨Ý˙©Ţţ°ă˙˝ë˙żé˙ÁçúĆëţČí˙ĹčţĂćüČî˙Éđ˙Ëđ˙Íń˙Ôô˙Řö˙ŮöţŰřţÚ÷ýŕý˙ŕ˙˙Đń˙Ăçý­Ý˙¦Ű˙Ň˙—Ń˙™Ń˙ŁŐú¦×ř»ç˙Äď˙Ďó˙Üú˙áü˙ę˙˙ë˙˙č˙˙äý˙ŘőűŇđřĹęüÇěţÍî˙ĎďţÎîýĚď˙Ęî˙Ŕč˙Âç˙Çí˙ŇîüÓîůŢ÷ţĺü˙é˙˙ć˙˙Űů˙Ëđ˙Âë˙µä˙·ä˙·ßů°ŰűˇŇúĄÖţŞŰü¸äýżčţąăüłßüŻÝ˙®Ţ˙®Üţ´á˙şć˙Ăé˙ĆéýĐđýŐóýÝůýě˙˙đţ˙ő˙ţř˙˙ř˙ü÷˙űő˙˙đ˙˙ŕř˙Íî˙ÇęţĆě˙Çí˙Ćď˙Äě˙ąăü˛ä˙«Ý˙źÔüťÔý–Đţ”Ńţ“Ń˙’Đ˙Íü”ÎüŃţŁÔü¨Řţ˛ŕ˙łŕýąćýľçýżčüÁę˙Âë˙Âë˙Ćě˙ĂéţÂčýŔé˙ľč˙ľę˙»é˙ąç˙±ßů®Ýů¨Ů÷´ă˙»é˙ľč˙żç˙ŔćýÂč˙ŔćýŔćýÁć˙Ăî˙Ăî˙Ĺî˙Äí˙Éí˙Îń˙Ńň˙ÖôţŰřţßűüÚůţ¸ĺú«Ýřś×˙•Ó˙ŹĚ˙–Î˙™ÍüˇÓř§Ůúµä˙Ŕę˙Ěď˙Ţů˙âů˙ë˙ţí˙ţë˙˙ĺţ˙Üú˙Ôô˙ÁĺűÉě˙Ëî˙Čë˙ÇęţÉě˙Éî˙Áę˙·ăü»ç˙Íî˙Őň˙çý˙í˙˙îţţíýýŕ÷ýÎń˙Ăí˙ĄŮţźÖ˙—Ń˙–Đ˙•Ďý—Đű—Ńů­ă˙˛ć˙˛â˙°Ţ˙°Ýţ°Ýţ´ß˙»ä˙żç˙ĹęýĚíţÓđřŰôůčýţď˙ţôţýöüü÷ýýř˙ţř˙˙ö˙˙ď˙˙čý˙ÜőüŘóüĎďüĐń˙Ëď˙Ęí˙Čî˙¶č˙­ß˙źÔüžŐţ–Đţ’Ďü‘Ď˙‘Ď˙Íü•ĎýŃţ Ôű¦Řý˛ŕ˙łŕýşçţľçýżčüĹë˙Ćě˙Çí˙Ĺë˙Ĺë˙Äę˙żčţżé˙Ŕě˙ąç˙¶äţ˛áý±ŕţ¬Ű÷¶ă˙»é˙˝ç˙żç˙Ăé˙ĂéţĂçýÄę˙Äę˙ŔéűżčúĂéüÂčűÇě˙Íđ˙Îď˙ŃňűÖôüŮöúŇóú˛ŕř§Řř—Ňţ‘Ď˙ŤĚ˙–Đ˙šĐţźÓú¤Ůűłâ˙Ŕę˙Éě˙Řô˙Ţ÷üë˙ţí˙ţí˙˙ç˙˙Ýú˙Öô˙ÄéüÉí˙Ęî˙Ćę˙ĂçýĹé˙Ćě˙˝ĺţ˛Ţůąĺ˙ČëţÓđţĺý˙ě˙˙đ˙˙ď˙˙âů˙Íđ˙Âę˙¤ŘýžŐţ”Î˙‘Í˙Íú“Îř–Đř§Ţ˙¬ă˙¬ŕ˙«Ý˙«Ű˙¬Úü±Ţ˙ąĺ˙ľč˙Ĺé˙ĘëüŐńüŢ÷ţë˙˙đ˙˙ó˙ýôýüőţýř˙˙ř˙˙ô˙˙ď˙˙éţ˙ŕů˙Ü÷ţŐń˙Öó˙Íî˙ĘëţËđ˙łĺ˙Żá˙§Ü˙˘Ů˙”Îü‘ÎűŹÍţŹÍţ’Ďţ—Ń˙™Ň˙ ŐýĄŮ˙°á˙łâ˙Ľé˙Ŕé˙ĂéţĆě˙Ćě˙Çí˙ĂéţĆě˙Ĺë˙Ŕé˙Âě˙»ç˙¶ă˙´ă˙˛ă˙Żŕţµä˙Âî˙Ćň˙Áę˙ĂéţČí˙Éě˙ÉíýĚđ˙Ęď˙ĹčűŔăöÄčřĘîüÉë÷ÇéőÔô˙ÔőţŐö˙ĎďúĆęúŞÜý Öü’Ň˙ŚĐ˙ŽŃ˙Îý•Îű›Đú Őý¬Ţ˙ąĺ˙Čí˙×ő˙Ű÷űęţýëţüî˙˙ë˙˙âů˙ŰóýČí˙Ăé˙ÁçţŔćýÁçţĽäţ¸áý¬Řő®Üý´â˙ÁĺűĚěűßú˙ĺý˙ěţţî˙˙ćý˙Ďó˙Ăě˙ŞŰűźŐű“Ď˙’Î˙ŽĚýŤËúŤĚř’Ďü–Ńý•Îů•ÎůźÔţĄÖţ«Ű˙µä˙şç˙Ĺë˙ČëţÚö˙äý˙î˙˙đ˙ýň˙˙ó˙˙ó˙˙ô˙˙ô˙˙ń˙˙ď˙˙éü˙âúţÝőůŘň˙Öň˙ĐíýĎî˙Ëî˙Żá˙­ß˙¦Ű˙ˇŘ˙”Îü’ĎüŹÍţŹÍţ“Đ˙—Ń˙—ŇţžŐţ˘×˙­ß˙±ŕţşć˙Ŕé˙ĂéţĹë˙Ĺë˙Ĺë˙Ĺë˙Ćě˙Ĺë˙żç˙»ç˙ąĺ˙·ć˙·ć˙łä˙°á˙łŕýŔě˙Ćđ˙ĂéţÄęýĘîţËďýËďűĎńýÍńýÍî˙ÉčúÍíüÓó˙ÎďřĘëôŮú˙Ůú˙Ůů˙ĐđýÄéü¦Ú˙śÓúŽĐ˙ŠĐ˙ŠĐ˙ŽÍů’Íů™ĎűťŇţ§Ű˙łáűĹěý×ő˙Ůőůčüűëţüń˙˙í˙˙ćű˙ŢőýÉî˙Ŕćý˝ăúľć˙Ŕč˙ąâţ˛Ţű©Ö÷«Ű˙Żß˙żĺúĘëúÜů˙âů˙éýţě˙˙ĺţ˙Đô˙Ĺî˙¬Ýű Ôů’Đ˙Î˙ŤÍýŠĘúČřŤÍűÎýŽËřŹĚůšÓ˙ˇÖţ¨Ú˙˛ă˙ąć˙Ăé˙Čë˙Ű÷˙ĺţ˙î˙˙đ˙ýń˙˙đţţď˙ţđ˙˙đţţîţýěţţęţ˙éţ˙âúüÖńüÔđţŃîţŇń˙Éě˙®ŕ˙¦Řű›Đř›Ňű•Ďý’ĎüŹÍţŽĚý“Đ˙—Ń˙–Ńý ×˙¤Ů˙­ß˙Żŕ˙ąç˙˝çýżčüÄęýÄęýĹë˙Áçţ˝ćüľçýżç˙ąăüąĺ˙şč˙·ć˙˛áý˛áýŔę˙Çí˙Čî˙ÄčřËěűŘö˙Úř˙ŮřýŘ÷üÜű˙Üř˙Ű÷˙Üř˙Ú÷˙ŘőůÚůüŘúüŮů˙Řř˙Ěí˙Áĺ˙˘Öţ–ĚřŚÎţ‰Ď˙†ÍűŹĎű‘Îú•ÎűšĐţˇÖ˙ŻŢüÁęţŇňý×ôúę˙˙í˙˙ő˙˙ő˙˙đ˙˙čů˙Ěíţľçű˝ćüżç˙ľč˙µâ˙´á˙­Ű˙¦Öţ¨Ů˙ľć˙ČíýŮú˙Ţů˙çü˙éţ˙âű˙Ňó˙Čî˙ŻŢřźÔô“Ń˙ŹÍţ‘Đ˙ŠĚ˙„ÇűË˙ŽĐ˙ŽĐ˙ŚÎ˙“Ń˙šÓţ˘Řţ­ß˙łá˙˝ĺţĂčűŮő˙ăü˙đ˙˙ó˙˙î˙˙ěţţë˙ţë˙ţęţýéýţę˙˙ę˙˙ě˙˙çüýÓďúŇň˙Đô˙Ďň˙Çí˙­ß˙§ŮüśŃůšŃú’ĚúÍú‘Ď˙‘Ď˙’Ďţ•Ďý–Ďü ×˙ĄÚ˙­ß˙°á˙·ĺý»ĺűľçýŔé˙Áę˙Âę˙żç˙Ľćţ»ĺý¸âú·áůşäüąăűąăű˝ç˙Ŕę˙Ëđ˙Ňó˙ÍďűÍëőÖóűć˙˙ĺţ˙áűüăýţăýţâű˙âú˙ăü˙äý˙ßűüŢúűŘőůÚř˙Ú÷˙ËęţÄć˙§ŮţžÓűĐţŚĐ˙ŠĐ˙ŹĎýĎű”Îü—ĎţźÔ˙®ß˙Áë˙ĚíüÖôţĺý˙ë˙˙ń˙˙ó˙˙đ˙˙ěű˙Řő˙Čí˙ÂčűżčţŔę˙şć˙´á˙®ÜţŞÚţ­Ý˙ľč˙Ćě˙Óő˙×ő˙ŕůţăü˙Ýř˙Óô˙Îô˙şć˙«Üü–Ó˙“Đý‘Ď˙ŤĚ˙‹Í˙ŤĎ˙ŽĐ˙ŚÎ˙ŽÍ˙–Ô˙ť×˙˘ŘţŞŰü°ßýşäúÁćůŘóţâů˙ď˙˙ń˙ýěţţčýţéţ˙ç˙˙ĺý˙Ţöúßůúč˙˙ç˙˙ăű˙Ő÷˙Íő˙Ĺď˙ľéúµâů®ŕ˙¨ÚýžÓű›Ňű’ĚúŹĚůÎ˙Î˙‘Îý”Îü•ÎűˇÖ˙¦Ú˙®ŕ˙±â˙¸ćţąćýĽćţľč˙ľč˙żé˙żé˙»ĺţąăü¸âúąáúĽäý˝ćüĽĺűżčţĆě˙Őö˙×ô˙ÓńűŐđ÷Ţ÷üç˙˙ç˙˙çüýćţţĺýýâúţâů˙äű˙ĺý˙ăü˙ßűţŮöúŮ÷˙Úř˙ĎěüÉéţ¬ÚűŁŐú‘ĐüŤĎ˙‹Ď˙ŹĎý‘Đü“Îú”Ďű›ŃýŞŰüĽć˙Ęí˙Óó˙Ţ÷üçü˙í˙˙ń˙˙îţţěűţÜř˙Íî˙ĆéüÂčýŔę˙ľę˙¸ĺ˙°Ţ˙®Üţ±ß˙Ŕę˙Äí˙Îň˙ÓóţŢů˙áý˙Üů˙Ňó˙Ďô˙Áë˙µä˙šŐ˙–Ńý‘ĎţŹÎ˙‘Đ˙ŹÎ˙ŹÎ˙ŽÎţ‘Ďţš×˙ťÔűˇŐú§Řř¬Ű÷şăůÄçűŮô˙ăú˙ď˙˙ń˙ýí˙˙çüýčýţč˙˙äü˙ÜőúŰ÷úăü˙äý˙áú˙Őů˙Ěö˙Ŕëű·ä÷°Ţő¨ÚýĄ×úžÓűśÓü–Đţ–Ó˙Î˙Î˙‘Îý”Îü•ÎűĄÖţ©Ű˙Żŕ˙łâ˙¸ć˙»ç˙ąĺţ¶âűµăýµăý·ĺ˙µáüµáúĽćţĂé˙ĂéţČëţÇęýËěýŇň˙Üř˙ßř˙âů˙čý˙ęţ˙íýýď˙ţîţýď˙ţě˙ýéýüčýţéţ˙ç˙˙ářţŢ÷ţÜ÷˙Ţů˙ŕű˙ÚőţŇđűŔé˙˛ßü—Î÷ŹĚűŹÎ˙‘Ď˙“Đ˙—ŇţÓýźÖý¨Řü·ŕţĚđ˙Ôő˙Űöýăú˙ë˙˙í˙˙í˙˙í˙˙äü˙ÓńüÎîűĂćůżĺřĆđ˙Ĺď˙˝é˙·ăü¶âűµáú»ĺýČď˙Ńň˙Ű÷˙Üů˙Úö˙Îď˙Ęí˙Ŕč˙¶ă˙ˇŰ˙žŘţšŐ˙•Ď˙“Đ˙‘Îý•Ď˙ŃţšÓţ Őý˘Öű¬Ţ˙´ă˙·ĺ˙ĂéţĎđ˙Ţů˙ćý˙ď˙˙đţţí˙˙ë˙˙ę˙˙âű˙Ţů˙×ôü×ôüÚ÷˙Ýř˙Űö˙Ďó˙Çđ˙żęý¸ĺú°Ţö¨Úý¤ÖůťŇú›Ňű—Ń˙Ő˙Î˙Î˙’Ďţ•Ďý—Đý¤Öű©Ůý±ß˙łâţ¸ć˙»ç˙¸äý˛ŕú˛ŕúłŕý˛ßü´ŕűµáúĽćţÇí˙Éî˙Îď˙ĎďţÓđţ×ó˙áú˙ĺü˙éţ˙î˙˙î˙˙ń˙˙ó˙˙ň˙˙ň˙˙ň˙˙ë˙ýé˙ýéţ˙ćţ˙ßöţÜňýŢö˙Ü÷˙ŕű˙Ţů˙ŘőýËđ˙ĽćţśŃů“ÍűÍ˙’Î˙•Ď˙—ŇţšŐý˘Ú˙¬Ü˙¸á˙Ęî˙Đń˙Ůöţáú˙éţ˙ě˙˙î˙˙í˙˙ć˙˙×óţŐóţĹéůÂçůÇđ˙Ćđ˙Ŕę˙»ĺű¸âř±Ýř´ŕůĹëţĚđ˙×ő˙Ůő˙Ů÷˙Ďđ˙Ęí˙Ŕĺ˙´ŕý˘Ú˙ ŘýśŐ˙–Îý•Ďý—Ďţ™Ń˙ Ő˙ˇÖ˙Ł×ü§Ůú±â˙µăý¶âűŔćűÍî˙Ýř˙ĺü˙đ˙˙ň˙˙ěţţë˙˙ćţ˙ÝůýÜ÷˙ÖôţÖôţŮő˙Ű÷˙Úő˙Îń˙Çí˙Ŕé˙˝ç˙˛Ţůşç˙łâ˙§Ůü Ôű›Ô˙žŘ˙’Î˙’Î˙–Đ˙šŇ˙ťÓ˙ĄŐű¨Řü®ß˙˛á˙¶ĺ˙¶ĺ˙´áţŻŢü°ßý±â˙°ßű»é˙Ľč˙ĂéţŃô˙Ř÷˙Úö˙Ű÷˙Ţů˙ß÷˙éţ˙ęţ˙ëý˙íýýďýţô˙˙ö˙˙ő˙ţôţ˙÷˙˙ň˙ýď˙ýď˙˙í˙˙ăů˙ŕö˙Ýő˙ÔďřŮôűä˙˙ŕý˙Ôö˙Ęđ˙¬Ţ˙žÔ˙ŹĚ˙Í˙‘Í˙’Ďű•ÓüźŮţ¨Ú˙°Űýżç˙ĹęýÖö˙Ůöţáú˙ĺý˙ę˙˙ę˙˙âű˙ŮôýÚö˙ÍíúČéřĚď˙Ěń˙ĂéüÁęüÂëý±Ýö˛Ţů»äúÂčűĐń˙ŐóţÚö˙Ňň˙Íî˙˝âü°Ü÷ˇ×űźŐűˇÖţ Ő˙ˇÖ˙¤Ř˙¤Őý¨ŘüŞŰü°ßýµâ˙˝é˙ľč˙Ŕé˙Îň˙Őő˙ĺü˙ëţ˙đ˙˙ń˙˙ď˙˙áůűŢőűŰö˙×ó˙×ő˙×ő˙Řů˙×÷˙Öó˙ÇęţľâúĽâůÂç˙żç˙Íň˙Çí˙łÜř«Řů¤Ő˙˘Ő˙šĎ˙›Đ˙śÔ˙žÔ˙ťŇţŁÔüĄÖţ©Űţ¬Ýţ°á˙±â˙łá˙¬Ýţ«Ű˙°Ţ˙łŕýŔę˙Ĺî˙Íń˙ÔňýÜř˙ÜôţŢ÷ţäý˙äý˙çü˙ëý˙ěţ˙đ˙˙ň˙˙ő˙˙ő˙˙ö˙˙ö˙˙őý˙ö˙ţň˙üđ˙˙ď˙˙çű˙ář˙ÖńüĎëöĐîöÚű˙ŕ˙˙×ő˙Ęď˙¬Ţ˙ťÖ˙ŽÍ˙ŽÍ˙ŹÍ˙ŹÍüĎűťŘ˙Ł×ţ­Űý¸äýŔę˙Íó˙Ő÷˙ßü˙âý˙çţ˙ç˙˙ŢúţÝú˙Ýú˙×ő˙ÓńüÍíüËěýĂčűÄí˙Ŕëţ¶ŕöµß÷µâů»ĺýĚń˙Öř˙ÚőüŮöţŐő˙Ľĺű­Űőˇ×ýŁŮ˙Ł×ü¨Úý¬Ýţ˛á˙¶ă˙˛ŕú°ŢřµáúÁçţÄę˙Ęđ˙Íň˙Őóýßú˙ęüţđţ˙ň˙˙ń˙˙ćţţŰöýÖđýÓî˙Őđ˙×őýŮřűŘűýÓő˙Íń˙˝ăú»äúŔćűÂčűČíýŮ÷˙ŇňýÉě˙Čî˙ąä˙˛Ţ˙©Ú˙¦×˙˘Öţ˘Öţ˘Öţ ŐýźÔüˇŐüŁ×ü¦Űű­ß˙®ß˙§×ű§×ű˛ŕ˙Ľč˙Čń˙Đő˙×÷˙Ü÷˙ŕůţŕřüâúţé˙˙č˙˙čý˙ęţ˙ęţ˙í˙˙ď˙˙ňţţó˙˙ő˙˙÷˙˙÷˙˙÷˙ýő˙úô˙˙ó˙˙ěý˙éü˙ÜóűÓîőÔďřÚ÷ýÜů˙ÔňúÉíýŞÜý›ŐýŠÉü†Čü‹Ę˙‘Ď˙ŹÍü“ĐüžŐţ˘Öű­ÜúłáűżęýÇî˙Ňô˙Őő˙Řô˙Ůô˙Úř˙Ú÷ýÜů˙áü˙áü˙Ů÷˙ŇňýÂćöĂěţĂî˙ľč˙·ŕü±Ţű¸ĺ˙Čń˙Ďň˙Ţů˙ÖňţÎí˙»ĺţ˛á˙¬Ţ˙®ŕ˙±ß˙ąĺ˙ľč˙Äí˙Ĺî˙Ăě˙Âë˙ÂčűČéüĘí˙Đó˙Őö˙Ýú˙ĺý˙ďýýó˙ýô˙˙î˙˙äţűŘőýÓî˙Đę˙Đě˙Ů÷˙ÚůüŘüüĎó˙Ëî˙ĆëţÇěţÍń˙Ňô˙Űů˙ßü˙Úř˙ĐňţÎň˙Ćď˙Áí˙´â˙­Ţ˙¦Řű¤Öű˘ÖýźÔţžÓýžÓűźŐű¤ŮűŞÜ˙ŞÜý¤Ôř§Őů´á˙żé˙Ěň˙Ň÷˙Űů˙ßř˙äü˙ăű˙äüţç˙˙ć˙˙éţ˙ęţ˙ë˙˙í˙˙ď˙˙đţţňţţő˙˙÷˙˙÷˙˙ö˙üö˙üö˙˙ö˙˙đ˙˙ěţ˙čű˙ŕ÷ýŕ÷ýâű˙ăü˙×őýÉíý¨Úű™ÓűŠÉü†Čü‹Ę˙‘Ď˙Îý“ĐýśŐ˙ Őý¨Ůú®ÝűąćýżčüÉîţÍń˙ĐđýŇďý×ő˙Ú÷˙Ýú˙ä˙˙ä˙˙Üů˙ÖôţĂç÷Ĺë˙Ăě˙Ľĺ˙´ß˙±Ţ˙¶ă˙Ăë˙Ęî˙Ú÷˙Ôń˙Čë˙¸ä˙˛á˙°á˙łá˙µâ˙żé˙Äí˙Éď˙Ęď˙Ëđ˙Ęď˙ÇëűËěýÍî˙Đô˙Ő÷˙Ţúţéţ˙ń˙˙ô˙ţň˙˙í˙˙ć˙ýÚ÷˙Őń˙Đę˙Ďë˙×ő˙Ř÷üŮűýÓő˙Îń˙Ďđ˙Đń˙Ôô˙Ů÷˙ŕű˙áůýäý˙ä˙˙ßţ˙Öř˙Óů˙Ĺđ˙ľéü°Ţö¬Ůř©ÚűžÔ˙›Ńý—Đű™Óű ×ţ ÖüˇŐú¦Ôö«Řůşă˙ÁçüÎň˙Öř˙Ýú˙âúüäůúćűüčýţç˙˙ç˙˙ćţţéţ˙ę˙˙ě˙˙î˙˙ď˙ţń˙˙ô˙ţő˙ţôţýö˙üö˙ü÷˙˙÷˙˙ö˙˙ö˙˙ő˙˙ň˙˙ń˙˙îţýęţ˙Üú˙Ěď˙§Ůú›ŇűŽÍ˙ŚË˙ŚĘýŹÍţŹÍţ“Ń˙”Ń˙™Ň˙žÓýˇŐüŞŰűŻŢúąăü˝ĺţĂéţÇë˙Ńî˙Ůő˙Ţú˙ä˙˙âţ˙Úřú×öűÉíűÄę˙żä˙ŻÚý®Ú˙˛ŕ˙˛ŕ˙¶â˙˝ĺ˙Çë˙Ĺé˙˝ä˙´á˙±ß˙·ăüĽć˙żčţČí˙ĚđţÓó˙Őő˙×ř˙Ö÷˙Ôőţ×ő˙Ôô˙Ôö˙Öö˙Üřüę˙˙đ˙ýň˙üđ˙˙ę˙˙č˙˙Ýú˙Řô˙Ńí˙Đí˙Ôô˙Őö˙×ř˙Ňô˙Ďđ˙ĐíűŇîůŮôűŢ÷ţčý˙éý˙ćű˙ŕřüßůúÚůű×ůűÎóűČîű˝ćüşáţµâ˙ž×˙™Ňý‘Îú’ĎűÓ˙žŐţźŐű­Űýµŕ˙żç˙ĆęúÖ÷˙Ţü˙ç˙˙ę˙˙čüűę˙ţę˙ţćţţäţýâüýăýţĺý˙éţ˙ę˙˙ëýýëţüń˙ýň˙ţő˙ýő˙ţ÷˙˙÷˙˙řţţřţţů˙˙ű˙˙ů˙˙ů˙˙÷˙ţń˙˙Öö˙Ëđ˙­ß˙ˇŘ˙‘Ď˙ŽÍ˙ŽĚ˙’Đ˙ŹĎ˙ŹĎ˙ŹÍ˙”Đ˙™Ó˙›Ô˙ Őý¦Ú˙­Űý­Üúłŕý¸ä˙Ëë˙Ňď˙Řô˙Ţű˙ŕü˙ÜúüŮřýËďýÄé˙Ľă˙˛Ţ˙«Ůý¬Úü±Ţ˙µáţ¶âý¶âű±Ýú°Ýü˛ă˙łâ˙ĂéţÇí˙Ěđ˙Ňň˙ÖôţÜů˙ŕý˙Ýú˙Ú÷ýŰřţÖôüÓôýÓôýÖôüÜőůčýţí˙ţî˙˙ě˙˙ć˙˙ă˙˙Ú÷ýÔňüÍěţĚë˙ĚěűÍíúŃńüŃń˙Đď˙Řő˙Ůő˙ÚőţÝöýŕ÷ýáőţáőţßöüŢ÷űŰ÷úŮöúÔőüĎńýĹé˙Áć˙˝ć˙ˇŘ˙—Đű‘ÎúŹĚůš×˙™ŇýźÔüŻÜý·â˙Éď˙ĘëüŮú˙ßţ˙č˙˙čýţęţýę˙ţę˙ţĺýýâüýÜřűßűţăýţç˙˙ę˙˙ęţýí˙ţń˙˙đ˙ýń˙ýôţ˙ôţ˙÷˙˙ú˙˙ü˙˙ü˙˙ü˙ýű˙ýű˙ýőţůđţţĎďüŔĺř¨Úű ×˙Î˙Í˙ŹÍ˙ŽÍ˙ŽÍ˙ŤĚ˙ŽĚ˙‘Ď˙šÔ˙śÔ˙ťÓ˙źÔţĄ×ü«Üý°Ţ˙´á˙Áĺ˙Ěë˙Ňň˙Űú˙ÜůýŘ÷úÓôűÉíýÁć˙şá˙ŻÝ˙­Ý˙°ßý˛ßüłáűłáű°Ţř®Ýů°ßý´ĺ˙¸ç˙Äę˙Éî˙Ëď˙Ôô˙Úř˙Ü÷ţŢů˙ŢúţÝůýÜůýŮřýŐö˙Ôőţ×őýÝöűçü˙î˙˙í˙˙é˙˙âţ˙ŰůűÚř˙×ő˙ĚíţËě˙ĘëţÍî˙Ôő˙×÷˙×ö˙Úú˙Űů˙Úř˙Ůő˙ÜôţÜó˙Ýő˙Ţö˙Ţö˙Ţ÷ţÜ÷ţŰ÷˙Ű÷˙Őô˙Đđ˙Ęď˙®ŕ˙˘Řţ–ŃýÍú”Ň˙–Ńý™Đů°Ýţ˝ć˙Íđ˙Ďđ˙Űů˙Ýú˙äý˙çüýéţ˙éţ˙ç˙˙áý˙ßűţŰřţŰřţŰřüáúţâű˙ćűţčýţě˙ţí˙ţí˙ţń˙˙ó˙˙ő˙˙÷˙˙ű˙ţű˙ţű˙üű˙ýř˙ţô˙űîţýÓô˙ĆëţŞÜ˙ ×˙“Ď˙Í˙‘Ď˙ŚË˙‹Ę˙ŚÎ˙ŹÎ˙’Î˙–Đ˙—Ń˙™Ň˙žÔ˙Ł×˙¦Ú˙ŞÜý¬Ţ˙¸áýÂćţÇě˙Đô˙Ňô˙Ďó˙Ěń˙Ăě˙»ć˙·ă˙˛ă˙˛ă˙·ä˙¸äý·ĺü¶ćý¬âţŞßţ«ŕ˙´ĺ˙ąç˙ÁçţÄę˙Ëî˙ŃńţÓńü×ôüŮöţÚ÷ýÚ÷ýŰřţŘöţÔőţÓóţÖô˙Úőţářţë˙˙ę˙˙ßü˙ÓőţŐö˙Ňň˙Ňó˙Íň˙Éí˙Ĺé˙Ćę˙Ěď˙Ńň˙Ňň˙Ďó˙Îň˙Óô˙Ňó˙Ôń˙ŐńýÖňţÚő˙Űö˙Ţö˙Ţö˙Ü÷˙Üř˙Ůö˙Ňń˙Ěđ˙±â˙¨ÚýŃü”Îü“Ń˙Ň˙šŃú°ÝţĽĺ˙Éě˙Ďđ˙Ű÷˙Üů˙ĺţ˙ę˙˙éţ˙ç˙˙ĺţ˙ßü˙ÝúţÚ÷˙ŮöţŮöüÜřüßřýâúţćűţë˙ţěţţě˙ýđ˙˙ń˙˙ô˙˙ő˙˙ů˙˙ů˙ýů˙űř˙ţö˙ýđ˙üěţţ×ř˙Éď˙©ŰţťÔýĚţÍ˙‘Ď˙ŠÉţ‡ÉýŠĚ˙ŽÎţ’Î˙”Îţ•Ď˙™Ň˙źŐ˙Ł×˙¦Ú˙¨ÚýŞÜý¶âýľć˙Âë˙Ęđ˙Ęď˙Čí˙Ĺëţ˝ç˙µâ˙łá˙±á˙˛ă˙¸ä˙şäý¸ĺü¶ĺ˙¬ă˙¨Ţ˙©ŕ˙˛ă˙¸ĺ˙ľć˙Áę˙Ęď˙Ďđ˙ĐđýÔňü×óţ×ôü×őýŘöţÖôüŇôţŇň˙Óó˙×óţßř˙é˙˙ć˙˙×ř˙ËďűÎđüÎďţÍń˙Čî˙Äę˙Ŕč˙Ăé˙Čě˙Ďđ˙ĐđýÍń˙Ëđ˙Ďó˙Ńň˙Đđ˙ŃóýŃóýŐő˙Ů÷˙Ű÷˙Ü÷˙Ýř˙Ţů˙Ýú˙×ôüŃó˙·ăţ¬ŰůšĎ÷•Đü”Ň˙šÔ˙źŐ˙µâ˙Ŕé˙Ěď˙Ňó˙Ű÷˙Úö˙ŕů˙ăű˙ĺý˙âű˙Ţů˙Ů÷˙Řö˙ŐóţÖô˙×ő˙ŮöţŰö˙Ţ÷üáůýéţ˙ëţ˙ěţ˙í˙˙î˙˙đ˙˙ń˙˙ôţýőţýô˙űň˙˙ń˙˙ë˙ţç˙˙Ďó˙Âčý§×űźÔţ–Đ˙Ě˙ŽĘţŠÇý†Čü‡ÉýŽĚű–Đţ–Đţ–ĐţžÔ˙ Ő˙Ł×˙ĄŮţĄÚú©Üű°âýµăýąĺ˙żč˙ľč˙şă˙·ă˙˛ßţ©Űü©Űţ¬Ü˙°Ý˙¸á˙şáţąâţµä˙¨ŕ˙ Ú˙ˇŮţ­Űý°Ýü·ă˙»ä˙Âę˙Ęď˙Ěď˙ĎďţĐđ˙ĐđýŃńţÓó˙Őő˙Óô˙Óô˙Óô˙Řô˙Űö˙áü˙Üř˙ÉďüÁçúÂĺůČí˙Çí˙˝çýşć˙ąĺ˙şă˙żčţĚđţĎńűÍń˙Ëď˙Ďđ˙Đń˙Ďî˙ŃöţŇ÷˙Ôö˙Őő˙Řô˙Řô˙Ü÷˙Ţů˙ßű˙ÚřúŐöýľč˙°Ýú™Îö•Îů’Đ˙—Ô˙ Ö˙´á˙˝ć˙Éě˙Ďđ˙Ůő˙Řô˙Ţ÷ţŕ÷ýářţŢ÷ţÚőüŐóýÔňüĐđýŐň˙×ő˙Űř˙Ü÷˙Ýöűŕůýç˙˙ę˙˙ë˙˙ě˙˙ě˙˙đ˙˙ń˙˙ôţýôţýňţüń˙˙î˙˙ę˙˙ć˙˙Ěđ˙˝ăř¦Öú Ő˙™Ó˙ŹË˙‹ÇűŚÉ˙ŠĚ˙‰Ë˙ŹÎú™Ň˙™Ň˙ŃţžÔ˙ Ő˙Ł×˙ĄŮţ§Ůú©Üű©Ü÷­ßú˛áýşć˙şĺ˙´ß˙˛ß˙­Űý˘×ůŁŘú¦×˙«Ř˙µŢţ·Ţý·ŕ˙łá˙¤Ű˙›Ô˙śÓü§ŐůŞÖů˛ßţµáţĽäţĆę˙Ëî˙Îď˙Ďđ˙ÎďţÎďţŃň˙Ňô˙Ńň˙Ďň˙Ńň˙Öń˙Ůó˙Ţř˙ŐóţÂéř˝ćúľâřÂćüÂč˙˝çýşć˙µâ˙µáţĽĺűËďýĎńűÎđüËěűÍíüĐđ˙Óđ˙ĚíţĎđ˙Ňó˙Đń˙Ęí˙ĘîţĐń˙Őő˙Űů˙Ú÷˙Ů÷˙Ĺë˙łßřžÓőŇřŹŇý”Ô˙—Ö˙©Ţţ±â˙ľč˙Âë˙Îń˙Őö˙Űů˙ŰöýÝő˙ÓďúŃďúËďýÉîţÍđ˙Đń˙Ňó˙Ůő˙Ü÷˙Ýöýâů˙ë˙˙ëţ˙ě˙˙ě˙˙ě˙˙í˙˙í˙˙ď˙˙đţţďýýń˙˙ň˙˙ďýýéýţĐń˙żĺúĄ×úˇŘ˙–Ô˙ŤËţŠČűÇúŠÉţŽĐ˙’Đ˙–Ó˙—Ô˙Ő˙ś×˙›Őű¤Úţ¨Ý˙­Ţ˙¬Ýţ§Ű˙ĄŮ˙ĄŮ˙ŞÜ˙ŞÜ˙ŞÚţ¨Ú˙˘ÖýťŇúšĎů™Ňý™Ňý˘Öý©Ű˙§Ű˙¤Ů˙Ő˙”Ń˙–ĐţźÔ˙˘Ő˙¦×˙¨Řü±Ţýżé˙Âë˙Ěń˙Íń˙ÎďţÎđüĎđ˙Îď˙Ěď˙Ěđ˙Îď˙ĐíűÖô˙Đđ˙Čë˙´áţ­Ţ˙ŻÜű·ă˙¸ä˙µăý¶ă˙°Ýú°Ţř·ăüşçţ˝çýÄçűÇçüÎď˙Îď˙Îď˙ÂäýÁĺýÁçţÂç˙ľć˙˝ĺţşăůÁçüĐó˙Ńň˙Ěď˙ľç˙±ŢýˇŐúźÖý™×˙—ŐţšŐýĄÚü¬Ýýµâ˙Ŕę˙Ĺë˙Čí˙Ňň˙Ůő˙ÓďűĎěúËěűĹęýÁçüÄéüÎď˙Óó˙Úö˙Úőţářţćű˙ě˙˙ěţ˙í˙˙ě˙˙ě˙˙í˙˙í˙˙ď˙˙ď˙˙đ˙˙ň˙˙ó˙˙ń˙˙í˙˙Ýű˙Ěń˙¦×ř›Ňů’Đ˙Î˙ŽĚ˙ŠÉţŠÉţ‰Ë˙ŤĚ˙Î˙ÎýĎú•Đř›ŐűŁŮý§Üţ®Ţ˙°Ţ˙§Ű˙ Ő˙źÔüŁ×üĄŮţ«ß˙ŞŢ˙ŁŘ˙śŇţšĐţ“Đý’ĎűŇúžÓűźÖ˙śŐ˙š×˙–Ó˙™Ň˙śŃűžŇú§×˙ŞÚ˙łŕ˙Ŕč˙Âč˙ÇěţĘí˙Ěđ˙Ëď˙ÇęýČë˙Éě˙Ęď˙Ěď˙ĎńýŃńţĚí˙Äč˙®ÜţŁŮ˙¦Řű­Űý®ß˙łá˙˛ŕ˙±ŕţŻŢü±ŕü˛áýµä˙˝ć˙»ĺţľč˙ľč˙»ĺţşßú·ßů¸áý»ä˙ąĺ˙¸ä˙°ÜőµßřĂě˙Çí˙Äé˙¶ă˙®Üţ˘Öý Őýť×˙žŘ˙ŁŘ˙ŞÜ˙­Ţ˙˛ßüąĺţżčţĹë˙Đń˙Řô˙Öň˙ÎîýĘëüÂčýľçýĹčűĎďüÖô˙Ü÷˙Ţ÷ţĺú˙čű˙í˙˙ěţ˙ěţ˙ěţţë˙ţěţţěţţîţţîţţđ˙˙ň˙˙ó˙˙ň˙˙î˙˙Ýů˙Íđ˙©ÚúźŐű“Đ˙‘Ď˙Î˙ŚË˙‰Ë˙ĘţŤĚ˙Î˙Îý‘Đü—Ňü›ŐýŁŮ˙©Ű˙°Ţ˙±Ý˙©Ý˙ ŐýźÓúŁ×üĄÚü¦Ú˙¦Ú˙ ×ţ›Ô˙›Ô˙‘ÎűÍú’Ěô—ĚôĎö—Î÷›Ö˙šŐ˙ťÓ˙źÓúˇŇú«ŮýŻŰ˙µáţÂç˙ÁçţĆëţČë˙Ęí˙Ęí˙Ĺé˙ĹčţĹé˙Čě˙Éî˙ÎďţĎđ˙Éě˙ÁçţŞŰü ŐýˇŐú¦Řű©ŰţŻß˙­Ţ˙Żŕ˙­ŢţŻŕ˙Żŕ˙˛ŕ˙¶ĺ˙łâ˙´ă˙¶ĺ˙±ŕţ¬Úü¬Úü¬Ü˙­Ý˙«Ý˙ŞÜ˙¤ÖůŁŐř¨Ůú¬Ýţ¬Ü˙ŁÖ˙˘Ő˙ĄÖ˙¦×˙ŞÚţ˛ŕ˙µá˙·ä˙´á˙ŻÜű­Ůö»ăýÄę˙Íđ˙Đđ˙×ô˙Ěí˙Äçűľäűżç˙Ďďü×ôüÜ÷ţĺý˙éţ˙ěţ˙ěţ˙ď˙˙ď˙˙îţţěţţěţţěţţěţţîţţîţţď˙˙đ˙˙ď˙˙đ˙˙ď˙˙ĺý˙Ôô˙µâ˙©Ý˙‘ÎűŹÍţŹÍ˙‹Í˙‹Í˙‰Ë˙‹ĘýŹÍţ‘Ďţ”Ó˙ś×˙ Ö˙ĄŮ˙©Ú˙ŻÜ˙±Ý˙ŞÚ˙Ą×ü¤Öů¨Úű©Űţ¨Úý¦Ú˙žŐüŃü™Ô˙žŰ˙ťÚ˙źÖ˙ ÖüˇŐúˇ×ýźÖýŁŰţ§Üţ˛á˙µáţĽă˙żä˙Áĺ˙Çë˙Çę˙Éě˙Ĺé˙Ćę˙Ćě˙Áé˙Ŕĺ˙ľć˙ľč˙Ŕé˙ĹëţÉî˙Ăé˙şäýŁ×ü™ŇýšŃú›ŇűťÔý˘×˙˘×˙˘Řţ˘Öý¨Ü˙ĄŮţĄ×üŁŰ˙žŘýźŮ˙źŮ˙śÖü Ň÷ŁŐú¦Ú˙§Ű˙¦Ű˙¦Ű˙ ŐýźÔüźŐűˇ×ý˘×˙ťÓ˙źŐ˙¨Ů˙¬Ü˙´á˙˝ć˙ľç˙»ç˙¸ä˙´ŕý¬ŘóąáűÂč˙Ęí˙Íî˙Đď˙ĘëţÄçűŔćýÁé˙ĐđűŰ÷űâű˙ę˙˙ë˙˙î˙˙ď˙˙đţ˙đţ˙ďýţě˙ýě˙ýěţţěţţěţţěţţěţ˙í˙˙ěţ˙í˙˙î˙˙ćý˙Řő˙¶ă˙¨Ý˙‘ÎűŹÍţŽÍ˙‹Í˙ŠË˙Ë˙‹ĘýŹÍü‘Ďţ“Ňţś×˙ˇ×˙¦Ú˙ŞŰ˙°Ü˙±Ű˙­Ű˙ŞŰü«Üý®ß˙®ß˙¬Ţ˙Şß˙ ×ţŃü™Ô˙—Ô˙—Ô˙śÓúžŇ÷ ŇőźÔö¤Úţ©Ţţ°á˙»ç˙żé˙Čę˙Çé˙ÇęţĚď˙Ěď˙Ęí˙Çě˙Çí˙Äě˙˝ç˙˝ĺ˙»ĺţąĺţşć˙żčţĹë˙ľć˙¶â˙ˇŐü–Ńý•Îű–Ďü–ĎüšĐüťÓ˙źÖ˙źÔţŁŘ˙ Öü Ôűť×ýšÖű›Öţ™Ôü–ŃůźÔţźÔţ ×˙ˇŘ˙źŐ˙ťÓ˙šÓ˙™Ň˙—Ń˙‘Îý’Ďţš×˙ˇŰ˙«Ý˙´á˙ŔćýĆëţĆëţŔćűĽĺůşäüľč˙Ŕé˙Ĺë˙Ěď˙Íî˙Îí˙Íî˙Ęí˙Čě˙Ęî˙Öôüáúţĺ˙˙ë˙˙ěţţď˙ţď˙ţđţ˙ďýţîý˙ěţţë˙ţęţýë˙˙ë˙˙ę˙˙ë˙˙ë˙˙čý˙čü˙ë˙˙ŕů˙×ô˙ąć˙¦Ú˙‘ÎűŹÍ˙ŽÍ˙‰Ę˙†Éţ‰Ě˙ŚÎ˙Îý—Ő˙™×˙›Ô˙˘Ř˙ŞŰ˙­Ý˙®ÚýłŢ˙µŕ˙·ă˙ąĺ˙şć˙şć˙´áţłâ˙®ŕ˙ŁŮ˙ťÔű™ÓűźÖý­ß˙łá˙±ŕü°ßű˛ă˙¶ĺ˙»č˙Ęđ˙Îó˙Ôô˙Öô˙×ő˙Ôô˙ŇôţĘđýËđ˙Äî˙˝ę˙´âü´ŕý±ŕţ®ßý®ßý±Ţű¸ä˙łŕýŻÝţžŐţ’ĎüŹËý‘Í˙‘Í˙ŹĚű‘Îý›Ő˙śŐ˙śŐ˙ťÔýźŐ˙ś×˙ś×˙šŐý™ÔüšŐý Őý Őý˘Ů˙¤Ů˙ˇŘ˙ Ö˙™Ň˙—Ňţ•Ň˙Î˙’Đ˙™Ö˙žŮ˙©ŰüłŕýĂéţÇëűČěüĹęüĂęűÂë˙Áę˙Ćę˙Éî˙Ńň˙Đđ˙Ńń˙Đď˙Îď˙Ëî˙Ěď˙Űř˙ăü˙ć˙˙ę˙˙ęţ˙đ˙˙đ˙˙đ˙˙ń˙˙đ˙˙ě˙˙ě˙˙ě˙˙í˙˙ë˙˙č˙˙ćý˙ăü˙áú˙áů˙ăü˙ÜőüÓó˙»č˙©Ý˙”Ń˙ŹÍ˙ŽÍ˙‡Čţ…Čý†ÉţŚÎ˙Îý–Ô˙Ö˙›Ô˙žÔ˙¨Ů˙ŻÝ˙±Üü¶ß˙»ä˙ľć˙żç˙żç˙ľč˙şć˙ąç˙łä˙«Ý˙¦Ú˙˘Řü¦Űý¶ĺ˙şç˙»ç˙ąĺţ¸ć˙ąçţżęýĚń˙Ňô˙Ů÷˙ŘöţŮ÷˙Ö÷ţÓőţĎő˙Íô˙Ăí˙»é˙˛áű±Ţý®ß˙¬Ţ˙­ß˙°ßý´ă˙°ßý«ÜýťÔý‘ĎţŽĚ˙Î˙ŹÍ˙ŹÍţ‘Í˙–Đ˙–Đţ—Đý—ĐűšĐüśÖţśÖţ›Őý™ÓűśÓü©Űţ©Űţ¬Ţ˙­ß˙ŞŢ˙©Ý˙žŐţšÓţ•Ň˙Î˙‘Ď˙ÓýśÖţ§Ůúłâ˙Ćď˙Îó˙Đô˙Ěň˙ËńţĚń˙Ěđ˙Ńń˙Ôô˙Ůö˙Úö˙Ű÷˙Ůő˙×ő˙Öô˙Řő˙Řô˙Ţů˙áý˙ç˙˙éţ˙ě˙˙ě˙˙ě˙˙í˙˙ě˙˙ę˙˙ę˙˙é˙˙ę˙˙äý˙ŕű˙×ôüŃďúÔňýÖó˙ŐóţÓďűĘí˙µć˙¤Ü˙’Đ˙ŠÉüŠÉţ‡Ę˙‡Ę˙‰Ě˙ŚÎ˙Î˙”Ň˙–Ó˙šÓ˙ťÔý§Ůü°ßý¸âű˝ĺţĂé˙ÄčţĆéýĆéüĆéüĆëţĹęý˝ćüµáü´ŕű¶äţşć˙Äí˙Éî˙Éî˙Çí˙Ĺî˙Ĺî˙Ęď˙Ôô˙Řö˙Ú÷ýÚ÷ýŘ÷üÓôűĐňűĘń˙Ăěţµáú®Ý÷¦×÷ĄÖ÷Ł×ü˘Ú˙ŁŰ˙¦Űý¨Úű§ŮüŁ×ü™Ň˙ŹÎ˙‹Í˙‹Í˙‹Í˙ŽÍ˙Î˙”Ń˙•Ň˙™Ô˙šÓţśŐ˙ťÔýťÔűźÔüžÓűŁ×ţ®ß˙®ß˙°á˙±â˙Żŕ˙®Ţ˙¤Ř˙ Őý—ŇţÍü‘Îý™ŇýźÖ˙©Űţłá˙Áë˙Ëń˙Íň˙Ëđ˙Ęď˙ĚđţĐňţÖô˙Řö˙Ű÷˙Ýř˙Ü÷˙Ü÷˙Ú÷˙ŮöţŰ÷˙Řô˙Űř˙ßú˙äý˙ćţ˙ę˙˙ę˙˙ę˙˙ë˙˙ę˙˙é˙˙č˙˙č˙˙č˙˙ŕű˙Ýú˙ŃďúËëřĎďüÓô˙Óő˙ĚěůÄéü­ß˙ť×ýŹĎ˙Ęţ‡Éý‡Ę˙‰Ě˙‹Î˙ŚÎ˙Đ˙“Ń˙•Ň˙šÓţžŐü¨ŮúŻŢúşäúżčüČë˙ČëţËěýÍî˙ÎďţĎđ˙Íî˙ĹęýżĺüľăýĽçúŔéűÉîţÎďţĎđ˙Íń˙Ęđ˙Ęď˙Ěď˙Öó˙×ő˙ŘöţŘöţ×őýŃńüÎđüĆíţŔé˙˛ßü­Üú§Řů¤Öů Öüť×ýźŮ˙ŁŰ˙˘Řü˘Öű Öü—Ń˙ŹÎ˙‹Í˙ŠÍ˙ŠÍ˙ŚÎ˙ŹĎ˙‘Ďţ“Ňţ–Ó˙™ÔţśÖţťÔýźÔţˇÖ˙Ł×˙ŞŰ˙¶âý¶âýąĺ˙şć˙¸ä˙µâ˙«Üý¤Řý›Ňű“Îú”ÎüśŇ˙ˇŐ˙ĄÖ˙ŞÚ˙˛ß˙Ľĺ˙Âç˙Éí˙Ëđ˙Óô˙ŐóýÜ÷ţŢů˙ŕůţăű˙ářţäű˙âű˙ßřýßöü×ő˙×ő˙×ő˙ŰöýŢ÷üŢ÷űßůúâüýĺý˙ç˙˙ć˙˙ĺţ˙ŕü˙ßú˙Ú÷˙×ő˙ĚěůÄčřÇëűĎô˙Ňő˙Îď˙Äí˙«á˙ś×˙‹Í˙‡Ę˙†Çý†ÉţË˙‰Ě˙ŚÎ˙Đ˙‘Îý’Ďü›Ńý Öü­Ţüąç˙Ćń˙Ęń˙Ďđ˙Đď˙Ňď˙ÔňýÖňý×óţÖôţÔń˙ĎďţÍî˙ĚđţÍňű×őýÚ÷˙Üů˙Űů˙Îň˙Ěđ˙Íî˙ŇďýÓďűÔń˙Ňň˙Ňň˙Íî˙Čë˙Ľäýąâţ°Ü˙­Ú˙¨Ů˙§Ű˙ťÔű–Ńű–ÔűźŮ˙ź×ü ŐýžŐţ•Ň˙ŤĎ˙ŚÍ˙Ë˙‰Ě˙ŤĎ˙ŽÎţÎý’Ńý—ŐţšŐýśÖţžÔ˙źŐ˙ŁŘ˙¤Ů˙ŞŢ˙´ář¶ăú˝ç˙ľć˙ľć˙˝ç˙µăý¬Ýý›Ňű‘Ď˙‘Í˙™Ň˙›Ó˙šÓ˙›Ô˙˘Ů˙¨ÚűŻŢúşäúĂěţÍďű×ôúÝöúßřüäüţçůůëţüćřřĺúýŢú˙Őő˙ĹëţĆď˙Čń˙Čń˙Éď˙Ęď˙Ëď˙ŇňýŘö˙Űř˙Ő÷˙Ň÷˙Íô˙Ęń˙Čî˙Čî˙Ĺë˙Ćé˙ÇęţĎđ˙Őň˙ăü˙áý˙Ćď˙µăý—ĎôŹÎúŽĚűŚËţŤĚ˙ŽÍ˙ŹĎ˙Î˙”Ń˙•ĐüźŐű­Ţ˙żç˙Ěď˙Ýů˙áú˙ćý˙ćţ˙ćţ˙čý˙čý˙çü˙ćű˙âů˙ŕů˙Ţů˙Ţúţâţ˙ÝůýÚőü×÷˙Ôö˙Ëđ˙Áę˙Ľćţ˝ç˙Ŕę˙Éď˙Éď˙Éí˙Âć˙ľäűľäůĽĺű»ĺţ¸ä˙±ß˙¬Ţ˙śÔů’ÍůŽËř—Ö˙×˙™×˙—Őţ“Îú‘Ëű’Đ˙ŹÎ˙ŤĚ˙ŚËţŤĚ˙ŹÍţŹÍü•Đü™ŇýśŇţśŃűžÓýˇŐüŁ×ţ®Ţ˙µâů·äű˝ç˙ľć˙ľć˙ľč˙¸ćţ°âýźÖý’Đ˙‘Ď˙•Îű—Ďţ—Ń˙–Ó˙žŘ˙˘Řú§Ú÷˛ßöľçůÍďűŘőűŢ÷üáúţäüţçúřîţűčúúćű˙Úú˙Ďň˙»ĺýĽč˙Ľę˙˝é˙Ľč˙żé˙ÁęţËď˙Ňô˙Öô˙Íň˙Éň˙Ăî˙Ŕę˙Ŕę˙Âë˙Äę˙Ćé˙Ęę˙Ńđ˙Öň˙ćűţć˙˙Ôř˙Ĺî˙ĄŘ÷–Ńů’ĎűŽĚýŽĚ˙Î˙ŹĎ˙Î˙”Ńţ–Ńýˇ×ý®ß˙Ăé˙Ďđ˙âú˙čű˙éţ˙é˙ýé˙ýęţýęţýě˙˙ě˙˙éţ˙ćţ˙ćý˙äüţç˙˙âű˙Ýř˙Öö˙Ňó˙Éî˙˝ç˙·ăţµâ˙¶äţ˝ç˙˝ç˙Áč˙żç˙˝ĺţ»äř»äřĽćţąĺţ´á˙­ŕ˙śÔů“ÍűŤËü’Ň˙–Ö˙™Ř˙×˙—Ňţ•Ď˙‘Ď˙ŹÎ˙ŤĚ˙ŚËţŽÍ˙ŽĚ˙ŹÍţ”Îü—ĐýšĐüťŇüžÓűźÓú¤Öű¬Ýţµä˙·ä˙şć˙Ľĺ˙ľć˙żç˙¸ćýµĺü¦Üţ—Ňţ”Îü–Ěú–ĎüŃţšÓţžŐţ¦Űý°á˙Ľé˙Ăě˙Ěđ˙×ő˙Ýú˙ßü˙ßű˙áůűéýţĺú˙ŕř˙Ëî˙żäţ¦Őń§ŘöŞŰůŻŢü±ŕüłßřąăűČî˙Íđ˙ÍîýÄçúÂçúĽâő»áôÂçúĹęýÇęýÍîýŃń˙Ůő˙Üôţçüýč˙˙ă˙˙Ůú˙µáú©Ţ˙ˇŘ˙’ĎţÎ˙ŹÎ˙Î˙Îý”ŃţÓ˙ĄŰ˙«Üýľć˙ÇęţÖňţŕř˙ę˙˙ë˙˙ě˙˙í˙˙í˙˙ěţţěţţęţ˙éţ˙éţ˙ę˙˙čýţáůýßřýŐóýĐđűĹéůľäűĽäýşäý·ăüłáű±ŢűłŢţ¶á˙¶âý·äű·äű·ĺ˙µä˙®ŕ˙«ŕ˙šÔü’Î˙ŽÍ˙†Čü‡ÉűŤĐý‘Ń˙“Đ˙“Ď˙ŽÍ˙‹Í˙ŠĚ˙‰Ë˙ŚÎ˙ŽÍ˙ŽÍ˙‘Îý•Îű—ÍűźŐ˙ ×˙źÔü˘Öý­Ý˙˛ă˙łä˙·ä˙¸ă˙ľć˙żç˙»čýąçţ­â˙ˇŘ˙śŐ˙šĐţ›Ń˙ťÓ˙ťÓ˙ťÔű¨Ý˙±â˙żé˙Âë˙Íń˙Öö˙Ýű˙Ţü˙Üú˙ßű˙ĺý˙ŕů˙Úö˙Ăéţ¶ßűŁÔőŁŐřĄ×ú©ÚűŞŰű˛ßü¸äýÉď˙Ěń˙Éě˙ÄĺöÁä÷żäöŔĺ÷Éě˙Ěđ˙ÎďţÔňýŮő˙Ţů˙ŕůţéţ˙ç˙˙ä˙˙Ţü˙Áçü˛ă˙¨Ü˙“ĐýŹĎ˙ŤĎ˙‘Ď˙‘ÎýŇ˙™Ôţ¦Ü˙¬Ţ˙˝ç˙Ĺé˙ŇďýÚö˙ćţ˙ę˙˙ě˙˙í˙˙î˙˙đ˙˙î˙˙î˙˙ě˙˙ě˙˙ě˙˙çüýß÷ůßöüŘőýÖôţĘëúĂčűĂéţľć˙Ľć˙´ăý±ŕü°Ýţłŕ˙´áţ´âú´âú˛áý®ß˙ĄŮţ¦Ü˙™Ňý‘Ď˙ŹÎ˙†ÇýĆúŠÎýŽĐ˙‘Ď˙‘Î˙ŠË˙‰Ě˙‡Ę˙Ë˙ŠÍ˙ŤĎ˙ŹÎ˙’Ďţ•Đü–ĎüťÓ˙źÖ˙ ŐýŁ×˙®ŕ˙«ŕ˙«ŕ˙±ß˙łŕ˙Ľäţżčţ˝čů˝čůµäţŞÜýĄŮţ˘×˙ˇÖ˙ŁŘ˙˘×˙ Ôű©Úű®Űú´Ţ÷·ŕöËî˙Ńň˙Ôő˙Ńő˙Đô˙Ůű˙Ůů˙Đń˙ČëţłŕýŞŰüźÖ˙ťÔýťÔýźŐű˘Öű­Űü´á˙Ćî˙Éď˙Ćę˙ČéúËëúŃń˙Óó˙Ů÷˙Űů˙ßü˙ŕůţäý˙é˙˙č˙˙č˙˙č˙˙ç˙˙ĺţ˙Ňň˙Ŕę˙Żŕ˙•ĐúŽÎüŤĎ˙Îý–ĐţśŐ˙śŐ˙ĄŮ˙«Ý˙µáţşäüÇęţÍî˙Ü÷ţäüţčýţě˙˙í˙˙íýüîţýď˙ţď˙˙îţţđ˙˙ě˙ýë˙˙çü˙Ţ÷ţŢů˙Úř˙Óô˙Íđ˙Çě˙Ĺë˙¸ćý¶âű¶â˙˝ć˙Ľč˙·ĺü¸ćý¶ĺ˙Żŕ˙˘ÖűžŐüŇ˙ŤĘ˙ŽÍ˙‰Ę˙…ČýË˙Ë˙‡ČţÉ˙…Č˙Č˙‚Çţ„É˙‰Ě˙ŤĎ˙ŤĎ˙‘Ď˙”Ńţ–Đţ™Ň˙śŐ˙ˇÖ˙¤Ř˙¬Ý˙¨Ţ˙ŞŢ˙°Ţ˙˛ß˙ĽäţľçűÁëűÁëűşçţ®ßý«Ű˙ĄŮ˙¤×˙§Ű˙¦Ú˙¤Öű­Űüłßüşâü»ářÉî˙Ëď˙Íń˙Ęď˙Éđ˙Óř˙Ňö˙Čí˙Ŕćý«Üü¤ŘýšŐ˙™Ô˙šÓţˇŘ˙¤Ú˙ŞŰüłŕ˙Ĺď˙Éî˙Çë˙Íî˙Ńń˙×÷˙Űř˙Ţú˙ßü˙ăţ˙âű˙ćţ˙ę˙˙é˙˙ć˙˙ç˙˙ĺü˙áú˙ÎîűÁë˙˛á˙•ĐúŽÎüŚĐ˙‘Îý—Ń˙ťÖ˙žŐţ¤Ř˙¬Ţ˙´áţ»ĺţÉí˙Ěď˙Ůöţáúţĺý˙ë˙˙í˙˙îţýîţýń˙˙đ˙˙đţ˙îţýîţýđ˙˙ë˙˙ÝôúŢ÷ţÝů˙Řř˙Óô˙Ďđ˙Íň˙ľéü»ĺýĽă˙Áé˙Áë˙˝ę˙żě˙˝ë˙·ć˙¨Ú˙ťÔű™Ó˙ŚÉ˙ŚË˙‰Ę˙‹Ě˙ŚĎ˙‹Î˙Ë˙‰Ę˙„Çţ‚ÇţĆýČ˙Ë˙ŚÎ˙ŤĎ˙Đ˙“Đ˙–Đţ›Ô˙ž×˙ŁŘ˙¦Ú˙¬Ý˙ˇÖö¤Ůů°Ţ˙µŕ˙Ăé˙ÇěţŃő˙Ó÷˙Ĺď˙»ĺţµŕ˙§ŮţĄ×ü§Ůţ­Ý˙·ĺ˙·ă˙»ä˙ÁçţżĺüÄéüÉě˙Ĺëţľçűżé˙Áë˙żé˙´ŕů°ÝúŁŮ˙šÓţ‘Ď˙Î˙”Ńţ ×˙ŞŢ˙¶ä˙¶ă˙Áé˙Ćě˙Çë˙Ňň˙Ůö˙Úř˙Ű÷˙ăţ˙ă˙˙áúţćţ˙ë˙˙ĺúűăűýÚ÷ýÚ÷˙ŐńüĐîůÄçú˝é˙˛ă˙‘Ěř‡Çő‹Í˙Íü—ĐýźÖ˙ Őý¨Ú˙Żŕ˙Ľč˙»ĺţĹë˙Ëď˙Óó˙Űř˙Ü÷ţćţ˙ëţ˙đ˙˙ď˙ţďýýňţţó˙˙ďýýď˙ţđ˙˙í˙˙äůţßöüŰö˙Úö˙Řö˙Óó˙Ňó˙Ěń˙Ęď˙Ĺé˙Ęî˙Éî˙Ęđ˙Éď˙Áë˙ąĺ˙«Ůűˇ×ý—Đý“Í˙’Î˙Ď˙‘Đ˙ŤĎ˙ŚĐ˙…Č˙†Č˙Ćý…Ę˙‚Çţ‚Çţ…Čý‰Ë˙‹Í˙‘Ď˙’Ďü•ĎýšĐüšŃú Őý¤Ř˙§Ůţ°âý±ăţ·ăţĽäţĘëţÎîűÖ÷˙Ö÷˙Ďó˙Çë˙Ŕç˙­Ţţ«Üüłá˙¸ĺ˙¸ä˙żé˙Áé˙ĂéţĂéţĆëţÉě˙Áçţ»ĺýµăű˛áű˛ŕúŞŰűĄÚüšŐ˙”Ń˙ŽÍ˙ŽĚý”Ń˙¤Ů˙­ß˙»ç˙ľč˙Äę˙ĆëţČëţĐňţÔô˙Úř˙Ů÷˙Ýůýŕůţŕřüäüţĺý˙áůýÝř˙Ńň˙Ěíţżä÷»ářłŕý¬á˙ŁÚ˙‘ÎűŤÍýŽÎţ”Ń˙ŃţˇÖ˙Ł×ţ®Ţ˙łá˙ľç˙żç˙Çí˙Ęî˙Îň˙Őő˙ŐóýŰöýäü˙ěţ˙îţţđţţó˙˙ô˙˙ő˙˙ó˙˙í˙˙ęüţáöűÝőůÝöýÜ÷˙Üř˙Ů÷˙Öö˙ÍńýĚđţËî˙Ëî˙Éî˙ĹěýĂęűşäü´ŕű¬Úű¦Řű ŐýśŇ˙šŇ˙™Ó˙—Ô˙’ŃýŹĎý„Ćú…ĆţŠË˙Ë˙†Éţ…Čý‡Ę˙ŤĎ˙ŹÎ˙Íü”Ďű™Ň˙ťŇúžÔúĄŮţ«Ý˙±â˙ąé˙ąç˙»ĺýżĺüÎí˙ÔňýŘöţ×őýŇó˙Ęě˙Ćë˙˛á˙®Ýűłŕý¶âý·áůÂë˙Ćě˙Ćę˙ĆëţÇě˙Éě˙ÁçţĽćţµäţŻáü¬Ű÷Ą×řźŐů“ĐýŹÍţŹÎ˙ŹÍţ•ĎýźÓú§×ű»ä˙Ŕč˙Éî˙ĘîţĘëúÎđüĐňüÖ÷˙×őýÚöúÜřüŕůýäý˙áúţßřýŰř˙Ëđ˙Ĺé˙µßř°ÜůŞÜ˙ĄÜ˙ś×˙ÎýŹÍţŹĎ˙”Ń˙Ńţ Ő˙˘Öý­Ţ˙łŕ˙˝ç˙Ŕč˙Čě˙Ëî˙Ëď˙Ňó˙ŃńţŮôýâů˙ęü˙íü˙ń˙˙ó˙˙ô˙˙ő˙˙ň˙˙ěţ˙éű˙â÷üß÷űáú˙Ţů˙Üř˙×ő˙ÓóţĘđűČîűËđ˙Ěđ˙Íň˙ĹëţÁęü¶âű±Ţű«Ůű¨Úű§Ű˙ĄŘ˙ˇÖ˙ťÓ˙ť×˙–Ńű‘ÎúČřŠË˙ŚÎ˙‹Í˙ŠĚ˙ĘţŠĚ˙Ď˙Ď˙Íü–ĎüśŇ˙ ÖüŁ×üŞÜ˙®ß˙¶ä˙Ľéü˝ęýÄęýÉě˙Řő˙Ýů˙Ú÷űŮöüĎďţĹç˙Ćë˙şé˙µăý°Üőłŕ÷ĽĺűÄęýĘď˙Ęď˙Ëđ˙ĆëýČë˙ÁçţŔę˙şé˙łä˙°á˙§ŮüźŐű‘ĎţŤĎ˙ŽÍ˙•Ň˙Ó˙śÎóĄÓôĽäýÇí˙Őö˙Ôö˙ÓóţĎôýÎôýÔ÷ýÓôűÖó÷Ú÷űă˙˙âţ˙áü˙Űö˙ÓđţÁé˙¸áýĄÖ÷źÓúŐ˙“Ó˙‘Ń˙ŠÉüŠÉüŽĚűÍü—ĐýˇÖţ¤Řý±ŕţąĺ˙żç˙Ĺë˙Éě˙Ęę˙ÄëüËđ˙Íń˙Ů÷˙Ţů˙ĺřţéűýđţ˙ńýýó˙˙ó˙˙đ˙˙ëý˙ęý˙ę˙˙é˙˙âű˙Ü÷˙Ű÷˙ÔňüÎîůÄîúĹěýÉď˙Âę˙Áë˙Ľéţşč˙°ßű©ÚúĄ×ú«Üü°á˙®Ţ˙ŞŰ˙ĄŮ˙˘ŘţśÖűšÖű‘Îű‘Ď˙‘Đ˙ŹÎ˙Ď˙‰Čű‰ČűŹÍ˙Î˙“Íű™Ň˙ Ö˙§Ű˙ŞÜý¬ÝýŻÝţµâ˙żéůĂęűĘîüĎđ˙Ůő˙Üů˙Ú÷˙Řô˙ËęüŔâűÂç˙ľě˙Ľč˙·äűąăůľçűÄęýÉď˙Ëđ˙Ëń˙ĆëţĆę˙ľçýÁë˙Ľë˙·ć˙°á˙¦ŘűťÓůÍúŽÎţŚËţ—Ô˙śŐ˙źŃô¨×őŔćýËî˙Řř˙Ů÷˙Ú÷˙Ö÷ţÓöüŐöýÓôűŐňřÚ÷ýŕü˙Ţúţâý˙Üř˙ĎďţĽĺ˙łŕ˙˘ÖűžŐţ™Ř˙ŽĐ˙ŤĎ˙Çú‡ĆůŤËţÍüŃţĄÚ˙ŞÜ˙¶ă˙ľç˙Ăč˙Čě˙Éě˙ÉęýĂéüĘď˙Íń˙Űů˙Ţů˙ăřűçűüď˙˙îţţđ˙˙ó˙˙ń˙˙ëý˙ęüţęý˙ę˙˙Ţ÷ţŘô˙Řô˙ŇđűËíůĂíýÁęţÄî˙¸äý¶âűµâůµăű¬Ýű§Ůú¤Řý«Üü±ß˙­Ý˙«Ű˙«Ű˙Żß˙«ŕ˙ŞŢ˙śŇţ–Đ˙“Ń˙Đ˙Ď˙Çú„ĆúŤĚ˙ŹÍţ”ÎüšÓţˇ×˙ŞŢ˙¬Ţ˙­ŢţŻŢü¶âýÎęöĎëöÖó÷ÚöúÜ÷ţÚ÷˙Ôó˙Íí˙Âç˙˝ç˙»č˙Âě˙Âę˙˝ćü˝ćüÂë˙Ćě˙Ćď˙Ăë˙Ćî˙ľč˙·ăü·ăü¸ćţąç˙¶ă˙´â˙©Ý˙ŁŮ˙•Đú’Íů‘Ëű—Ďţ™Đů­Űüąĺ˙Ďň˙Őő˙ăű˙äű˙âőűŕřüŢ÷űÔďřŃëřŃíůÔđüŰřţŰřţÜů˙ÖňţËěý˛ă˙«Ű˙źÔţ›Ô˙”ÓţŽĎů‹ÎůŚĚüŤĚ˙Í˙’Î˙™Ň˙¤Ř˙ŞÜ˙·ă˙żć˙Čě˙Ěď˙Îď˙ĚíţĆě˙Ëď˙ĐňţŰřţáúţăů÷äú÷çýűć˙˙ä˙˙ë˙ţě˙ýěţţěţţçűüäůüßř˙Ů÷˙Řő˙Íî˙Çě˙żé˙˝ć˙´á˙˛á˙łŕý¶âý¸ä˙©ÚúŁŘř¦Ü˙­Ţ˙±ß˙ŻÝţłŕ˙¶ÝúľáýĚđ˙Çě˙˛Ýý¤ŘýžŐţ‘ÎűŹÍţ†Éý„ÇţŠÍ˙‹Î˙‘Ďţ™ÓűźÖýŞŕ˙Şß˙±â˙¶ă˙Ŕĺ˙ŇđűÓńűŮřűÝúţÝú˙Üř˙Ńđ˙Ĺčţľć˙»é˙ąç˙Ŕę˙Áë˙żčţľçýŔćűÄę˙Ĺë˙żç˙Âę˙»ĺţ±ßů±Ţű˛áý´ă˙˛ŕ˙°á˙§Ű˙ˇŘ˙—Ňü”Ďű’ÍůťÔýźŐűłŕýľč˙Îň˙Őő˙ĺţ˙çţ˙ĺřţäý˙ŕű˙ÖňýÓďýŇďýÔňýŮ÷˙Ů÷˙Ů÷˙ŃîüÇčű°á˙¨Řü›Đü—Đý‘ĐüŽÎúŤÍůŽĚűŹÍ˙‘Í˙•Ď˙śŇţ§Ř˙­Ý˙şć˙Áé˙Ęď˙Ďň˙Đń˙ĎďţĹęüĘîüĐňüÝúţäţ˙ĺűůćüůé˙ýĺ˙˙âţ˙é˙˙ę˙˙ë˙˙ě˙˙čý˙äü˙Ýř˙×ő˙Ôń˙ĚíţÇěţĽć˙ąâţ˛ßţłŕ˙µáţşäýĽć˙ŻŢü¨Űú©Ţ˙ŻÝţ´ă˙˛ßţµâ˙˝ĺţÄčţĐó˙Îň˙żé˙­Ţ˙ˇŘ˙‘ÎűÎýË˙„Çţ‡Ę˙Ë˙Î˙šÓţźÖ˙Şŕ˙Şß˙´ă˙ąĺ˙Äč˙Ů÷˙Úř˙â˙˙ä˙˙ŕ˙˙Ţü˙Ęí˙żĺü±Ýřłâü´ăý˛Ţů¸áýŔč˙Áę˙ÁçüĆëţĂéţ˝âüşßůŻŰř©ÚűĄ×üĄ×ü§ŮţĄŮţźŐű›ŐýšŐ˙™Ö˙™Ö˙©ß˙´ĺ˙¶ĺ˙ľčţÄëüĚîřŇóúâţ˙ä˙˙ĺţ˙Ýű˙Ůů˙Óó˙Ńđ˙Óň˙Óó˙×ř˙Řů˙Öö˙ÍěţÄçűŞÜ÷˘ÔőšĎű™Ń˙™Ö˙”Ó˙•Ňţ—Ňü—Ňü›ŃýźÔü¤ŘýŻÝţ´áţÁę˙Ëď˙Óô˙×÷˙Öô˙ÓńüĚěůÍířÓńűăü˙ç˙˙ę˙ţę˙ţç˙˙áúţŰ÷űŰř˙Ú÷˙Ú÷˙ŰöýÚőüŮôýŮő˙ÔňýĎďüĚíüËď˙Ŕé˙şäý´ŕű·áú·áůÂč˙Ĺë˙şć˙´áţŻŕ˙°ßű´ăýµăýąćýĘď˙Ňó˙Řö˙Őő˙Ďő˙˝ę˙­á˙“ÎúŽÍůŚÎ˙ŠÍ˙„Çţ†ÉţÎ˙™Ô˙ž×˙§Ý˙©Űüµâ˙˝ç˙Îî˙ŮöţÚ÷ýâţ˙ĺ˙˙ä˙˙á˙˙Íî˙Äčţ˛Ţ÷˛âů´ăý±Ýú¶ßűŔč˙Ĺë˙ĆëţČí˙Ćę˙ľäűşßů®Ú÷©Ů˙ˇŐý Ôű ÔűźÔüžŐü›Ö˙šŐ˙—Ô˙—Ö˙­â˙şé˙Ľę˙Äí˙Ęď˙ŇôýŐöýŢű˙Ţű˙Ýú˙Őő˙Óó˙Đď˙Ńđ˙Ňń˙Ňň˙×÷˙Řů˙Öö˙Îí˙Ĺęý¬Ţ÷¤×öśŃýťÓ˙śÖ˙šÔ˙›Ö˙žŘţ ×ţ˘ŘţĄÚü¬ÝýłŕýşäýÄéüËî˙Ôô˙Ů÷˙Úř˙Ůő˙ÔňýÓďúÖóűäý˙č˙˙é˙ýç˙˙ć˙˙ŕü˙Ţů˙×ő˙Ôô˙ÓóţŐóýÔňüÔđűÖňýÓńüŃńţĐń˙Đń˙Ćě˙ľć˙ąăüąăűąâřĆëţĘí˙Áé˙¸äý±ŕţ°ßű±ŕüµăýąćýËđ˙Öö˙Űř˙Ú÷˙Öř˙Ĺđ˙łĺ˙”ĎůŤĘ÷ŠĚ˙‹Ě˙„Çţ†ÉţŤÍý–Ó˙ś×˙ĄŰ˙§Ůú´áţľć˙Đđ˙ç˙˙ç˙˙ę˙ţë˙ţç˙ýĺ˙˙×ő˙Ďî˙Äę˙Ľéüşéýąĺ˙ąăüĂéţÉî˙Đń˙Ôő˙Ôő˙Îń˙Çë˙Ľĺ˙˛â˙ĄÚ˙˘×˙žÓý›ŇűźÖ˙ Ú˙ś×˙—Ňú›Ů˙˛á˙żç˙Ŕé˙ĘîţĐń˙Őő˙Ôô˙ÎďţËěýÉě˙Ëď˙ĘîţÍí˙Ďď˙Đě˙Ďěü×ő˙Řö˙×ô˙Ńđ˙Ęď˙¶ę˙­ŕýťŇţšÎţ“ËţźŐ˙˘Ů˙«ŕ˙°ă˙¶ĺ˙¸ćţŔę˙Ćě˙Éě˙ÎîůÔňýŮôýÚőüÜřüŢ÷üĺţ˙ßřýáůýč˙˙ë˙˙č˙˙ć˙˙ŕü˙Űř˙Úö˙Ďô˙Íô˙Ëđ˙Ěđ˙ĚîúĚě÷ĎířÓńüÖö˙Řř˙Őő˙Ęí˙ÄéüÁçţŔćűżä÷Ěí˙Ďđ˙Çë˙ľć˙±Ţű°ßýŞŘů´áţ¸äýĘîţŐóţŕů˙áú˙Ú÷˙Čí˙¸ç˙—ŃůŤĘö†Ĺř„Ĺű‚ÇţČ˙‡ÉűŹÍü•Ň˙ˇ×ý¤Öů±Ţű˝ĺţŇń˙čüýě˙˙í˙üí˙úě˙üęţüâű˙Úö˙ÍîýÉđ˙Čň˙˝ç˙˝ĺţČëţÎďţÖô˙Ů÷˙Ú÷˙Ôó˙Íî˙żäţ±Ý˙§Ůţ¦Řý¨Ů˙¨Ü˙§Ű˙ĄŰ˙ŁŮýˇÖř˘×ů´ÜöĆé˙Čë˙Đď˙Ňň˙Ôó˙Đń˙Ăč˙˝ä˙±Ţ˙´Ţö¸á÷Äę˙Éí˙Ďî˙Ďî˙ÔňýÖô˙Őň˙Íě˙Ëď˙¶ę˙©ŢýśŃűĚűšÎţĄŮ˙¬Ţ˙¶äüşçţĹî˙Ëń˙Íń˙Ňň˙×ő˙Ü÷ţÝöűäü˙ĺý˙ćţ˙ę˙˙ę˙˙éţ˙éţ˙ç˙˙č˙˙âű˙âţ˙ŘöţĎďüĚěűÄęýÁě˙ĆíţČí˙ÍďűÎîůŇđúŐóű×óţÚö˙Úř˙Óó˙Íî˙ĆëýÎń˙Ńő˙Óó˙Ňń˙Ęí˙Áçţ°ÝüŞÚţ§×˙°Ţ˙¶á˙Ęí˙Óđ˙Ýő˙ß÷˙Úö˙Ćëţ˛áýśÓú–ŃűŽÎţŚÎ˙Č˙„É˙ŠÍ˙Đ˙’Đ˙śÓü Ôů´á˙ľč˙Đń˙čű˙ë˙˙ë˙űëţřě˙űęţüĺü˙Ýř˙Đđ˙ĚđţĘń˙˝ç˙ÁçüÍîýÓóţŰř˙Ţů˙ßú˙Ůö˙Ňň˙Äčţ´Ýű¬Úű¬ÚűŻŕ˙˛ă˙Żŕ˙Żŕ˙®ß˙®Ýű®Ýű˝áůĎď˙Ôó˙Řő˙Řő˙Ôó˙Îń˙żč˙¶ă˙§Ř˙©Řö­Űőşă˙Ŕç˙Ëí˙Ěď˙ĎďţÎďţÍî˙Ćé˙Ĺę˙±ä˙©ŢţśŃűÍůťĐýŞÜ˙°Ţ˙şäüżčüËđ˙Íń˙ŃńüŘô˙Űöýáůýăű˙čý˙éţ˙éţ˙ë˙˙í˙˙éýţćűüćţ˙č˙˙Ýř˙Ýú˙ŃńüÇëűĹčűÁçüľçűÂéúČí˙ĐňţŃńüŘőýŘőűŮôýÜ÷˙Üů˙Řö˙Óó˙Íń˙Ńő˙Ó÷˙Óó˙Ňń˙Čě˙Ŕč˙ŻŢü¬Ţ˙ĄÖ˙­Ý˙µâ˙Çë˙Đď˙Űó˙Ýő˙Úö˙ĂčűŻŢúťÓů™ÓűĐţŽĐ˙„É˙…Ę˙ŠÍ˙Ď˙’Đ˙—ĐűžÔúµă˙Ľč˙Îń˙Űö˙ŕű˙ĺ˙˙ĺýýę˙˙é˙˙áů˙Üö˙Ńđ˙Ëď˙Ęď˙Ćě˙Éî˙Řö˙Ýú˙ĺý˙ę˙˙ë˙˙áü˙Ú÷˙ÎîűĹčűżĺüĽĺűľć˙ľč˙Áé˙Ăë˙Çí˙Ęî˙Čě˙ËěýÖó˙×ô˙Řô˙Öô˙Íđ˙Ĺë˙ŻÝţ¦Ú˙™Ó˙–Ńů—ÓřˇÖţ¨Ů˙¶ă˙şć˙˝ç˙˝ę˙»ç˙´á˙°Ţ˙§Üü§Ű˙¤×˙˘Ő˙«Ý˙˛áý·äűĂéüČë˙Ďî˙Řô˙Ýř˙ĺü˙éţ˙ě˙˙ë˙˙ěţţěţţěţţěţ˙î˙˙ęţ˙çüýáúţÝůýŘö˙Ôô˙Číý˝ăřĽâůŔćűŔĺřĆéüÎďţÚř˙Üř˙Ü÷ţŕůýŕůţÝöűŰôůÜ÷ţÚř˙Ôö˙Ďđ˙ÎďţĎďţĘëü˝ăú·ăü¬Ýţ¨Ü˙ĄÚ˙¨Ú˙¬ÝýÄę˙ČëţŐóţŮ÷˙Öö˙Ŕćůłáű¤ŘýźÖýÎý‹Í˙Ć˙‚Ç˙…Č˙‰Ë˙ŚËţ”ÎüšÓţ±ă˙·ć˙Čî˙Öô˙Üú˙áţ˙áý˙ĺţ˙ĺţ˙Ý÷˙Ůô˙Đń˙Ëî˙Éî˙Ëđ˙Ďó˙Ýű˙ă˙˙ę˙ţë˙ţë˙˙ăü˙Ü÷ţÔňýĐđ˙ČëţĆëýĆëţĹë˙Éí˙Íđ˙Îń˙Ďđ˙Ďî˙Ńńţ×ő˙Öôţ×óţÔňüČěü˝ćú§Řůˇ×ý–Ó˙ĐüĐü•ŇţťÓ˙ŞŰ˙­Ţ˙®Ýů°âý°á˙­ß˙©Ű˙ĄÚüĄŮ˙ĄŮ˙¤Ř˙¬ÝţłáůşäúĹęüËě˙Đí˙Úő˙áú˙éţ˙ě˙˙í˙˙í˙˙íýýíýýď˙˙í˙˙í˙˙ě˙˙éţ˙ŕůýÚőüŐő˙Ňô˙Čď˙ĽĺűşâűÂćüĂčúËěýĐđýŰ÷˙Ţů˙âű˙ć˙˙ć˙˙áúţßřüÜřüŰř˙Ôô˙ĚíüĘëúÍî˙Čéü¸ŕů·ăţ«Ýţ¦Ú˙¦Ű˙ĄÚü©ÚúżčţĆęúŐő˙Řů˙Ő÷˙Ŕęú´âüĄÚü Řý‘ĎţŤĎ˙Ć˙€ĹţĆý‡Čţ‹Ę˙‘Îý–Ńý§Ű˙­Ţţżé˙ÇęýĎó˙Öř˙ÔőţŃňűŃńüŃđ˙Îď˙Čě˙Äę˙ÄęýĘîúĐňüŕü˙ç˙˙ě˙üí˙üě˙ţéţ˙ç˙˙ă˙˙Ú÷ýÖôţÔô˙Ôö˙Ôő˙Íî˙Öö˙×÷˙Řô˙Űő˙Üů˙ßü˙Ţű˙Űů˙Öôţľăő´Ţô˘×÷ť×ý‘Ń˙‡Í˙‡Í˙‹Í˙ŹÎ˙Ň˙›Ô˙šŇ÷Đő™Đ÷ťÖ˙›Ô˙ ÔűźÓú©Ý˙®ŕ˙µä˙˝çýľçůĘëüĎî˙Řó˙Ü÷˙äü˙í˙˙î˙˙ď˙ţń˙˙îüýďýţň˙˙ň˙˙ń˙˙í˙˙ęţ˙âů˙Ýř˙ŃńüÎďţÍň˙Äę˙Ŕé˙Ęí˙Đń˙×÷˙Řö˙Ţů˙âţ˙ăü˙ĺ˙˙ç˙˙éţ˙éţ˙ÝöűŰöýÔô˙ĚíţĘëüËď˙Ęí˙ľć˙»ç˙ŞŰü§Üţˇ×ű§ÜüŞÝúµŕóÁćöŘů˙Űü˙Ő÷˙ĹďýĽé˙­ß˙ŁŰ˙‘Ń˙ŽĐ˙Č˙‚Ç˙„ÇţĘţŚË˙’Đ˙ÍúĎöźÔö˛ŕúĂčűËđ˙Đô˙Íń˙ÎňţËńüĹęúĹęüÂčűżčüĆě˙Ńńü×ő˙ă˙˙é˙˙ęţýî˙˙î˙˙ě˙˙ę˙˙ĺ˙ţŢ÷űÚőüŘőýÔô˙Ôő˙Ôő˙Őő˙Öö˙Ů÷˙Űř˙ŕű˙ßú˙Ýú˙Úř˙Ňó˙·ßř®Űř˘Řţ›Ô˙ŤĚ˙‡ÉýĘţŹÎ˙’Đ˙”Îţ”Îü–Ďú–Ďú–Ďú™Ô˙śŐ˙ Öüˇ×ý©Ţ˙Żâ˙şč˙ÁçüĹęüÎîűŃîüŘô˙Űöýç˙˙í˙˙ń˙˙ń˙ýő˙˙îüüďýýó˙˙đ˙˙đ˙˙í˙˙ë˙˙äř˙ßő˙Úô˙Öň˙ÎďţĹéůĆěůÎđüÔňýÜů˙ŢúýŕúűŢúűĺ˙˙âţ˙ć˙˙í˙˙ęţ˙Ü÷ţŰ÷˙×ô˙ČéüÂăöĚđ˙Ęď˙Ăě˙Áë˙¶â˙ŻÝ˙«Ý˙§ŮüŞŰü´ŢöŔĺřŘö˙ßű˙Ýű˙ĚîúÄę˙«ÜüťÓ÷ŤĎ˙ŚĎ˙…Ę˙‚Çţ…ÇűŹÎ˙ŹÎ˙ŹËý”Ěý›ŇűźÓú­ŢţĽáüĽäýżčţĂéţÁęü˝ćřąâô·ŕô˝ćüľć˙ÁçţÎđüŃó˙ŇîůÔďřŕ÷ýçü˙čý˙ćţţç˙˙âţ˙Ýůý×óţÔňýŃň˙Ńô˙Ęí˙Íî˙Đđ˙×ő˙Űř˙ßřýŰöýŘőýŃńţÉęűŔę˙˛ß˙™Đů•ĎýŠĚ˙‡Čţ‰Ë˙ŤĚ˙ŤĚ˙’Î˙•Ň˙—Ń˙”Íú”ÍřŃü›Őý Öú¤Řý®ŕ˙˛ă˙Ľć˙ÂçúĹčűÎîűĎďúŮő˙Ţů˙ç˙˙í˙˙đ˙˙ń˙˙đ˙üďýýďýýďţ˙í˙˙ë˙ţë˙ţęţ˙čű˙ćú˙á÷˙Ü÷˙Řö˙ĐňüÎňţ×÷˙Úř˙Ű÷úÝ÷řŕúűßűüáţ˙ă˙˙ć˙˙ëýýćúűŕű˙Ţů˙Řó˙ĚëýČéúĚđţĚň˙Éđ˙Éď˙Ŕč˙¶ă˙®ß˙ĄÖ÷¨×ő·á÷Čí˙Ýú˙âţ˙ă˙˙Řö˙Îó˙®ÜýťÓů‹Í˙Í˙…Ę˙‚ÇţĹůŚËţŽÍ˙‘Ď˙“Ń˙™Ôţ›Őý¦Ü˙¬×ůŻÚüµŕ˙¶ßý·ŕüşă˙ąăü·ßůľĺ˙Äé˙Âç˙ÁçúĹęýËî˙Ďđ˙Ďďü×ő˙Ůő˙Ýú˙áţ˙â˙˙×÷˙Íń˙ČëţÂčýĂé˙Čî˙Ęí˙Ěí˙ÓđţÖňýŢ÷ţÜ÷ţŮöţÓóţĚíţ»ĺţłá˙›ŇűŹĚů†ÉţČ˙†É˙…Čý†ČüŽÍ˙“Ń˙•Ďý›Ô˙žÔ˙źÖ˙ˇ×ý§Ůú«Ýţµä˙¸ĺ˙ĽćţÄęýÇęýĎđ˙ĐňţŰů˙ŕű˙ĺý˙í˙˙î˙˙đ˙˙đ˙üđ˙˙đ˙˙ěţ˙ěţ˙ęý˙éţ˙éţ˙čýţčýţç˙˙äý˙ŮöüÖö˙×ů˙Řö˙Üů˙ăü˙äüţâüýŕü˙Ůřýßü˙äý˙ĺůúäřůŢ÷űÝöý×ńţÔđţÓńüŇôţĐőţËđ˙Ęď˙ľć˙·ĺ˙«Üú©ÚřŻŢřÉň˙Ńő˙âţ˙ć˙˙ç˙˙Űů˙Íó˙Ą×ü—Î÷„Ĺű‚Äţ‚ÄţĆý‹Ę˙ŹÎ˙Ď˙ŹŃ˙‘Ô˙”Ő˙”Óüť×ý¦Ňő©Őř°ŰýŻÚüłÜü¸á˙˝ć˙˝ä˙˝ä˙Äč˙Äé˙ľçý˝ćüÄę˙Éí˙Íđ˙Ňó˙Óó˙Ôô˙×÷˙Řř˙Őö˙Ëđ˙Ĺë˙ľć˙˝ĺţŔč˙Ćę˙Éě˙Ňň˙Öô˙ŘóúŰöýŰöýÖö˙Đń˙Ľäţ·ä˙śÖţÍú†Éţ„É˙Č˙Ćý†ÇýŽÍ˙Đ˙“ĐýťÖ˙ ×˙ŁŘ˙ĄŮţ¬ÝýŻŕ˙¸ĺ˙şć˙ľć˙ĹëţÇě˙Ďđ˙Đń˙Űů˙ßú˙äü˙ě˙˙ě˙˙ń˙˙ń˙ýđ˙˙đ˙˙ě˙˙ëţ˙ë˙˙ę˙˙éţ˙ę˙ţę˙ţč˙˙ĺ˙ţŮőůÚř˙Ůů˙Řô˙Ü÷ţĺţ˙ćţ˙áűüÝůüŘöţŰů˙ßű˙áôřáőöß÷ůßöüŰó˙Řô˙Řö˙Öř˙Ő÷˙Ěň˙Ęď˙˝ĺţ°Ýú¨ŰřŻŕţ´ăýČň˙×ů˙ć˙˙é˙˙ç˙˙×ř˙Äě˙žŇů“Ě÷„ĹűĂýĂýĆýŚË˙Ď˙Ď˙Ň˙Ô˙”Ő˙”Óü›Őý±ß˙®Üýłá˙¸ĺ˙şć˙Ľč˙Âě˙Ĺí˙»ŕúÁć˙Âę˙»ç˙˝é˙şć˙¸ä˙»ç˙Áë˙Ăč˙ÄčţÇě˙Ęď˙Čî˙Âę˙˝ç˙·ă˙µáţąâ˙Ŕč˙Ćě˙Đń˙Óó˙ÔńůŰöýŢů˙âţ˙Űű˙Ëđ˙Áí˙źÖý“Đý‰Ě˙‡Ě˙Č˙‚Čü‰Ě˙ŹÎ˙ŽÎţ–Ó˙śÓüžÓű§Ű˙­ß˙µâ˙¶ă˙şć˙ľč˙Ŕé˙ĹëţĆëýÍî˙Íî˙Öö˙Ýř˙áůýë˙˙ęţýń˙˙ň˙˙íýýěţ˙ë˙˙čý˙Ţö˙Ţ÷ţŢ÷űâűřăüřĺ˙űć˙ýŢúýŢú˙Úř˙Ůő˙Ýř˙ăü˙âů˙ÜőúŘóúÍířÓóţÚö˙ŕ÷ýĺúýäůúâúţŢö˙Úö˙Úř˙×ů˙Óř˙Ëđ˙Çí˙şă˙˛ŕ˙žĐó¨Úű°Ţ˙Ĺî˙Îň˙áü˙âý˙Űö˙Äčřłßü–Ëő“ÍűŠÍ˙†Ë˙‡É˙É˙Çü‹ÉüŽÍ˙”Ó˙•Ő˙Ő˙Ó˙źÔüąć˙şç˙şč˙Ľč˙Áë˙Ăí˙Ŕč˙ŔćýÁĺűÇě˙Čî˙ľč˙»ç˙ąĺ˙¶ă˙±Ţý¶ă˙Ľĺ˙»ăü»äúĂéţÁę˙ľč˙ąĺ˙±ŢýŻÜű´ß˙Âę˙Ĺę˙Ďđ˙Đď˙ĎěôÚőüÝř˙Ţú˙Űř˙Ňö˙Çđ˙ŁŮ˙“Îú‰Ë˙†É˙†ÉţË˙‹Î˙‘Đ˙‘Ń˙–Ó˙ťÔý Öü«Ý˙®ß˙¶âý¸ä˙ľč˙˝ç˙Áę˙Éî˙Ëî˙ĚíţĚíţĎďúŮôýăű˙ë˙˙ě˙˙ń˙˙ń˙˙ěüüî˙˙çü˙âöýÜ÷˙ŘóüŮőůŢř÷ăţůć˙üć˙ýŕü˙Üř˙Öô˙ŃířÖńúâű˙ăú˙×ňűŇîůÍďűĎńý×ő˙ßř˙ß÷űćűüăű˙ß÷˙×óţŐóýÔö˙Ň÷˙Çî˙Ŕé˙¸ă˙«Ű˙¤Ř˙Ą×üŞÚţ»ăýĹčţÖň˙Ű÷˙Öó˙Âćü°Ýţ—Íű‘Í˙‹Í˙„É˙…Ç˙‡Č˙ŤĘ˙Î˙ŹÎ˙’Î˙–Ď˙™Ń˙śŇţŞÜ˙Ĺđ˙Čó˙Éň˙Ĺî˙ÄęýĹëţČí˙ÇěüĆęřČěřÉíűĹë˙żčţ¶âýłâ˙¬Ţ˙©Űţ«Üý®Űř±ÝřĽćţ˝ĺţľč˙Ľč˙µâ˙®Üý°Ýüşă˙˝ĺ˙Ćę˙Ęí˙ÖôţŰř˙Űř˙Ü÷˙Ůő˙Íî˙Äč˙©ŮýźÔţ‘Ď˙ŹĎ˙ŽÎţŤĚ˙ŹÎ˙Đ˙ŹĎ˙šŐ˙źÖýŁ×ü­Ţ˙ŻŢü´ŕű¸âűľć˙ľć˙Ĺë˙Éî˙Ęí˙ÍěţÎîýÔňýÚőüäüţęţ˙ęţýîţýń˙˙ěţ˙ëţ˙äř˙ßöţÓó˙ĎďüĎđůÓđô×ő÷âţ˙ĺ˙˙ßü˙ŐňúŃďůŇđúÖóűßú˙ßú˙Őń˙ÎîýÇě˙Éî˙Îň˙Úř˙Űř˙ŕůţß÷˙Ůő˙Ôô˙Ňô˙ĘđýĹďýżé˙¸ä˙«Ř˙ĄŘ˙ˇ×˙ Ő˙Ł×˙±Üţ¸ßüÄć˙Çé˙Áć˙®ŰüĄÖţ•Ďý‘Ď˙ŠĚ˙‡Ě˙ŠË˙ŠË˙ŽĚýŽĚýŽÎţ–Ë˙šĚ˙˘Ň˙©Ö˙şĺ˙ĘňţÍő˙Ďô˙Ęď˙ÇęýČëţËď˙ĘîüĚîúÍďůÍďůČí˙Áçú´ŕů°ßýŞÜ˙Ł×üĄ×ú©Řö®Űřąĺţ˝ćüľć˙˝ç˙·ä˙ŻÝţ±Ţý¶â˙şäýÄę˙Éî˙ÓóţŰř˙Ú÷˙Űö˙ŘóţĚëýĂćü¬Ůú¤ŐýŇ˙‘ÎýÍúŹÍü‘Ďţ“Ń˙“Ń˙™Ô˙ ŐýŁ×üŻÝ˙ŻŢü¶âýşă˙żç˙żčţĆě˙Ęí˙Íî˙ÎîýĎďüÖôţÚöúĺúýęţ˙ë˙ţď˙ţđ˙˙ë˙˙éü˙ŕ÷ýŢ÷ţŇó˙ĚđţÎđüŃďůÖôüŕý˙â˙˙Ýú˙ÖóűŇđúŃďůÔňüŢů˙Ţů˙Ôń˙Îď˙Äę˙Äę˙Ęď˙Öö˙Ů÷˙Űö˙Úő˙Őň˙Ďđ˙Ěđ˙ÄîţŔëüşć˙µâ˙ĄÔţ Ő˙ťŐ˙źŐ˙ˇÖ˙®Úý´ÝýĽáüżä˙·â˙§ŮüžŇú”ÎţŹÍ˙†Č˙†Ë˙ŚÍ˙ŽÍ˙ŽĚűŹÍüŽÎü–ĘúťÍý©Ö˙°Ü˙żč˙ĎďúŃńüÓóţŇň˙Ďî˙Ďî˙Ďî˙ÎîýŃńţŐő˙×ř˙ÖôţÎđüżčţ¶äţ©Ţ˙ŁŮ˙˘Öű§Ůú­Ţţ»ç˙ÁęţŔćűľçý»ç˙´á˙±Ţýłßü¶âűľçűĹë˙ÎđüŰů˙Ţű˙áú˙Ţö˙ÔđţĚëý¶Ýú®Úý¤×˙ Ő˙ťÓ˙—Đý–Ńý”Ńţ”Ńý™Ôţˇ×ý¦Ú˙±ß˙ŻŢüłŕýµáü»ĺţ˝ćüĆëţÎď˙Ńń˙ÔňýÖôţŰö˙Ýöűçü˙ě˙˙ě˙˙đ˙˙ěţţęý˙ćűţâů˙ŕř˙ĘđýĹěűĹěýĆéüËěý×ô˙×ô˙ÖôţŰů˙Ů÷˙ĎďúŃńüÚö˙Úö˙Ňń˙Íđ˙żé˙ąĺţĽćüĘď˙Îň˙×ô˙Öó˙Ďđ˙ÄęýŔéý¸ĺú˛âů«Ű˙§Ř˙śĐ˙•Îű•Đü™ŇýźÖ˙ŞÜ˙ŻÝţ±Ţű˛á˙«ß˙ Ú˙™Ňý’ĎţŤĚ˙Ć˙…Ę˙ŚÍ˙ŤĚ˙ŽËř‘Đü’Ňţ Ôű¦Öú´â˙»ç˙Áé˙ÔňüÔňüÖô˙×ô˙Őň˙Óđ˙Ňď˙ŃîţŃńţ×÷˙Űů˙ŮöţÓóţÄí˙»ç˙Şß˙ĄŰ˙ŁŮýŞÜý°á˙Ľč˙Ăě˙ĂéţÂë˙ľę˙µâ˙˛ßţłßü·ăüĽçúÂë˙ÎňţŰů˙Ýú˙âű˙ář˙Ůó˙Ôń˙Ŕĺ˙´ß˙¨Ů˙ĄŮ˙˘×˙śŇţšÓţ—Ô˙–Ó˙ś×˙ŁŮ˙¨Ý˙±ß˙®Ýű°Ýúłßú»ĺţ˝ćüČí˙Îď˙Ňň˙Řô˙Ůő˙Ü÷ţáú˙éţ˙ě˙˙ě˙˙ď˙˙ěţţęý˙çü˙çţ˙ăű˙Ěň˙ÄîţĹëţÄçűČčýĎî˙Ńđ˙Ôń˙Ů÷˙Úř˙ŃńüÓóţŮ÷˙Řő˙Ďď˙Ęî˙˝é˙¶âý¸âúÄęýÉîţĐđ˙Ńđ˙Ëî˙ÁçüĽĺűłářŻŢř¤Őý Óţ›Ń˙‘ĚöÎ÷•ĐúšÔú§Üţ­ŢţŻŢü¬Ýý¤Ü˙™×˙ŃüŹÍţ‰Ë˙‚Çţ…Ę˙ŽĐ˙ŹĎ˙‘Îú–Ő˙™Ú˙§Ý˙­Ţţ·ć˙˝é˙Äí˙Úő˙Ůô˙ŘóüŮôýŰöýÚ÷ýÚ÷˙Úř˙Őő˙Öř˙Úú˙Ü÷˙Úř˙Ëđ˙Âë˙°ßý¨Řţ¦Řý®ß˙¶ĺ˙Áî˙ĆëţČí˙Çí˙Ľč˙¸ć˙łáűşć˙˝ç˙ÂčýČí˙Öö˙Ü÷˙áú˙éţ˙éţ˙äü˙ßú˙Îď˙Âčý˛Ţű¬Ü˙¦ŘýžŇůźÔţźŐ˙›Ô˙ĄÜ˙¨Ţ˙§Ű˙«Ţý­ŕý¬Ű÷ŻŢú·ăü˝çýÉî˙Óó˙Řö˙Ţů˙âű˙ç˙˙ç˙˙ę˙˙ěţ˙îý˙ďýţđţ˙đţ˙ďţ˙ë˙˙ë˙˙ßü˙Ů÷˙ŃńüÍîýÎď˙ĘîţĚíţÓđţŮöţŰö˙Ţ÷üßřýŢů˙Úö˙Ěđ˙Éď˙µáú¬Ű÷«Úřµä˙˝ë˙Ćě˙Âčýľč˙·ăţŻŢü¤ŮűśÓú’ĎüÎ˙‹Ę˙ŠË˙‘Đ˙‘Îű–Ńű§ß˙«á˙©ß˙ĄŰ˙›Ń˙—Ń˙ĚţŹÎ˙ĘţČ˙Ę˙ŚĎ˙ŤĎ˙’ĐůˇŮü§Ý˙±ŕţ´áţ»ĺţľć˙Ęđ˙Őń˙Ôń˙Ůő˙Ýů˙ŕý˙ŕý˙Üů˙Űů˙ÓóţŃó˙ÓóţÚ÷˙Üř˙Îň˙Çî˙¸ć˙ŻÝ˙«Ű˙°Ţ˙´ă˙»č˙Ĺë˙Ćě˙Âę˙ąĺţ¶äţµăý»ĺýżčţÇě˙Ęí˙Ďěúßú˙äý˙ĺúűçűüé˙˙ç˙˙Úř˙Đń˙˝ćü°ÝţŞŰü§Ůţ¦Ú˙§Ü˙¦Ű˙¤Ů˙¨Ü˙§Üü¬ßüŻáü˛ßü´âü»ĺýŔéýËď˙ŐóýŮöţŕůýăűýç˙˙ç˙˙ę˙˙í˙˙đ˙˙ô˙˙ôţ˙ďýţîţţë˙˙ë˙˙ě˙˙ç˙˙áý˙Üú˙Ůů˙Ňô˙ĐňţŐóţŕű˙ĺý˙ë˙˙ç˙˙áý˙Ţű˙Ńő˙Ëň˙µáúŞŮ÷¦×÷©Űţ°á˙˝ćú˝çýąĺţ´ă˙­ß˙ťÔű“ÎúÇú†Čü€Ĺţ|ÁüĆý‹ĘýŹÍü™ÔţťŘ˙ž×˙›Ö˙•Ď˙ĚţŹÍ˙ŠÉţ„Çű…Ë˙‡Í˙ĚýŠĘř—Ńů®ă˙µć˙¸ĺ˙¸ĺ˙»ĺţ˝ĺţĹë˙ÍěţÎîýÔń˙Řö˙Ýú˙Ýú˙Ýú˙Űů˙Öô˙ŃńţŇňýŘőýÚř˙Îň˙Čď˙»é˙®Ü˙ŞÚ˙°Ţ˙´ă˙ąç˙Ľćţ˝ĺţ»ĺţ´âü´âü¶äţĽćţŔéýĘí˙Íî˙Đíűßú˙ă˙˙çüýéýţę˙˙ç˙˙ßü˙×÷˙Ĺęýłŕý°Ţ˙ŞÜ˙«Ü˙©Ý˙§Ü˙ĄŮ˙«Ý˙«Ţý˛áý´ăý¶âý¸äýľçýĂéţÎďţŮő˙Ýř˙ăűýçüýéţ˙čýţë˙˙đ˙˙ň˙˙ő˙˙ő˙˙ňţţîüýěţ˙ěţ˙ë˙˙é˙˙ĺţ˙ŕý˙Űů˙ŇňýŃńüÖňýŢů˙ăü˙éţ˙äüüÝůýÜů˙Ďó˙Éď˙¶âűŞŘůĄÖ÷¦Řý¬ÝţĽćüżé˙ąĺ˙łá˙®ŕ˙ťÔý•Đü‹Ę˙†ÉţÄý{ŔűÄý‡Éý‹ËűŹÎú“Đý”Ńţ”Ńţ‘ÎýŽĚý‘Ď˙Ęţ…ÇűÎ˙ŠĐ˙ŚÎ˙ŚĚúšÔú˛ä˙¸ç˙ąć˙¸ĺ˙·ăţąăüŔé˙Ăç˙ĂçýÇęýĚíţÓóţÖôţ×ôü×óţŐóţÓđţÓďűÔđűÖôţÎňţĘń˙»ç˙°Ţ˙¬Ü˙¬Ü˙­Ţţ­ßúŻŢú°ßýŻŢüŻŢü˛áý·ăţŔč˙Ćě˙Îď˙Đđ˙Řö˙Űř˙ŕü˙é˙˙ë˙˙ę˙ţéţ˙ç˙˙ä˙˙×÷˙Ŕč˙şç˙°Ţ˙«Ű˙¨Ú˙§Ű˙«Ý˙±ß˙µâ˙»ĺýĽćţÁé˙Âë˙Čí˙Ëî˙×ô˙Ýř˙ăú˙çűüçűúéüúëýýí˙ţň˙ţő˙˙÷˙˙ö˙˙ô˙ţó˙ýđţţđţ˙íýüě˙ýęţýç˙˙áú˙ÖńúÖňýŮő˙Ü÷˙Ýöýč˙˙ç˙ýßűţÜů˙ĘîţÄę˙´áţ§×űŁŐú¦×˙¬Ü˙¸äý»ç˙µâ˙¬Ţ˙§Ű˙Ńţ’ĎţŠË˙…Ę˙{Ăý}ĆýĘ˙€Ç˙ÄýĂý‚ĂýÄú†ČüŚÎţŹĎ˙ŽÍ˙‰Ë˙†ČüŠÍ˙ŚĎ˙ŹÍü‘Îúˇ×ý¶ĺ˙şć˙¶ĺ˙´ă˙°Ţř˛ŕúşäüŔĺ˙żäţÂćüÇęýŇň˙Öô˙×óţ×óţ×óţŐńýÔđüÔđüÔňýĎó˙Ěó˙ąĺţ°Ţ˙­Ý˙«Ý˙¬Ţ˙«Ţý­Ţţ¬Ýţ«Üý«Üü±ŕü¶âýĂě˙Čî˙Îď˙Đđ˙Öö˙Űř˙Ýř˙äüţéţ˙ë˙ţé˙ýč˙˙č˙˙Üů˙Ćě˙Ŕę˙±Ţý¬Úü¨Ú˙©Ű˙­Ý˙łŕ˙·ăţ˝ćüľçýÂč˙ĂéţČëţÍî˙Öô˙ßřýăű˙éýţęüüęýůě˙ýď˙ţň˙ţő˙˙÷˙ţö˙ý÷˙˙ö˙˙ń˙˙đţţďţűď˙üě˙ýë˙˙äü˙ŮôűŘóüÚőţÜ÷˙Űö˙äüüäýúßü˙Űů˙Éî˙Âë˙±Ţý¤Ôú Ńů¤Ř˙¬Ý˙·ä˙ąć˙´â˙«ß˙§Ý˙–ĐţŽĚý†É˙Č˙|Äţ}Ćý€Ë˙|Ä˙zŔü|ŔýĂ˙Áű‚Ĺü‰ÍţŤĎ˙ŚËţŤĚ˙ĘţŠĚ˙ŤĎ˙ŽÍů“Îř¤Řýµä˙¸ä˙µä˙°âý®Ý÷˛ŕúąĺţ˝ć˙Ľĺ˙˝ăúŔäúĎđ˙Őő˙Ű÷˙Ü÷˙Ü÷˙Úő˙Ůó˙Öó˙ŐóţÍńýČđüĽé˙ŻÝţ­Ý˙«Ý˙©Ţ˙©ß˙§Ý˙˘Řţ˘Öý©Űţ°ßý»č˙Âë˙Çě˙ÎďţÎîýŇôţÜú˙Üů˙Üőůâúţę˙˙čý˙ę˙˙ę˙˙ăü˙Ńň˙Čě˙·ßů°Üů¬Ýţ­Ý˙Żŕ˙¸ä˙˝ç˙ĂéţÄéüÄčţĆéýŃň˙Đń˙ÖňýŢ÷üĺú˙éýţéýüě˙ýëýýě˙ýđ˙ýó˙˙ő˙˙ô˙ţő˙˙ó˙˙ń˙˙ďýţň˙ţď˙ţě˙ýę˙˙çü˙Ţ÷üŰôűÖńúÜ÷˙Ýř˙âţ˙ŢűůŮ÷˙Ő÷˙Ćě˙˝ć˙«ŮýťĐűťĐűˇÖ˙ŁŘ˙ŞÜ˙ŞÜ˙¨Ü˙˘Ů˙źŘ˙“Ń˙ŹÎ˙Č˙Ç˙‚Ę˙~É˙|Ç˙wÁţużţuĽţxż˙{Á˙{ÁüÉýŽŇ˙ŚÎ˙ŤĚ˙ŤĚ˙ŹÎ˙’Đ˙Ő˙›Ô˙¨Ú˙´á˙¶á˙˛ă˙Żâ˙Żáüµä˙şć˙»ç˙Ľĺ˙˝ăúżăůËěűĐđűÚ÷˙Ţů˙ßú˙Úő˙Řóţ×ô˙Ôô˙ĚđüĆîúąćű¬ÚűŞÚţĄŮţ˘Řü Řű¦Ý˙˘×˙ Őý¦Ú˙łâ˙¸ĺ˙Ŕé˙ĹëţĚđ˙ÎďţŃóýÚř˙Úř˙Úöúßřýčý˙ćű˙ĺúýĺý˙ăü˙Ôô˙Ěď˙˝ăú¶ŕůŻÝţ¬Ýţ°á˙ąć˙ľč˙Äę˙ĆëţĹé˙Ćé˙Îď˙Ďđ˙Öô˙ŕů˙äü˙éţ˙ë˙ţě˙˙í˙˙ěţţí˙ţđ˙ýó˙˙đ˙˙ń˙˙ň˙˙đ˙˙îţţđ˙˙ď˙ţí˙˙ě˙˙č˙˙ßřýÜőüÖńúÜ÷˙Ýř˙ŕü˙ÜúüÔőţĐô˙Áé˙¸ă˙ŞÚ˙ Ő˙ Ő˙ Ö˙ Ö˙ ŐýˇÖţźÖ˙›Ô˙™Ô˙‘Ď˙ŚË˙Č˙‚Č˙É˙~ÇţzĹţxÂ˙vŔ˙uż˙wľ˙|Â˙|Âţ‚É˙‹Ď˙ŚÎ˙ŽÍ˙ŽÍ˙Đ˙’Đ˙Ň˙šÓţ¦Ú˙±ß˙°Ýţ­ŢţŞÝü®ßý¶ĺ˙ľę˙Ŕč˙Áé˙Çë˙Éě˙ĐđűÔňüßú˙č˙˙č˙˙Ţ÷ţÚő˙Řő˙Óó˙ĚîúĹëřşĺř°ßý«Ű˙˘×˙ ×ţ›Őű›Ô˙ Ö˙źŐ˙˘Öý°á˙łŕýĽćţŔé˙Čí˙Ëđ˙Ńó˙Őő˙Ů÷˙Ű÷˙Űö˙ß÷˙ÝöýŰôůŢőűáú˙Ú÷˙×ő˙Ěď˙Âë˙°Ýü¨ŮúŞÜ˙¶ĺ˙ąĺ˙żčţĂé˙Ćě˙Ĺë˙Éî˙Ěď˙Óó˙Ű÷˙ßú˙äü˙ĺý˙č˙˙éţ˙éţ˙éţ˙éţ˙ę˙ţë˙˙ě˙˙ě˙˙ęý˙ęý˙éţ˙ćţ˙ĺý˙âúţářţŢ÷ţÚőüÔńůŘô˙Úö˙Üú˙Ö÷ţĘîţÄę˙µŕ˙¬Ü˙ˇÖ˙›Ó˙™Ó˙•Ďý‘Îű‘Îý’Ďţ’Ďţ‘ÎýŹÍţ‰ČýÄúĆý‚Ç˙}Ăţ}Ăţ}Ăţ|Ä˙|Ă˙yĂ˙v˝ű|Âţ|ÂýČ˙ŠÍ˙ŽÍ˙‘Ď˙’Đ˙“Ń˙“Đ˙“Íű–Ďü Ő˙¤Ř˙¦ŘýŞÜ˙ŞÜýŻŕ˙´ă˙¸ä˙ŔćýĂéţÎń˙Óô˙Úř˙Üů˙âţ˙ĺţ˙ĺţ˙ŕůţÜ÷˙Ňď˙ĎďţÎđúĘđűÂíţłâ˙ŞÚţźÔüžŐţšÓţ—Ń˙śÔ˙ťÖ˙Ł×ţ¬Ýţ±Ţý¸äýĽćţŔéýĹë˙Ďđ˙Óó˙Őő˙Ůő˙Řň˙Ůó˙Úô˙Ü÷˙Ü÷˙Űö˙ßřýßř˙Őő˙Ëđ˙±ŕü©ÚűĄ×ü­Ţţłâ˙»ĺţĽćţľč˙Âę˙Ĺë˙Çí˙Ëď˙Ôô˙Řö˙ŰřţŢúţăü˙âű˙ĺţ˙ć˙˙ă˙˙áýţäý˙ăü˙ăű˙ářţářţÜ÷ţŰř˙Ú÷ýŮôűÚőţÝř˙Üů˙Úö˙Řö˙Ů÷˙Ő÷˙ÎňţŔćű¸âű«Ř˙¦×˙™Ń˙ÍüŹÍüÎýŽÎţ‹Î˙ŠÍ˙‹Í˙ŚË˙ŚË˙ŚË˙‡Čţ‡Č˙†É˙Ć˙„Ć˙„Ć˙Ć˙Ćţ~ÇţzĂú|Ăű|Áú„Ć˙Î˙ŹÍ˙‘Ďţ’Đ˙’Đ˙’Ďţ“Íű•Ďý™Ň˙žÔ˙ˇ×˙¬Ţ˙­ß˙˛ŕ˙µâ˙ąĺ˙ÂćüĆëţĎó˙Óő˙ŘöţÚ÷ýŕůýŕůýäü˙ŕůţŰö˙Ńî˙ÎîýÎđúĚňýĆń˙¸ç˙°ŕ˙ĄÚ˙ˇŘ˙Ó˙Ň˙Đ˙™ŇýˇŐüŞŰüŻÜű·ăüąćýľéüĂě˙Ďđ˙Óó˙Ôô˙Öó˙×ň˙×ň˙Řô˙Úö˙Úö˙Ú÷˙âúţářţÖö˙Íň˙´ă˙¬ÝţŁ×üŞŰü±ß˙·ăţ¶âűąĺţ˝ç˙ľçýÄę˙ÉíýŃńţÓóţŘőýÚ÷ýßú˙Ţů˙Ýř˙ÜřüŰřüÜúüÜřüŰ÷űÝöűÝöýŢ÷ţŘőýŘö˙×őýÖóű×óţŰ÷˙Ű÷˙Úř˙Řö˙Őő˙Ňô˙Ëďýşăů±Ýú¦ÖţˇÔ˙–Î˙ŹÍţŹÍţŹĎýŚÎţÍ˙‡Ě˙Ë˙É˙Ęţ‹Ę˙ŠÉ˙†Çý…Čý…Ç˙…Ĺ˙„Ć˙Ć˙€Çý€Çý|ĂůÄű~Ăú…Ć˙ŤË˙ŹÍ˙’Ďţ’Ďţ’Ďţ‘Îý‘Îý“Đ˙™Ó˙›Ô˙ťÖ˙¨Ů˙ŞÚţŻÝ˙˛ß˙ąĺ˙Ćě˙Ëď˙Đń˙ŃîţÔňýÓńűŮ÷˙Řů˙ŰřüÝ÷řÝöűĐíűĎířÖôţŮ÷˙Ôö˙Éď˙Áë˙ŞÚţ Ôü™Ň˙•Ó˙”Đ˙•ĎýšĐüžÓű¨Ý˙©Ý˙­ß˙şć˙Áę˙Ěď˙Óó˙×ó˙ŮńűÚňüŮô˙Řô˙Řö˙Úö˙Ü÷˙áúţăü˙Űű˙Ńö˙·ä˙­Ţţ ÖüźÖý ×ţ¤Ű˙Şŕ˙¬ßţ­ŕý°ßűłáůľéüČď˙Ěń˙Ďó˙Îň˙ĚđţËđ˙Ęď˙Ęđ˙Çí˙Čî˙Ęď˙Íń˙Íń˙ĎďüĎďüŃńţÍîýĎđ˙ĚíţĚíţÎď˙Đń˙Ňó˙Íî˙ĘëüŔéýąćý«Üý¤Ú˙–ĐţŹĚű’Î˙ŽĚűŤÍű‹Ň˙‰Ď˙‹Ě˙É˙‡Ę˙Č˙‚Ç˙~Ä˙|Âţ‚Ç˙€Ĺ˙Ć˙Ć˙‚Ç˙‚Ç˙Ć˙Ćý€ĹţĹ˙‚ÄţĹ˙ŠÍ˙ŤĐ˙ŠÎ˙ŚĐ˙ŤĎ˙ŽÍ˙ŽĚ˙Î˙—Ô˙ś×˙ś×˙źÔţˇÔ˙ŞÜ˙ŻÝ˙µŕ˙Âç˙Çí˙Îď˙ĐíýŇđűŇđűÓő˙Öř˙Űú˙Ý÷řÜőůÔňýÓńűŮöţŰř˙×ő˙Ëî˙Ăë˙°Ţ˙ĄÖţ–Ďü’Đ˙’Î˙•Ď˙™ŇýźŐ˙ Ů˙¤Ů˙¨Ü˙¸ä˙żç˙Ęî˙Óó˙Ůő˙ÝôüÝôúÜ÷ţŰř˙Úö˙Úö˙Ýöýăü˙ŕü˙Řř˙Îó˙·ĺ˙®ß˙ˇŮţ›Őý™Ôţ™Ôţť×˙ĄŰ˙§Üţ«ÜüŻŢú¸ĺüÁę˙Äí˙Éď˙Čď˙ĹëţŔéýżčţÁë˙Ľč˙żé˙Ľć˙Áę˙Ĺë˙ÉíýĚđ˙Đń˙Íî˙Ěđ˙ČëţČë˙Éě˙Éî˙Ěń˙Ęď˙Çěţľč˙¸ć˙©Ý˙ Ú˙“Đ˙ŹĚű’ĎţŽÍůŽÎü‹Ň˙‰Ď˙ŚË˙É˙‡É˙É˙Ç˙{ĂţyŔţ~Ä˙}Ă˙Ĺ˙Ĺ˙Ć˙‚Ç˙Ć˙Ć˙€ĹţĹ˙Ĺ˙„Ć˙ŠÍ˙‰Ď˙‡ÍţÎ˙Ë˙ŠĚ˙ŽÍ˙Î˙“Đ˙™Ô˙›Ö˙źŐ˙ Ő˙¨Ü˙­Ý˙łŕ˙şăůŔéýĚđ˙ĎďţŇďýÎîýĚđţÎň˙Öö˙Ü÷ţÜ÷ţÚř˙Ů÷˙Ú÷˙ŮöţÓńüÍđ˙Ĺí˙¶ä˙«Ü˙–Ěú’Ďţ•Ďý—Đý›ŇűťÔýšÔüźÖý¤Řý˛áýşă˙Ăé˙ÍěţÔń˙Ţ÷üŢőűŢúţŢů˙ßú˙âű˙ćű˙ĺý˙ŢúţĎďúÇěţ¸ć˙łä˙žŐüŇú™Ôţ—Ňü—ŇüśŇţťÔýŁ×ţ¨Úý±Ţ˙¶â˙»ä˙ľç˙˝ç˙şă˙´ŕýłŕ˙¶ă˙˛ŕ˙˛Ţ˙°Ü˙łŢţ·ŕü˝ĺţĂé˙Ëđ˙Ëď˙Éî˙ÄčţÁçüÁć˙ľć˙żç˙Áë˙˝ç˙­Úů®Üţ§Ű˙ ×˙šÓţšÔüśÓü—Ńů“ÎúŽÎţŠĚţÇü†ÇýĘ˙É˙€Ć˙}Ĺ˙zÁ˙{Áý|ÂţĹ˙Ĺ˙€Ĺţ€Ĺţ€ĹţÄý€ĹţĹ˙Ĺ˙†Č˙ŠÍ˙Î˙‡Í˙‡Í˙„ÇüÉ˙ŹÎ˙ŽÍ˙ŹËý“Đý—Ń˙šÓ˙śŇ˙ŁŘ˙§Ř˙¬Úü¸âřŔéýĚđ˙ĎďţĎďţÍîýĘď˙ÉîţŃň˙Úö˙Űř˙Ů÷˙Úř˙Űř˙ŮöţÓńüĚď˙Ăë˙łá˙©Ű˙—Íů”Îü—Đý›ŃýžÓűžŐüśÖţźÖý˘Řţ­Ţü´ŕýŔé˙ËěýĐđýÜřüßřýáý˙áý˙âţ˙ĺţ˙ęţ˙ĺý˙ÝůýÍířĆëýąç˙łä˙ŁÚ˙šÓţÓ˙ÍůŹĚř•Ďý—ĐýźÔţ¤Ř˙ŞÚţłŕ˙µâ˙¸ă˙¸ă˙´á˙±Ţ˙ŻÝ˙°Ý˙«Ű˙¬Ů˙­Ú˙°Ü˙˛Ýýąâţľć˙Čí˙Éî˙Čí˙Ăé˙ľć˙»ä˙ąâţ¸ä˙¸ĺ˙łâţ¨Öř¨Řţ¤Ů˙źÖýśÖü Řý¤ÚţźŐűšŃúÍüŚĘý‡Ćű„Ĺű†Č˙Ç˙~Ä˙~Ć˙|Ă˙yżűzŔü}Ăţ€Ć˙Ć˙€ĹţÄý~ĂüĆ˙Ĺ˙„Ć˙‡É˙‰Ě˙†Ě˙†Ě˙…Ę˙Ćý‡ČţŽÍ˙ŽÍ˙ŹÍţ’Ďü“Đý–Đţ—ĎţźÔ˙˘Öţ©×ű»ćůÂë˙Ęď˙ĚíţĚíţÉíýÄę˙ÁçüÄéüÍěţĎěüÓńü×ő˙Űř˙Ú÷˙Öô˙Ęí˙Âë˙°Ţ˙¦Řý›Ńý—ĐýźŐ˙ŁŘ˙©Ý˙§Ţ˙¤Ű˙žŘ˙źÖý§Ůü®ÜýĽćţÍň˙Ôö˙Üřüâű˙č˙˙ç˙˙ç˙˙ę˙˙íýüë˙˙ăü˙ŇňýËď˙´âüŞŰűžŐü™Ôţ•Ňţ’Ďű”Ńţ‘Í˙‘Í˙šÓ˙žÔ˙ˇŐý§Ůţ¨Řţ©Ů˙ŞÚţŞÜ˙¬Ţ˙¨Ů˙¨Ů˙¤×˙¦Ú˙Ł×˙ŞÜ˙­Ţ˙µâ˙¸ĺ˙żčüĹëţÁęţĽć˙¶â˙¬ÚűŞŰü©Űţ¤Řý ÖúťĐűžŃţťÔýžÖű§Ţü¬âţ¸ę˙łä˙«Ý˙žÔ˙Ň˙‹Ę˙†Çý…Ç˙Ĺ˙}Ăţ|Ä˙|Ă˙xľú{Áý|ÂýĹ˙Ć˙Ć˙Ć˙Ć˙‚Ç˙‚ÄţĹ˙†Č˙…Ç˙‚Ç˙Ĺ˙…Ç˙…Č˙‡Č˙ŽÍ˙ŽÍ˙ŹÎ˙Î˙ŹÍţÎ˙Íü—ĐýśŃű¨Ú˙ľéüÄď˙Ěń˙Ëď˙Ëď˙Éî˙Âčý˝ćüÂćüÇčűÇçöĎěúÓńüŮő˙ŮöţÖô˙Ěđ˙Ćď˙łá˙¨Ú˙žŐţžÔ˙¤Ů˙§Ü˙ŞŢ˙¨ŕ˙¦Ý˙źŮ˙ ×ţ¨Úý°Ţ˙ąăüÎó˙Ő÷˙Ű÷űáúţĺ˙˙ĺ˙˙ç˙˙ę˙˙ď˙ţî˙˙ć˙˙Öô˙Ěđ˙˛Ţů¦×÷˘Ů˙›Ö˙•ŇţÍů’Ďü‘Ď˙’Î˙›Ó˙ž×˙ Őý¤Ř˙Ą×ü¦Řý§ŮţŞÜ˙ĄŮ˙ˇŐýˇÔ˙ Óţ˘×˙ĄŮ˙¬Ţ˙®ŕ˙´ă˙·ä˙˝ćúÂë˙żčţ¸ä˙łßü¨ÖřĄ×řŁ×üžÔúśÔůËřĚű›Ňűź×üŻĺ˙µé˙ľî˙şé˙°ŕ˙¤Ř˙žÖ˙ŤĚ˙‡Čţ…Ç˙Ĺ˙}Ăţ|Ä˙}Ä˙zŔü}Ă˙Ĺ˙~Ä˙€Ĺţ‚Ç˙Č˙Č˙‚Ç˙‚ÄţĹ˙†Č˙Ĺ˙Č˙Ĺ˙†Č˙‡Ę˙É˙ŹÎ˙ŽÍ˙ŤĚ˙ŽĚýŹÍţÎ˙ŹÍü–Ďü›Ńý©Ű˙ \ No newline at end of file diff --git a/libraries/ode-0.9/drawstuff/textures/wood.ppm b/libraries/ode-0.9/drawstuff/textures/wood.ppm new file mode 100644 index 0000000000..a53d2dca9a --- /dev/null +++ b/libraries/ode-0.9/drawstuff/textures/wood.ppm @@ -0,0 +1,5 @@ +P6 +# Created by Paint Shop Pro +256 256 +255 +ŰŰŰĐĐĐÇÇÇÉÉÉĚĚĚĚĚĚĚĚĚÍÍÍÎÎÎĐĐĐŃŃŃŃŃŃŃŃŃŃŃŃĐĐĐÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÍÍÍĘĘĘÉÉÉÇÇÇĂĂĂĚĚĚĚĚĚÇÇÇżżż°°°¬¬¬¸¸¸±±±±±±µµµ»»»»»»ĽĽĽÉÉÉŘŘŘŐŐŐÔÔÔŘŘŘâââęęęćććŘŘŘĘĘĘĂĂĂŃŃŃÜÜÜîîîîîîäääçççäääŮŮŮŰŰŰĐĐĐÇÇÇĹĹĹĽĽĽćććçççčččćććŰŰŰćććčččâââăăăŰŰŰčččçççćććăăăŕŕŕâââçççęęęęęęëëëîîîńńńňňňňňňńńńďďďëëëçççääääääčččęęęęęęççççççÝÝÝíííčččÎÎÎÂÂÂÂÂÂÇÇÇĆĆĆĹĹĹÂÂÂÂÂÂÂÂÂĂĂĂĹĹĹĹĹĹĹĹĹĆĆĆĹĹĹÎÎÎĹĹĹ°°°´´´······ÍÍÍŘŘŘĚĚĚ»»»ĽĽĽÇÇÇĐĐĐĘĘĘÉÉÉÎÎÎŔŔŔşşşľľľ¸¸¸ĽĽĽľľľĂĂĂżżżłłłłłłĽĽĽżżż¸¸¸ÂÂÂÉÉÉÇÇÇ»»»¸¸¸ĹĹĹŃŃŃŐŐŐŘŘŘŃŃŃĆĆĆŘŘŘăăăŇŇŇÉÉÉÉÉÉĆĆĆÍÍÍĘĘĘ»»»ÍÍÍäää×××ĐĐĐĐĐĐÔÔÔŘŘŘŘŘŘ×××ŇŇŇŃŃŃĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐÎÎÎĚĚĚĘĘĘÇÇÇĘĘĘÍÍÍĚĚĚŔŔŔşşşĹĹĹÇÇÇ»»»ÍÍÍĆĆĆÇÇÇĹĹĹ»»»»»»żżż¸¸¸¸¸¸żżżĂĂĂĂĂĂĆĆĆÇÇÇĂĂĂżżżĆĆƸ¸¸ÝÝÝçççŘŘŘÇÇÇĐĐĐÍÍÍŐŐŐÔÔÔäääíííßßßÝÝÝăăăÝÝÝÜÜÜŮŮŮŐŐŐŃŃŃÍÍÍĘĘĘÉÉÉĆĆĆĆĆĆÇÇÇÉÉÉĚĚĚĚĚĚÇÇÇĹĹĹŔŔŔĆĆĆÉÉÉĂĂø¸¸±±±±±±´´´łłłżżżÍÍÍŃŃŃĚĚĚÉÉÉÎÎÎŐŐŐŇŇŇĘĘĘĹĹĹÇÇÇĘĘĘĘĘĘĚĚĚÎÎÎÎÎÎĐĐĐĐĐĐŃŃŃŃŃŃŃŃŃĐĐĐĐĐĐĐĐĐÎÎÎÎÎÎÍÍÍĚĚĚĘĘĘĘĘĘÉÉÉÂÂÂÍÍÍÎÎÎÉÉÉŔŔŔ´´´­­­łłłłłł···şşş¸¸¸şşşŔŔŔÍÍÍ×××ŇŇŇÔÔÔŮŮŮâââčččćććŰŰŰĐĐĐĚĚĚÎÎÎŃŃŃâââęęęćććçççŕŕŕßßßÜÜÜŃŃŃĚĚĚĹĹŸ¸¸ßßßçççßßßŕŕŕŰŰŰăăăäääÝÝÝăăăŕŕŕßßßâââćććçççççççççęęęíííęęęęęęčččçççćććäääääääääăăăßßßÝÝÝßßßâââăăăâââßßßăăăÜÜÜčččŰŰŰĽĽĽ»»»ŔŔŔŔŔŔĆĆĆĆĆĆĹĹĹĂĂĂĂĂĂĂĂĂĆĆĆÇÇÇÇÇÇÉÉÉÉÉÉĘĘĘŔŔŔ±±±´´´»»»żżżĚĚĚĐĐĐĆĆĆżżżĆĆĆÍÍÍĐĐĐÍÍÍĚĚĚĚĚĚĽĽĽşşşŔŔŔ»»»ŔŔŔŔŔŔĂĂĂżżż¸¸¸şşşÂÂÂĂĂĂżżżľľľÂÂÂŔŔŔşşşĽĽĽĚĚĚ×××ŘŘŘŐŐŐÎÎÎÂÂÂŇŇŇÝÝÝĐĐĐĘĘĘĘĘĘÇÇÇÂÂÂĂĂĂÂÂÂÔÔÔâââŇŇŇÍÍÍŃŃŃÔÔÔŐŐŐŐŐŐŇŇŇĐĐĐÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÍÍÍĘĘĘÉÉÉÇÇÇĹĹĹÉÉÉĐĐĐĘĘĘ»»»¸¸¸ŔŔŔĂĂõµµ´´´żżżĆĆĆĽĽĽµµµşşşĽĽĽŔŔŔĂĂĂĂĂĂĂĂĂĆĆĆÇÇÇŔŔŔ¸¸¸ÉÉÉżżż±±±ŇŇŇŰŰŰŃŃŃÇÇÇŇŇŇÇÇÇŐŐŐĐĐĐäääçççÝÝÝÝÝÝŕŕŕÝÝÝÜÜÜŮŮŮŐŐŐŃŃŃÍÍÍĘĘĘÉÉÉÇÇÇÉÉÉÉÉÉĘĘĘĚĚĚĘĘĘÇÇÇĹĹĹÂÂÂÉÉÉĐĐĐŃŃŃÍÍÍÉÉÉĘĘĘÍÍÍĘĘĘÉÉÉĘĘĘÍÍÍŃŃŃŃŃŃÎÎÎĘĘĘÇÇÇĹĹĹĂĂĂĆĆĆÇÇÇÉÉÉĘĘĘÎÎÎÎÎÎÎÎÎĐĐĐŃŃŃŃŃŃŃŃŃŃŃŃĐĐĐĐĐĐĐĐĐÍÍÍĚĚĚĚĚĚĚĚĚĚĚĚÍÍÍÇÇÇĐĐĐĐĐĐÇÇÇľľľ´´´°°°´´´···ľľľľľľ······ĂĂĂŃŃŃŐŐŐŃŃŃŇŇŇŮŮŮâââçççćććßßßŘŘŘŇŇŇĚĚĚĹĹĹŃŃŃçççćććçççÝÝÝŕŕŕŮŮŮĐĐĐÎÎÎĂĂø¸¸ÝÝÝęęęŕŕŕăăăßßßäääâââŰŰŰâââăăăăăăçççęęęęęęçççćććčččíííóóóóóóďďďęęęăăăŕŕŕŕŕŕăăăëëëçççäääćććęęęëëëęęęčččćććßßßíííŘŘŘ´´´şşşĹĹĹżżżĆĆĆÇÇÇÇÇÇĆĆĆĂĂĂĂĂĂĆĆĆĘĘĘÇÇÇÉÉÉĚĚĚ···´´´µµµżżżĚĚĚĚĚĚÇÇÇÂÂÂĆĆĆŃŃŃŐŐŐŃŃŃŃŃŃĐĐĐÉÉÉ»»»ÂÂÂÉÉÉĂĂĂĘĘĘÎÎÎĚĚĚÇÇÇĹĹĹĹĹĹĹĹĹĂĂĂÂÂÂĂĂĂĆĆĆĂĂĂľľľÂÂÂÎÎÎŐŐŐÔÔÔÎÎÎĚĚĚĹĹĹÔÔÔÝÝÝÎÎÎÇÇÇÇÇÇÇÇÇĽĽĽĹĹĹŃŃŃ×××ŘŘŘĐĐĐÎÎÎŇŇŇŇŇŇŇŇŇŃŃŃÍÍÍĚĚĚĘĘĘĚĚĚÍÍÍÍÍÍÍÍÍĚĚĚĘĘĘÉÉÉĆĆĆĆĆĆĂĂĂŔŔŔĚĚĚŃŃŃŔŔŔ´´´»»»ĹĹĹĆĆĆľľľżżżĹĹĹ»»»°°°µµµľľľľľľľľľŔŔŔĂĂĂÉÉÉÍÍÍÇÇÇĽĽĽĘĘĘżżżŻŻŻÎÎÎŐŐŐÎÎÎÉÉÉŇŇŇŔŔŔ×××ĘĘĘćććŕŕŕÝÝÝßßßßßßÜÜÜŰŰŰŘŘŘŐŐŐŃŃŃÎÎÎĚĚĚĘĘĘĘĘĘĚĚĚÍÍÍÍÍÍĘĘĘÇÇÇĆĆĆĆĆĆżżżĂĂĂĘĘĘĐĐĐĐĐĐÎÎÎÎÎÎÎÎÎĘĘĘĂĂĂżżżĹĹĹĐĐĐŐŐŐŇŇŇĚĚĚŔŔŔÂÂÂĹĹĹĆĆĆĆĆĆĆĆĆĘĘĘÍÍÍÍÍÍÎÎÎÎÎÎĐĐĐĐĐĐŃŃŃŃŃŃŃŃŃŃŃŃĐĐĐÍÍÍĘĘĘĘĘĘĚĚĚÎÎÎĐĐĐŇŇŇĐĐĐĚĚĚÇÇÇżżżłłłłłłşşş»»»żżżľľľ···¸¸¸ÂÂÂÎÎÎÔÔÔĐĐĐŇŇŇŮŮŮŕŕŕäääćććăăăŕŕŕ×××ĚĚĚŔŔŔĘĘĘćććäääçççÝÝÝŘŘŘ×××ĐĐĐĚĚĚÂÂÂĂĂĂâââíííŕŕŕŰŰŰŐŐŐŐŐŐŃŃŃĚĚĚÎÎÎŇŇŇĚĚĚĐĐĐŇŇŇÔÔÔŐŐŐŰŰŰäääííířřřůůůöööńńńčččäääćććčččęęęäääßßßÝÝÝâââćććččččččçççßßßíííŮŮŮłłł¸¸¸ĹĹĹżżżĹĹĹÇÇÇÇÇÇĆĆĆÂÂÂÂÂÂĆĆĆĘĘĘĆĆĆĆĆĆĚĚĚşşş°°°¸¸¸»»»ÇÇÇÔÔÔÎÎÎĹĹĹŔŔŔÇÇÇÔÔÔ×××ŇŇŇĐĐĐŇŇŇÇÇÇŔŔŔÍÍÍÔÔÔÎÎÎŇŇŇŇŇŇÍÍÍÍÍÍŃŃŃĐĐĐÉÉÉĹĹĹĹĹĹĘĘĘÍÍÍĘĘĘĂĂĂŔŔŔĹĹĹÉÉÉÉÉÉżżżĹĹĹĆĆĆŰŰŰäääŐŐŐÎÎÎÍÍÍĆĆĆÂÂÂŇŇŇßßßÔÔÔĚĚĚĐĐĐÔÔÔÔÔÔŇŇŇŃŃŃÍÍÍÉÉÉÇÇÇÇÇÇĘĘĘĚĚĚĚĚĚĘĘĘÉÉÉÇÇÇĆĆĆĹĹĹĂĂĂÇÇÇĽĽĽŔŔŔĚĚĚÉÉÉżżżĽĽĽ»»»ÍÍÍ»»»ľľľżżżľľľżżżŔŔŔŔŔŔŔŔŔĆĆĆÇÇÇĆĆĆÉÉÉĆĆĆĽĽĽÇÇÇżżż´´´ŐŐŐŰŰŰÔÔÔĚĚĚĐĐĐżżżŘŘŘÉÉÉčččÝÝÝßßßâââßßßÜÜÜŰŰŰŘŘŘŐŐŐŃŃŃÎÎÎĚĚĚĘĘĘĚĚĚÍÍÍÎÎÎÍÍÍÉÉÉĆĆĆĆĆĆĆĆĆżżżŔŔŔŔŔŔĂĂĂĂĂĂŔŔŔĽĽĽşşş······¸¸¸ľľľĂĂĂĘĘĘÎÎÎĐĐĐżżżĂĂĂĆĆĆĆĆĆĹĹĹĆĆĆÉÉÉĚĚĚÍÍÍÍÍÍÍÍÍÍÍÍÎÎÎĐĐĐĐĐĐŃŃŃŃŃŃĐĐĐÍÍÍĘĘĘĚĚĚÍÍÍŃŃŃŇŇŇ×××ĚĚĚĘĘĘŃŃŃÇÇǵµµłłłĽĽĽľľľşşş¸¸¸şşş»»»ľľľÇÇÇŇŇŇŃŃŃÔÔÔŘŘŘÝÝÝâââäääććććććÔÔÔÎÎÎĆĆĆĘĘĘčččŕŕŕćććßßßŇŇŇŮŮŮŇŇŇÉÉÉŔŔŔŃŃŃççççççćććŘŘŘĐĐĐĚĚĚĚĚĚĘĘĘÉÉÉĘĘĘÉÉÉĚĚĚÍÍÍÎÎÎĐĐĐŐŐŐÝÝÝäääëëëîîîńńńîîîčččććććććčččćććßßßŐŐŐŃŃŃŐŐŐÝÝÝăăăćććŕŕŕ×××ćććŘŘصµµ´´´ĽĽĽ»»»ĂĂĂĹĹĹĆĆĆĂĂĂŔŔŔżżżĂĂĂÉÉÉÉÉÉÉÉÉĚĚ̸¸¸łłłÂÂÂÇÇÇÔÔÔŇŇŇÎÎÎĆĆĆŔŔŔĂĂĂĘĘĘÍÍÍĚĚĚÉÉÉÍÍÍĹĹĹĹĹĹÔÔÔŮŮŮŐŐŐŃŃŃŔŔŔŔŔŔÇÇÇŇŇŇÔÔÔĚĚĚÇÇÇĘĘĘĘĘĘĐĐĐĐĐĐÉÉÉŔŔŔŔŔŔĆĆĆÉÉÉÍÍÍÔÔÔŇŇŇßßßăăăĐĐĐÉÉÉÇÇÇÍÍÍŃŃŃßßßăăăÔÔÔÍÍÍÔÔÔÔÔÔÔÔÔŇŇŇĐĐĐĚĚĚÇÇÇĆĆĆÇÇÇÉÉÉĘĘĘÉÉÉÇÇÇĆĆĆĹĹĹĂĂĂĂĂĂÂÂÂÇÇÇĽĽĽľľľĆĆĆÉÉÉÉÉÉŔŔŔłłłżżżÂÂÂŔŔŔżżżĂĂĂÇÇÇŔŔŔ¸¸¸ľľľÂÂÂĚĚĚĚĚĚĹĹĹĆĆĆÉÉÉŔŔŔÇÇÇżżż¸¸¸ŮŮŮÜÜÜ×××ÍÍÍÍÍÍĂĂĂŐŐŐĚĚĚëëëßßßââââââŕŕŕŰŰŰŰŰŰŘŘŘŐŐŐŃŃŃÎÎÎĚĚĚĚĚĚĚĚĚÍÍÍÎÎÎĚĚĚÇÇÇĹĹĹĹĹĹĆĆĆĹĹĹÂÂÂľľľĽĽĽľľľĽĽĽ···´´´±±±µµµşşş»»»»»»»»»ŔŔŔĹĹĹżżżĂĂĂĆĆĆĹĹĹĂĂĂĆĆĆÉÉÉÉÉÉĘĘĘĘĘĘĘĘĘĚĚĚÍÍÍÎÎÎĐĐĐŃŃŃŃŃŃÎÎÎÍÍÍĚĚĚĚĚĚÎÎÎŇŇŇÔÔÔŇŇŇÉÉÉÎÎÎŮŮŮŃŃŃľľľµµµ¸¸¸ĽĽĽ······ĽĽĽľľľĽĽĽĂĂĂÎÎÎŐŐŐŐŐŐ×××ŮŮŮßßßăăăćććçççŇŇŇĐĐĐĚĚĚĚĚĚíííÝÝÝâââÝÝÝÔÔÔŰŰŰŇŇŇÉÉÉÂÂÂÝÝÝęęęŕŕŕčččŮŮŮŇŇŇĐĐĐŇŇŇ×××ŃŃŃÔÔÔŘŘŘŰŰŰŰŰŰŰŰŰŰŰŰŮŮŮŰŰŰŰŰŰŕŕŕäääęęęíííëëëęęęęęęëëëęęęâââŮŮŮ×××ŰŰŰăăăčččęęęÝÝÝ×××âââ××׼ĽĽşşşĽĽĽżżżĂĂĂĹĹĹĹĹĹĂĂĂŔŔŔŔŔŔĂĂĂÇÇÇĚĚĚĚĚĚĘĘĘľľľ»»»ÉÉÉÔÔÔßßßĐĐĐÎÎÎÉÉÉĂĂĂŔŔŔŔŔŔĂĂĂĂĂĂÂÂÂĹĹĹÂÂÂĘĘĘÔÔÔ×××ŐŐŐÇÇǸ¸¸ĽĽĽĆĆĆĐĐĐÎÎÎÇÇÇĹĹĹÉÉÉĐĐĐŐŐŐ×××ÔÔÔÎÎÎĐĐĐŐŐŐŰŰŰŰŰŰŕŕŕŘŘŘŮŮŮŘŘŘÇÇÇĆĆĆÉÉÉŘŘŘÝÝÝŕŕŕăăăÜÜÜ×××ŘŘŘĐĐĐŐŐŐÔÔÔŃŃŃĚĚĚÇÇÇĆĆĆÉÉÉĚĚĚÉÉÉÉÉÉĆĆĆĹĹĹĂĂĂÂÂÂÂÂÂÂÂÂÂÂÂżżżÂÂÂĂĂĂĂĂĂÇÇÇĹĹŵµµşşşÉÉÉĚĚĚĂĂĂÂÂÂÇÇÇĆĆĆĂĂĂĹĹĹĆĆĆŃŃŃĐĐĐĂĂĂĂĂĂĆĆĆ»»»ÉÉÉżżż···××××××ŐŐŐĐĐĐÎÎÎĚĚĚÎÎÎÎÎÎëëëâââäääŕŕŕâââŰŰŰŮŮŮŘŘŘŐŐŐŃŃŃÎÎÎÍÍÍĚĚĚĚĚĚĚĚĚĘĘĘÉÉÉĆĆĆĹĹĹĂĂĂĂĂĂŔŔŔĽĽĽşşşşşşĽĽĽľľľ»»»¸¸¸µµµ···¸¸¸»»»ĽĽĽĽĽĽĽĽĽĽĽĽľľľÂÂÂĂĂĂŔŔŔŔŔŔĆĆĆÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉĘĘĘÍÍÍÎÎÎĐĐĐĐĐĐÎÎÎÍÍÍÍÍÍÎÎÎĐĐĐŇŇŇŐŐŐŃŃŃÍÍÍÔÔÔŘŘŘĐĐĐĆĆĆżżż······¸¸¸»»»ľľľżżżÂÂÂĆĆĆÉÉÉŮŮŮ×××ŐŐŐ×××ÜÜÜâââććććććÔÔÔŃŃŃÍÍÍĘĘĘďďďÜÜÜßßßŮŮŮ×××ŐŐŐÍÍÍĚĚĚĘĘĘčččëëëŕŕŕÝÝÝŇŇŇÔÔÔŃŃŃŇŇŇŐŐŐÎÎÎŐŐŐÎÎÎÎÎÎŃŃŃÔÔÔŘŘŘŰŰŰÜÜÜÜÜÜßßßăăăçççëëëîîîîîîîîîíííâââÝÝÝŰŰŰÜÜÜŕŕŕääääääăăăÜÜÜÝÝÝŕŕŕĚĚĚĽĽĽŔŔŔÂÂÂĆĆĆĆĆĆĹĹĹĹĹĹĂĂĂÂÂÂĂĂĂĹĹĹĆĆĆĚĚĚĚĚĚÂÂÂľľľľľľĆĆĆ×××ÜÜÜŇŇŇŇŇŇŃŃŃÎÎÎÉÉÉĹĹĹĂĂĂĂĂĂĹĹĹĹĹĹĆĆĆŇŇŇŇŇŇÔÔÔ××׿żżĽĽĽĹĹĹÎÎÎŃŃŃĚĚĚĆĆĆÇÇÇÍÍÍŘŘŘ×××ÔÔÔÔÔÔÔÔÔŐŐŐŘŘŘŮŮŮÉÉÉŃŃŃĘĘĘĐĐĐŇŇŇĚĚĚÔÔÔÝÝÝŮŮŮäääŕŕŕćććäääŮŮŮŘŘŘŇŇŇŐŐŐŐŐŐŇŇŇÍÍÍĘĘĘÉÉÉĘĘĘÍÍÍÉÉÉÇÇÇĆĆĆĂĂĂÂÂÂÂÂÂÂÂÂÂÂÂŔŔŔŔŔŔĹĹĹĹĹĹŔŔŔĹĹĹĆĆĆĽĽĽłłłÂÂÂĆĆĆŔŔŔĹĹĹĘĘĘĐĐĐ×××ŇŇŇĚĚĚŃŃŃĐĐĐĂĂĂĂĂĂ°°°ÍÍÍ»»»ŮŮŮŘŘŘŘŘŘŐŐŐĐĐĐÔÔÔĆĆĆŃŃŃčččćććăăăŰŰŰŕŕŕŰŰŰŮŮŮ×××ŐŐŐŃŃŃĐĐĐÍÍÍĚĚĚĘĘĘÉÉÉĆĆĆĹĹĹĹĹĹĂĂĂĂĂĂÂÂÂşşş¸¸¸µµµ···»»»»»»şşş···µµµµµµ···şşşľľľŔŔŔŔŔŔżżż»»»żżżżżżĽĽĽżżżĆĆĆĘĘĘÇÇÇÉÉÉÇÇÇÇÇÇÇÇÇÉÉÉĚĚĚÎÎÎĐĐĐÎÎÎÎÎÎÍÍÍÍÍÍÎÎÎŃŃŃÔÔÔŐŐŐÔÔÔÔÔÔŐŐŐĐĐĐÇÇÇĚĚĚÉÉÉşşşłłłşşşżżżľľľŔŔŔÇÇÇÉÉÉĹĹĹÜÜÜŘŘŘÔÔÔŐŐŐŰŰŰâââäääćććŐŐŐŃŃŃĚĚĚÇÇÇńńńÜÜÜÝÝÝŐŐŐŐŐŐÎÎÎĆĆĆÍÍÍŃŃŃďďďíííäääŰŰŰŐŐŐÝÝÝŰŰŰŘŘŘŘŘŘĐĐĐŮŮŮŐŐŐŃŃŃÍÍÍÎÎÎÔÔÔŮŮŮÜÜÜÝÝÝÝÝÝßßßăăăçççęęęëëëëëëęęęÜÜÜÜÜÜßßßäääččččččăăăÝÝÝŐŐŐÝÝÝŘŘŘşşşłłłżżżŔŔŔĂĂĂÇÇÇĆĆĆĹĹĹĂĂĂĹĹĹĆĆĆĆĆĆÇÇÇÇÇÇÇÇǸ¸¸şşşĽĽĽżżżŃŃŃŐŐŐŰŰŰŰŰŰŰŰŰŮŮŮŐŐŐĐĐĐĘĘĘÇÇÇÍÍÍĘĘĘÍÍÍŰŰŰÔÔÔÔÔÔŰŰŰĽĽĽżżżĘĘĘÔÔÔÔÔÔÎÎÎÎÎÎŐŐŐÜÜÜŘŘŘĐĐĐĆĆĆĹĹĹÉÉÉĘĘĘĆĆĆŔŔŔÂÂÂÍÍÍÉÉÉÍÍÍĐĐĐÉÉÉŃŃŃŮŮŮŐŐŐćććăăăęęęčččŐŐŐÔÔÔŮŮŮ×××ŐŐŐŇŇŇĐĐĐĚĚĚĘĘĘÍÍÍÎÎÎÉÉÉÇÇÇĆĆĆĂĂĂÂÂÂŔŔŔÂÂÂÂÂÂĹĹĹżżżŔŔŔĹĹĹÂÂÂĹĹĹĆĆĆżżżłłłĽĽĽżżżĂĂĂĘĘĘĹĹĹľľľŔŔŔżżż···żżżĘĘĘĚĚĚ×××ŘŘŘĂĂĂÎÎÎĆĆĆÂÂÂâââŕŕŕßßßŮŮŮŃŃŃŘŘŘżżżŇŇŇćććçççăăă×××ŕŕŕŰŰŰŮŮŮ×××ŐŐŐŃŃŃĐĐĐÍÍÍĚĚĚÉÉÉĆĆĆĂĂĂĂĂĂĂĂĂĂĂĂÂÂÂŔŔŔĽĽĽ»»»şşş»»»»»»şşşµµµ±±±···¸¸¸şşşşşşşşş»»»ľľľŔŔŔżżżŔŔŔżżż»»»ĽĽĽĂĂĂĆĆĆĹĹĹĘĘĘÉÉÉÇÇÇÉÉÉĚĚĚÎÎÎÎÎÎÍÍÍŇŇŇŃŃŃÎÎÎÍÍÍÍÍÍÍÍÍÎÎÎĐĐĐÎÎÎŐŐŐŇŇŇÇÇÇÇÇÇÎÎÎĚĚĚŔŔŔłłłµµµşşşĽĽĽľľľŔŔŔĹĹĹÇÇÇâââÜÜÜŐŐŐŇŇŇ×××ÜÜÜŕŕŕâââ×××ĐĐĐŃŃŃĘĘĘńńńŕŕŕÝÝÝŰŰŰĐĐĐĚĚĚßßßęęęčččëëëçççęęęŰŰŰŮŮŮŘŘŘŐŐŐÔÔÔŇŇŇŇŇŇŃŃŃÎÎÎŇŇŇŐŐŐŘŘŘŮŮŮŮŮŮÜÜÜßßßŘŘŘâââäääŕŕŕäääîîîëëëßßßçççßßßăăăčččćććââââââßßßŮŮŮ×××ĚĚĚĽĽĽ¸¸¸ÂÂÂÇÇÇĹĹĹÉÉÉĹĹĹÇÇÇÉÉÉĹĹĹÇÇÇĚĚĚÉÉÉĐĐĐĆĆĆľľľżżżÂÂÂÂÂÂżżżżżżŔŔŔĂĂĂÉÉÉŃŃŃŮŮŮÜÜÜŘŘŘŇŇŇŇŇŇŃŃŃŐŐŐ×××ŃŃŃÔÔÔÎÎÎĽĽĽÍÍÍŘŘŘÍÍÍÍÍÍŐŐŐßßßßßßĆĆĆÇÇÇÇÇÇĹĹĹżżżĽĽĽÂÂÂĹĹĹľľľŔŔŔĆĆĆĆĆĆĂĂĂĚĚĚÜÜÜßßß×××ŮŮŮÜÜÜÝÝÝÜÜÜŮŮŮ××××××ŘŘŘŐŐŐŃŃŃÎÎÎÎÎÎĐĐĐŃŃŃĐĐĐÎÎÎĚĚĚÉÉÉĂĂĂżżżĽĽĽ»»»ĽĽĽľľľľľľĆĆĆĆĆĆÂÂÂÂÂÂĂĂĂĚĚĚŰŰŰĂĂĂşşşľľľÎÎÎÂÂÂÍÍÍÎÎÎÇÇÇĂĂĂĚĚĚÉÉÉĆĆĆĘĘĘĚĚĚÎÎÎŰŰŰĘĘĘĆĆƸ¸¸ßßßŮŮŮŰŰŰÍÍÍŇŇŇ×××ŘŘŘĆĆĆăăăăăăŰŰŰŰŰŰÔÔÔŘŘŘŐŐŐŇŇŇŃŃŃĐĐĐÍÍÍĘĘĘĆĆĆÇÇÇĆĆĆĆĆĆĹĹĹĂĂĂÂÂÂŔŔŔżżż»»»¸¸¸¸¸¸»»»şşş´´´´´´¸¸¸şşşşşşşşşşşş»»»ĽĽĽľľľżżżľľľŔŔŔŔŔŔľľľżżżĹĹĹĆĆĆĹĹĹÉÉÉÇÇÇÇÇÇĘĘĘÍÍÍÎÎÎÎÎÎÍÍÍŃŃŃĐĐĐÎÎÎÎÎÎÍÍÍÍÍÍÎÎÎÎÎÎĚĚĚÎÎÎÍÍÍÉÉÉĘĘĘĐĐĐÎÎÎÇÇÇÂÂÂżżż»»»şşşľľľĂĂĂĆĆĆÇÇÇŮŮŮŮŮŮŰŰŰÜÜÜÝÝÝÜÜÜŰŰŰŮŮŮĐĐĐĘĘĘÍÍÍÉÉÉíííÝÝÝŰŰŰŘŘŘĐĐĐÎÎÎăăăíííëëëíííćććäää×××××××××ŐŐŐÔÔÔÔÔÔŇŇŇŇŇŇÎÎÎÎÎÎĐĐĐŃŃŃŇŇŇ×××ŰŰŰßßßÝÝÝââââââßßßâââęęęëëëçççčččâââçççîîîčččăăăŕŕŕŰŰŰÜÜÜÎÎÎÂÂÂľľľżżżÂÂÂĹĹĹÇÇÇÉÉÉĹĹĹÇÇÇÉÉÉĆĆĆÉÉÉÍÍÍĘĘĘÎÎÎĹĹĹľľľŔŔŔĹĹĹĹĹĹĹĹĹĹĹĹĂĂĂĂĂĂĹĹĹÇÇÇĚĚĚŇŇŇŮŮŮÝÝÝŐŐŐŇŇŇÔÔÔÔÔÔŇŇŇŇŇŇĚĚĚŔŔŔÉÉÉÔÔÔĚĚĚĚĚĚŃŃŃŘŘŘŕŕŕŇŇŇÇÇÇĆĆĆÂÂÂÂÂÂĚĚĚŇŇŇŇŇŇĐĐĐÂÂÂĹĹĹĆĆĆÇÇÇĐĐĐŰŰŰÝÝÝ×××ÔÔÔŐŐŐ×××ŐŐŐÔÔÔŇŇŇÔÔÔŐŐŐŇŇŇŃŃŃĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐÍÍÍÉÉÉĂĂĂżżżľľľľľľľľľľľľÂÂÂĹĹĹĂĂĂĹĹĹÇÇÇĂĂĂĂĂĂÎÎÎÉÉÉ»»»»»»ĐĐĐĂĂĂĚĚĚÎÎÎŃŃŃŇŇŇÔÔÔÎÎÎÎÎÎÔÔÔŇŇŇÍÍÍĐĐĐÍÍÍÍÍÍżżżâââŰŰŰŰŰŰĐĐĐÔÔÔ×××ŮŮŮÉÉÉăăăŕŕŕŮŮŮŮŮŮÔÔÔ×××ŐŐŐŇŇŇŃŃŃĐĐĐÍÍÍÉÉÉĆĆĆĆĆĆĆĆĆĹĹĹĂĂĂÂÂÂŔŔŔżżżżżż»»»······şşşşşşµµµµµµ¸¸¸¸¸¸¸¸¸şşşşşş»»»ĽĽĽżżżżżż»»»żżżÂÂÂŔŔŔĂĂĂĆĆĆÇÇÇĹĹĹÇÇÇÇÇÇÉÉÉĚĚĚÎÎÎĐĐĐÎÎÎÍÍÍÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÍÍÍÍÍÍÉÉÉÇÇÇÇÇÇĘĘĘÍÍÍÎÎÎÎÎÎÎÎÎÇÇÇŔŔŔ»»»»»»ÂÂÂĹĹĹĂĂĂŔŔŔĐĐĐÔÔÔŮŮŮÝÝÝÜÜÜŘŘŘÔÔÔŃŃŃĚĚĚÉÉÉĚĚĚÉÉÉçççÜÜÜŰŰŰŘŘŘŃŃŃŇŇŇćććîîîíííîîîăăăÜÜÜÔÔÔÔÔÔŐŐŐŐŐŐŐŐŐÔÔÔŇŇŇŃŃŃ×××ŐŐŐÔÔÔÔÔÔŘŘŘßßßăăăćććăăăâââßßßÜÜÜÝÝÝăăăęęęďďďëëëäääçççęęęćććâââßßßŘŘŘŮŮŮĹĹŸ¸¸ÂÂÂÇÇÇÂÂÂĂĂĂĘĘĘÇÇÇĂĂĂÇÇÇÉÉÉĆĆĆĘĘĘÎÎÎĚĚĚÉÉÉżżżşşşľľľÂÂÂĂĂĂÂÂÂÂÂÂÂÂÂĂĂĂĂĂĂÂÂÂĂĂĂĘĘĘ×××âââŰŰŰŮŮŮ×××ŘŘŘŰŰŰÔÔÔĚĚĚĚĚĚÂÂÂĘĘĘĆĆĆĆĆĆĆĆĆÇÇÇÎÎÎĘĘĘĚĚĚĘĘĘÂÂÂĆĆĆŘŘŘŮŮŮÔÔÔŮŮŮĹĹĹĆĆĆÉÉÉÎÎÎŐŐŐŮŮŮŮŮŮ×××ÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍÎÎÎŃŃŃŇŇŇÎÎÎĐĐĐŃŃŃŃŃŃĐĐĐĐĐĐĐĐĐĐĐĐÎÎÎÉÉÉĂĂĂżżżżżżŔŔŔżżżżżżľľľżżżżżżĂĂĂĘĘĘĹĹĹŔŔŔĆĆĆÔÔÔĹĹĹĆĆĆÜÜÜÎÎÎĚĚĚÉÉÉÍÍÍĆĆĆĐĐĐŇŇŇĐĐĐÍÍÍÇÇÇÉÉÉĐĐĐĘĘĘĐĐĐÉÉÉäääÝÝÝßßßŘŘŘÜÜÜ×××ŰŰŰÍÍÍâââÜÜÜ××××××ŐŐŐ×××ÔÔÔŇŇŇŃŃŃĐĐĐÍÍÍÉÉÉĆĆĆĆĆĆĹĹĹĂĂĂÂÂÂŔŔŔżżżżżżľľľ¸¸¸µµµµµµşşşşşş······şşş¸¸¸¸¸¸¸¸¸şşş»»»ľľľżżżŔŔŔ»»»ŔŔŔĂĂĂÂÂÂĂĂĂÇÇÇÉÉÉĆĆĆĆĆĆÇÇÇÉÉÉÍÍÍĐĐĐŃŃŃÎÎÎÍÍÍĚĚĚÍÍÍÎÎÎĐĐĐĐĐĐÎÎÎĚĚĚĘĘĘĘĘĘĆĆĆĆĆĆĚĚĚÎÎÎĚĚĚĚĚĚÎÎÎÉÉÉ»»»¸¸¸ĽĽĽŔŔŔŔŔŔżżżÉÉÉÍÍÍŃŃŃŇŇŇŃŃŃĐĐĐĐĐĐĐĐĐĐĐĐÍÍÍÎÎÎĘĘĘăăăÜÜÜÜÜÜŰŰŰŇŇŇÔÔÔćććëëëčččëëëŕŕŕ×××ŐŐŐŐŐŐ×××ŘŘŘŘŘŘŐŐŐŇŇŇŃŃŃŇŇŇŃŃŃĐĐĐÔÔÔŮŮŮÝÝÝŕŕŕŕŕŕäääßßßŰŰŰŰŰŰŮŮŮÜÜÜćććńńńčččââââââăăăÝÝÝÝÝÝßßßŮŮŮÎÎÎżżż»»»ĆĆĆĚĚĚĹĹĹĂĂĂĚĚĚÇÇÇĂĂĂÇÇÇĘĘĘÇÇÇĚĚĚĐĐĐÍÍÍĂĂĂĽĽĽ¸¸¸ĽĽĽŔŔŔŔŔŔŔŔŔÂÂÂŔŔŔÂÂÂĹĹĹĆĆĆÇÇÇĚĚĚŃŃŃ×××ÎÎÎĐĐĐĚĚĚÎÎÎÔÔÔĘĘĘżżżĹĹĹżżżĂĂĂĆĆĆĘĘĘĚĚĚĘĘĘÍÍÍÍÍÍÇÇÇĘĘĘÂÂÂĆĆĆŘŘŘŐŐŐĐĐĐÝÝÝÎÎÎĚĚĚÎÎÎ×××ŰŰŰŘŘŘŐŐŐŐŐŐĚĚĚĘĘĘÉÉÉÇÇÇÇÇÇĘĘĘÍÍÍĐĐĐÍÍÍĐĐĐŇŇŇŇŇŇŃŃŃĐĐĐŃŃŃŇŇŇŃŃŃĚĚĚĂĂĂŔŔŔÂÂÂĂĂĂÂÂÂżżż···ŔŔŔŔŔŔľľľĂĂĂÇÇÇĆĆĆÇÇÇŘŘŘĘĘĘÂÂÂÎÎÎÂÂÂÇÇÇĚĚĚŐŐŐÜÜÜ×××ĚĚĚĹĹĹĆĆĆĚĚĚŃŃŃ×××ĘĘĘ×××ÔÔÔçççÝÝÝÜÜÜŮŮŮŮŮŮŘŘŘÝÝÝŇŇŇâââŘŘŘÔÔÔÔÔÔ×××ŐŐŐŇŇŇŃŃŃĐĐĐÎÎÎÍÍÍÉÉÉĆĆĆĹĹĹĹĹĹĂĂĂÂÂÂŔŔŔżżżľľľĽĽĽ¸¸¸´´´´´´¸¸¸şşş¸¸¸¸¸¸şşş¸¸¸¸¸¸¸¸¸şşş»»»ľľľżżżŔŔŔľľľÂÂÂĹĹĹÂÂÂŔŔŔĆĆĆÉÉÉÉÉÉĹĹĹĆĆĆÉÉÉĚĚĚĐĐĐŃŃŃĐĐĐÍÍÍĘĘĘĚĚĚÎÎÎĐĐĐĐĐĐÍÍÍĘĘĘÉÉÉÎÎÎÇÇÇĆĆĆĚĚĚĚĚĚÇÇÇĹĹĹÉÉÉÎÎÎĘĘĘ»»»¸¸¸şşşľľľÂÂÂĂĂĂĆĆĆĚĚĚÍÍÍÍÍÍÎÎÎĐĐĐŃŃŃŇŇŇĐĐĐÎÎÎĘĘĘŮŮŮŮŮŮŰŰŰŮŮŮÔÔÔŃŃŃăăăćććăăăäääÜÜÜ×××ŘŘŘŮŮŮŰŰŰŰŰŰŘŘŘŐŐŐŇŇŇŃŃŃĐĐĐŃŃŃÔÔÔŮŮŮÝÝÝŕŕŕßßßÜÜÜâââŰŰŰŘŘŘŮŮŮŘŘŘ×××ßßßęęęâââÝÝÝŕŕŕăăăßßßŕŕŕŕŕŕŮŮŮŔŔŔżżżĂĂĂĘĘĘĚĚĚĆĆĆĆĆĆĚĚĚÉÉÉĹĹĹÇÇÇĘĘĘÇÇÇĚĚĚŃŃŃÎÎÎľľľşşşşşşżżżÂÂÂÂÂÂĹĹĹÉÉÉĹĹĹĹĹĹĹĹĹÉÉÉÍÍÍÎÎÎĚĚĚÉÉÉÇÇÇĘĘĘÇÇÇĚĚĚŃŃŃÇÇÇĽĽĽĂĂĂÇÇÇĂĂĂĂĂĂĹĹĹĆĆĆĹĹĹĂĂĂĹĹĹżżżÉÉÉĆĆĆĘĘĘ×××ŃŃŃĐĐĐăăă×××ŇŇŇŐŐŐÜÜÜÝÝÝŐŐŐŃŃŃÔÔÔÎÎÎĚĚĚÉÉÉĆĆĆÇÇÇÉÉÉĚĚĚÎÎÎĚĚĚĐĐĐŇŇŇÔÔÔŇŇŇŇŇŇŇŇŇÔÔÔŐŐŐÎÎÎĆĆĆĂĂĂĂĂĂĹĹĹÂÂÂżżżŔŔŔŇŇŇÎÎÎĽĽĽ»»»ĆĆĆĚĚĚĚĚĚĐĐĐÍÍÍĹĹĹÇÇǸ¸¸ÂÂÂÂÂÂĂĂĂĘĘĘÇÇÇÉÉÉĚĚĚĐĐĐÔÔÔ×××ŐŐŐÍÍÍßßßßßßçççŰŰŰŘŘŘŐŐŐŃŃŃŰŰŰŕŕŕŘŘŘâââŐŐŐÔÔÔŇŇŇ×××ÔÔÔŃŃŃĐĐĐÎÎÎÎÎÎÍÍÍÉÉÉĆĆĆĹĹĹĂĂĂĂĂĂÂÂÂżżżľľľľľľĽĽĽ···łłł±±±···şşşşşş¸¸¸şşş······¸¸¸şşş»»»ľľľŔŔŔÂÂÂľľľĂĂĂĆĆĆÂÂÂŔŔŔĂĂĂÇÇÇÇÇÇĹĹĹĹĹĹĆĆĆĘĘĘÎÎÎĐĐĐĐĐĐÎÎÎĘĘĘĚĚĚÍÍÍÎÎÎÎÎÎÍÍÍĘĘĘÉÉÉÎÎÎÉÉÉĆĆĆÉÉÉÉÉÉĂĂĂÂÂÂĂĂĂÎÎÎŃŃŃŃŃŃÍÍÍĆĆĆľľľşşş¸¸¸ľľľĂĂĂÉÉÉÎÎÎĐĐĐĐĐĐĐĐĐĐĐĐÎÎÎÎÎÎÍÍÍÉÉÉŃŃŃÔÔÔ×××ŐŐŐÔÔÔÎÎÎßßßäääŕŕŕßßßŮŮŮŰŰŰŰŰŰŰŰŰŰŰŰŮŮŮŘŘŘŐŐŐŇŇŇŃŃŃÔÔÔ×××ŰŰŰßßßăăăăăăâââŕŕŕÝÝÝŮŮŮŘŘŘŮŮŮŮŮŮŐŐŐŘŘŘßßßŮŮŮŰŰŰâââçççäääćććăăă××׼ĽĽĂĂĂĘĘĘÍÍÍĘĘĘĘĘĘĘĘĘĚĚĚĘĘĘĆĆĆÉÉÉĚĚĚÉÉÉĚĚĚŃŃŃÎÎδ´´´´´¸¸¸ĽĽĽĽĽĽĽĽĽÂÂÂÉÉÉĘĘĘÇÇÇĹĹĹĆĆĆĚĚĚÍÍÍĘĘĘĆĆĆÉÉÉĚĚĚĚĚĚÎÎÎŃŃŃĚĚĚÇÇÇÉÉÉÉÉÉŔŔŔżżż»»»ĽĽĽÂÂÂŔŔŔĹĹĹÇÇÇŇŇŇÔÔÔŇŇŇŐŐŐĐĐĐŃŃŃŕŕŕŰŰŰ×××ŘŘŘŰŰŰŮŮŮŇŇŇĐĐĐŃŃŃĐĐĐÍÍÍÉÉÉÇÇÇÉÉÉĚĚĚÍÍÍÎÎÎÎÎÎĐĐĐŇŇŇÔÔÔÔÔÔŐŐŐ××××××ŘŘŘŇŇŇĘĘĘĆĆĆĹĹĹĂĂĂÂÂÂŔŔŔŃŃŃăăăŰŰŰŔŔŔşşşĂĂĂÉÉÉĘĘĘĹĹĹĐĐĐĐĐĐÔÔÔÉÉÉĐĐĐĆĆĆŔŔŔ»»»ŔŔŔÍÍÍÔÔÔŃŃŃĐĐĐŃŃŃÎÎÎÉÉÉÝÝÝŕŕŕâââŘŘŘŮŮŮÜÜÜŐŐŐßßßăăăÜÜÜâââŇŇŇŐŐŐŃŃŃ×××ŇŇŇĐĐĐÎÎÎÎÎÎÎÎÎĚĚĚÉÉÉĆĆĆĹĹĹĂĂĂĂĂĂÂÂÂŔŔŔżżżľľľĽĽĽ¸¸¸łłł±±±···şşşşşş¸¸¸¸¸¸······¸¸¸şşş»»»ľľľŔŔŔÂÂÂĽĽĽĹĹĹÇÇÇĹĹĹŔŔŔÂÂÂĹĹĹĹĹĹĹĹĹĹĹĹĹĹĹÇÇÇĚĚĚÎÎÎĐĐĐÎÎÎĘĘĘĚĚĚÍÍÍÍÍÍÍÍÍĚĚĚĘĘĘÉÉÉÉÉÉĆĆĆĹĹĹĆĆĆĆĆĆĹĹĹĂĂĂÂÂÂĘĘĘÎÎÎŇŇŇÔÔÔĐĐĐÇÇÇ»»»´´´ĽĽĽżżżĂĂĂÉÉÉĚĚĚÍÍÍĚĚĚÉÉÉĘĘĘÍÍÍÎÎÎÍÍÍŃŃŃ×××ŘŘŘÔÔÔŇŇŇĚĚĚÝÝÝčččâââŰŰŰŘŘŘŕŕŕŘŘŘŘŘŘ××××××ŐŐŐÔÔÔŇŇŇŃŃŃŐŐŐŐŐŐ×××ŘŘŘŮŮŮŰŰŰÝÝÝßßßÝÝÝŰŰŰŮŮŮŮŮŮŮŮŮŘŘŘ××××××ŐŐŐ×××ÝÝÝŕŕŕßßßâââŕŕŕÔÔÔĂĂĂĆĆĆÉÉÉĚĚĚĚĚĚÍÍÍÍÍÍÍÍÍĚĚĚÇÇÇĘĘĘÍÍÍÉÉÉĚĚĚĐĐĐÍÍÍ»»»ľľľÂÂÂĂĂĂĽĽĽ···ĽĽĽĆĆĆÉÉÉÇÇÇĆĆĆĹĹĹĆĆĆÇÇÇÉÉÉÉÉÉĂĂĂĂĂĂĆĆĆĆĆĆĂĂĂÇÇÇĘĘĘĆĆĆĹĹĹĹĹĹÎÎÎĘĘĘĚĚĚŐŐŐ×××ßßßÔÔÔŰŰŰÝÝÝŘŘŘÔÔÔŃŃŃŇŇŇŐŐŐŮŮŮ×××ŐŐŐŐŐŐŇŇŇĐĐĐĐĐĐŃŃŃĐĐĐĚĚĚÉÉÉÉÉÉĚĚĚÎÎÎĐĐĐĐĐĐŃŃŃŃŃŃŃŃŃŇŇŇŐŐŐŘŘŘŮŮŮŮŮŮŮŮŮŐŐŐÎÎÎÉÉÉĹĹĹÂÂÂŔŔŔŔŔŔŃŃŃŘŘŘĐĐĐżżżľľľÂÂÂĆĆĆĚĚĚĹĹĹĚĚĚĘĘĘŇŇŇÎÎÎŰŰŰŰŰŰŕŕŕćććŘŘŘĐĐĐÍÍÍÍÍÍŇŇŇŐŐŐÍÍÍĘĘĘŕŕŕŕŕŕŰŰŰŐŐŐŮŮŮăăăÜÜÜăăăćććŕŕŕŕŕŕŇŇŇ×××ŃŃŃ×××ŃŃŃĐĐĐÎÎÎÍÍÍÍÍÍĚĚĚÉÉÉĆĆĆĹĹĹĹĹĹĂĂĂÂÂÂŔŔŔżżżľľľľľľ¸¸¸łłł±±±µµµşşş¸¸¸······µµµ······şşş»»»żżżŔŔŔ»»»ĂĂĂÉÉÉĆĆĆÂÂÂÂÂÂÂÂÂŔŔŔĹĹĹĂĂĂĂĂĂĆĆĆĘĘĘÎÎÎĐĐĐÎÎÎĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĘĘĘÉÉÉĹĹĹĂĂĂÂÂÂĂĂĂĹĹĹĆĆĆĆĆĆĂĂĂĐĐĐĘĘĘĹĹĹĹĹĹÇÇÇÉÉÉĹĹĹżżżĽĽĽ»»»»»»ľľľÂÂÂĹĹĹĹĹĹĂĂĂÉÉÉÍÍÍŇŇŇÔÔÔŐŐŐŰŰŰÜÜÜ×××ŃŃŃÉÉÉÝÝÝíííäääŮŮŮŘŘŘäääŐŐŐÔÔÔÔÔÔŇŇŇŇŇŇŇŇŇŇŇŇŇŇŇÝÝÝÝÝÝŰŰŰŘŘŘŘŘŘŰŰŰâââčččŕŕŕÝÝÝŰŰŰŮŮŮŮŮŮŮŮŮ×××ÔÔÔ×××ÔÔÔŐŐŐÔÔÔŃŃŃŘŘŘÜÜÜŇŇŇÍÍÍĆĆĆĹĹĹĘĘĘÎÎÎÎÎÎÎÎÎĐĐĐÍÍÍÉÉÉĚĚĚÍÍÍÉÉÉĚĚĚĐĐĐÍÍÍŃŃŃŐŐŐŘŘŘŇŇŇĹĹĹ»»»ľľľÇÇÇÂÂÂĹĹĹÇÇÇÇÇÇĂĂĂĂĂĂĆĆĆĘĘĘĆĆĆĂĂĂÇÇÇĹĹĹľľľÉÉÉŃŃŃĘĘĘÎÎÎ×××çççÜÜÜŇŇŇÔÔÔÍÍÍŇŇŇÔÔÔŘŘŘŰŰŰ×××ÔÔÔŘŘŘŮŮŮÔÔÔŐŐŐŐŐŐŇŇŇĐĐĐÎÎÎÎÎÎĐĐĐĐĐĐÍÍÍĘĘĘÉÉÉĘĘĘÍÍÍŃŃŃŇŇŇŇŇŇÔÔÔŃŃŃŃŃŃŇŇŇ×××ŰŰŰŰŰŰŰŰŰŰŰŰŘŘŘŃŃŃĘĘĘĂĂĂŔŔŔŔŔŔŔŔŔÂÂÂŔŔŔ»»»»»»ŔŔŔÂÂÂĂĂĂÎÎÎŃŃŃŃŃŃĚĚĚÔÔÔĘĘĘÍÍÍĘĘĘŐŐŐŇŇŇĚĚĚĐĐĐŃŃŃÎÎÎŇŇŇŮŮŮŐŐŐŮŮŮëëëćććŘŘŘĐĐĐÔÔÔßßß×××ćććçççâââŕŕŕŇŇŇŘŘŘŃŃŃ×××ŃŃŃÎÎÎÍÍÍÍÍÍÍÍÍĚĚĚÉÉÉĆĆĆĹĹĹĹĹĹĂĂĂÂÂÂŔŔŔżżżľľľľľľşşşłłł±±±µµµşşş¸¸¸···µµµµµµ······şşşĽĽĽżżżŔŔŔĂĂĂÂÂÂÂÂÂĆĆĆÂÂÂÇÇÇÇÇÇĽĽĽĂĂĂĂĂĂĹĹĹŔŔŔĂĂĂÍÍÍĐĐĐÍÍÍÎÎÎÇÇÇÉÉÉĚĚĚÍÍÍÎÎÎÍÍÍĘĘĘÉÉÉĆĆĆĂĂĂĂĂĂĆĆĆĹĹĹŔŔŔÂÂÂÉÉÉĆĆĆĹĹĹĂĂĂÂÂÂĂĂĂÇÇÇĘĘĘÍÍÍĹĹĹĘĘĘÍÍÍĚĚĚÇÇÇĂĂĂŔŔŔżżżĆĆĆĆĆĆĚĚĚŇŇŇŮŮŮÝÝÝÜÜÜ×××ĚĚĚĐĐĐŮŮŮâââßßß×××ÔÔÔŐŐŐÝÝÝŰŰŰŘŘŘŐŐŐÔÔÔŇŇŇŃŃŃĐĐĐŮŮŮŮŮŮŰŰŰÝÝÝßßßŕŕŕŕŕŕŕŕŕ×××ŘŘŘŮŮŮŘŘŘŐŐŐÔÔÔŇŇŇŃŃŃĘĘĘĐĐĐăăăßßßÔÔÔ×××ŐŐŐŐŐŐÔÔÔĂĂĂľľľĘĘĘÎÎÎĆĆĆÇÇÇŃŃŃÎÎÎĘĘĘÇÇÇĆĆĆÇÇÇÉÉÉÇÇÇÇÇÇÇÇÇĆĆĆÉÉÉĚĚĚÇÇÇŔŔŔĹĹĹÎÎÎŃŃŃÔÔÔÔÔÔÍÍÍĘĘĘÎÎÎŐŐŐ×××ŮŮŮßßßŇŇŇÂÂÂĹĹĹĘĘĘĘĘĘÍÍÍâââ×××ĐĐĐĐĐĐĐĐĐÍÍÍÎÎÎÔÔÔŇŇŇÔÔÔ××××××ŐŐŐÔÔÔÔÔÔÔÔÔŇŇŇŇŇŇŃŃŃŃŃŃĐĐĐÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎĐĐĐĐĐĐŃŃŃÔÔÔŐŐŐ×××ÔÔÔÔÔÔÔÔÔ×××ŘŘŘŮŮŮ×××ÔÔÔÜÜÜŮŮŮŇŇŇŇŇŇŰŰŰâââÝÝÝÔÔÔĂĂĂżżżľľľŔŔŔÂÂÂÂÂÂĆĆĆĘĘĘÍÍÍĐĐĐŇŇŇŃŃŃÎÎÎĚĚĚĘĘĘĚĚĚĘĘĘĚĚĚĚĚĚÍÍÍÎÎÎŇŇŇŇŇŇŇŇŇëëëŰŰŰßßßŘŘŘŇŇŇÜÜÜŮŮŮŰŰŰęęęŕŕŕęęę×××ŃŃŃĐĐĐÔÔÔÍÍÍŃŃŃĐĐĐÎÎÎÍÍÍĚĚĚĘĘĘÉÉÉÇÇÇŔŔŔżżżĂĂĂĂĂĂľľľŔŔŔżżż´´´µµµŻŻŻłłłşşş···µµµşşşşşş»»»´´´łłł···»»»ĽĽĽÂÂÂÇÇÇĆĆĆĹĹĹÇÇÇÂÂÂĆĆĆÇÇÇżżżÇÇÇĂĂĂĹĹĹŔŔŔÂÂÂĚĚĚÎÎÎÍÍÍĐĐĐÎÎÎÎÎÎĐĐĐÎÎÎÍÍÍÉÉÉĹĹĹĂĂĂĆĆĆĂĂĂĹĹĹÇÇÇĹĹĹŔŔŔÂÂÂĆĆĆĹĹĹĂĂĂŔŔŔŔŔŔŔŔŔĂĂĂĆĆĆÉÉÉÇÇÇÉÉÉÉÉÉÉÉÉÉÉÉĚĚĚŇŇŇ×××ÔÔÔŐŐŐŮŮŮÜÜÜÜÜÜŘŘŘŃŃŃÍÍÍĘĘĘÎÎÎ×××ÜÜÜŮŮŮŇŇŇĐĐĐŇŇŇŃŃŃŇŇŇŇŇŇŃŃŃÎÎÎÍÍÍĐĐĐŇŇŇŐŐŐ×××××××××ŘŘŘŘŘŘŰŰŰÜÜÜÝÝÝÝÝÝÜÜÜŘŘŘÔÔÔÎÎÎĚĚĚÉÉÉÎÎÎŇŇŇćććäääÝÝÝŕŕŕŰŰŰ×××ÍÍÍÂÂÂżżżÉÉÉÍÍÍÇÇÇÇÇÇĐĐĐÍÍÍĘĘĘĆĆĆĹĹĹĆĆĆÇÇÇÇÇÇĆĆĆĘĘĘĘĘĘĚĚĚÍÍÍĚĚĚĚĚĚŃŃŃ×××ŰŰŰßßßÝÝÝ×××ŃŃŃŇŇŇ×××ŘŘŘÔÔÔŰŰŰÔÔÔĘĘĘŇŇŇÝÝÝâââäääÜÜÜŮŮŮŘŘŘŮŮŮŮŮŮŐŐŐŃŃŃĐĐĐŇŇŇÔÔÔÔÔÔÔÔÔŃŃŃŃŃŃŇŇŇÔÔÔŃŃŃŃŃŃŃŃŃĐĐĐĐĐĐĐĐĐĐĐĐÎÎÎŃŃŃŃŃŃŃŃŃŇŇŇÔÔÔŐŐŐŘŘŘŘŘŘ×××ŐŐŐŐŐŐ×××ŘŘŘŮŮŮŮŮŮŮŮŮŮŮŮŐŐŐĐĐĐŃŃŃŰŰŰććććććßßßÔÔÔÇÇÇżżżÂÂÂÉÉÉĘĘĘĘĘĘĘĘĘÎÎÎĐĐĐŃŃŃŃŃŃÎÎÎÍÍÍĘĘĘĘĘĘĚĚĚĚĚĚÍÍÍÎÎÎÍÍÍÉÉÉĹĹĹĂĂĂčččŕŕŕçççÝÝÝŐŐŐÜÜÜßßßäääíííâââęęęŐŐŐŃŃŃĐĐĐŐŐŐĐĐĐŇŇŇŃŃŃĐĐĐÎÎÎĚĚĚĘĘĘÉÉÉÉÉÉĂĂĂŔŔŔĂĂĂÂÂÂľľľŔŔŔŔŔŔ······°°°´´´»»»······»»»şşş´´´±±±łłł¸¸¸»»»»»»ľľľÂÂÂÉÉÉÇÇÇÇÇÇŔŔŔĹĹĹÇÇÇŔŔŔĘĘĘĂĂĂĂĂĂľľľżżżĘĘĘÎÎÎÍÍÍĐĐĐŃŃŃŃŃŃŃŃŃĐĐĐĚĚĚÇÇÇĂĂĂżżżĹĹĹĹĹĹĹĹĹĆĆĆĹĹĹŔŔŔÂÂÂĹĹĹĂĂĂÂÂÂżżżľľľľľľżżżÂÂÂĂĂĂÉÉÉĹĹĹŔŔŔĽĽĽ»»»»»»ŔŔŔĹĹĹĘĘĘĚĚĚÍÍÍŃŃŃÔÔÔŇŇŇĐĐĐŃŃŃĘĘĘÎÎÎŐŐŐÜÜÜŰŰŰÔÔÔÔÔÔŘŘŘŐŐŐŘŘŘŮŮŮÔÔÔĘĘĘĆĆĆÉÉÉÍÍÍĚĚĚÍÍÍĐĐĐĐĐĐÎÎÎŃŃŃŐŐŐŮŮŮŰŰŰŘŘŘ×××ŐŐŐŇŇŇÎÎÎĘĘĘÉÉÉĐĐĐŃŃŃâââăăăßßßâââ×××ĚĚĚĹĹĹŔŔŔÂÂÂĆĆĆÉÉÉÇÇÇÉÉÉÍÍÍĘĘĘÉÉÉĹĹĹĂĂĂĹĹĹĹĹĹĹĹĹĹĹĹÇÇÇĘĘĘÉÉÉÉÉÉĘĘĘŃŃŃŐŐŐ×××ĐĐĐ×××ŘŘŘÔÔÔŃŃŃÔÔÔ××××××ŮŮŮßßßŘŘŘÎÎÎŃŃŃŮŮŮÜÜÜÝÝÝŮŮŮŘŘŘÔÔÔŃŃŃŃŃŃŇŇŇŇŇŇŃŃŃŇŇŇŇŇŇŃŃŃÎÎÎĚĚĚÍÍÍĐĐĐÔÔÔĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐŃŃŃŃŃŃŃŃŃÔÔÔÔÔÔÔÔÔŐŐŐ×××ŘŘŘŰŰŰÜÜÜŮŮŮŮŮŮŮŮŮŘŘŘŘŘŘŮŮŮŰŰŰÝÝÝŰŰŰŐŐŐĐĐĐŃŃŃŰŰŰäääçççăăăŘŘŘĚĚĚÂÂÂĂĂĂĘĘĘÍÍÍÎÎÎÎÎÎĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐÎÎÎĚĚĚÉÉÉÎÎÎÇÇÇĹĹĹÉÉÉÉÉÉÉÉÉÍÍÍŐŐŐßßßÝÝÝäääÜÜÜŃŃŃŐŐŐÝÝÝçççîîîăăăęęęÔÔÔŇŇŇŃŃŃŐŐŐÔÔÔŇŇŇŇŇŇŃŃŃĐĐĐÍÍÍĚĚĚĘĘĘĘĘĘĆĆĆĂĂĂĂĂĂÂÂÂľľľÂÂÂĂĂĂşşş···łłłµµµľľľ···şşş»»»şşş°°°´´´şşşľľľżżż»»»»»»ŔŔŔÇÇÇÇÇÇÉÉÉŔŔŔĂĂĂĆĆĆżżżÉÉÉÂÂÂÂÂÂĽĽĽľľľÉÉÉÍÍÍÍÍÍŃŃŃÍÍÍÎÎÎÎÎÎÎÎÎÍÍÍÉÉÉĆĆĆĂĂĂÂÂÂÂÂÂÂÂÂÂÂÂŔŔŔżżżÂÂÂĹĹĹÂÂÂŔŔŔżżżĽĽĽĽĽĽľľľżżżżżżŔŔŔżżżÂÂÂĘĘĘŃŃŃŐŐŐŮŮŮÝÝÝŰŰŰŐŐŐĘĘĘÉÉÉÎÎÎÎÎÎĚĚĚÎÎÎĐĐĐÔÔÔÜÜÜăăăăăăÝÝÝÝÝÝâââŕŕŕŕŕŕßßßŮŮŮŇŇŇÍÍÍÍÍÍÎÎÎĚĚĚĐĐĐŃŃŃĐĐĐĚĚĚĚĚĚÎÎÎŇŇŇŃŃŃÎÎÎĐĐĐÔÔÔŐŐŐŐŐŐŐŐŐ×××ßßßŰŰŰçççčččçççęęęŰŰŰĚĚĚľľľŔŔŔĂĂĂĹĹĹÇÇÇÉÉÉĘĘĘĘĘĘÉÉÉÇÇÇĹĹĹĂĂĂĂĂĂĂĂĂĹĹĹĹĹĹÇÇÇĘĘĘĘĘĘÇÇÇĘĘĘŇŇŇŇŇŇÎÎÎĂĂĂĚĚĚŇŇŇŃŃŃŃŃŃÔÔÔŐŐŐŐŐŐĐĐĐŐŐŐŇŇŇĘĘĘÎÎÎŮŮŮßßßÝÝÝŘŘŘŘŘŘŇŇŇĘĘĘĘĘĘŃŃŃŐŐŐŇŇŇŇŇŇŃŃŃÍÍÍÉÉÉĆĆĆÉÉÉÎÎÎŇŇŇÎÎÎÎÎÎÎÎÎĐĐĐŃŃŃŃŃŃŇŇŇŇŇŇ×××××××××ŘŘŘŮŮŮŰŰŰÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÜÜÜŮŮŮŘŘŘŰŰŰÜÜÜßßßŮŮŮÔÔÔÔÔÔŘŘŘÝÝÝÝÝÝŰŰŰÍÍÍÉÉÉĆĆĆÇÇÇÉÉÉĘĘĘÎÎÎŐŐŐŃŃŃĐĐĐĐĐĐĐĐĐŃŃŃĐĐĐĚĚĚÉÉÉĹĹĹÂÂÂÉÉÉ×××ŰŰŰ×××ŮŮŮăăăŰŰŰÜÜÜßßßŮŮŮŇŇŇÔÔÔÝÝÝçççîîîäääęęęŇŇŇÔÔÔŇŇŇ××××××ÔÔÔÔÔÔŇŇŇŃŃŃÎÎÎÍÍÍĚĚĚĘĘĘÇÇÇĹĹĹĹĹĹĂĂĂŔŔŔĹĹĹĹĹĹşşş···µµµ···ŔŔŔ···ľľľ»»»şşş±±±ĽĽĽÂÂÂĹĹĹĹĹĹżżżĽĽĽĂĂĂÂÂÂĹĹĹÇÇÇŔŔŔÂÂÂÂÂÂşşşĂĂĂŔŔŔÂÂÂĽĽĽĽĽĽÇÇÇÍÍÍÍÍÍŃŃŃĘĘĘĚĚĚÍÍÍÎÎÎÍÍÍĘĘĘÇÇÇĆĆĆżżżżżżżżżĽĽĽ»»»żżżĂĂĂÇÇÇÂÂÂŔŔŔżżżľľľĽĽĽĽĽĽľľľľľľĽĽĽşşşĽĽĽÇÇÇÎÎÎÎÎÎÎÎÎŃŃŃäääŘŘŘÇÇÇĂĂĂÍÍÍÉÉÉŔŔŔĂĂĂŘŘŘÜÜÜäääęęęčččŕŕŕÝÝÝŕŕŕÝÝÝŰŰŰŘŘŘŘŘŘÜÜÜÝÝÝÜÜÜŰŰŰŮŮŮÝÝÝßßßÜÜÜŐŐŐÎÎÎÍÍÍÎÎÎŐŐŐŇŇŇÔÔÔŰŰŰÝÝÝÝÝÝŕŕŕäääćććÝÝÝççççççčččîîîŕŕŕŃŃŃ»»»żżżĂĂĂĹĹĹĆĆĆĘĘĘĘĘĘÉÉÉÉÉÉÇÇÇĆĆĆĂĂĂÂÂÂĂĂĂĂĂĂĹĹĹÍÍÍŃŃŃŃŃŃÎÎÎŃŃŃŐŐŐŃŃŃÉÉÉÉÉÉŇŇŇŮŮŮŮŮŮ×××ŘŘŘŘŘŘŐŐŐÎÎÎŇŇŇŇŇŇÎÎÎŇŇŇŕŕŕčččććć×××ŰŰŰŮŮŮÔÔÔŇŇŇ××××××ŇŇŇŇŇŇĐĐĐĚĚĚĆĆĆĹĹĹĆĆĆĚĚĚĐĐĐÍÍÍÍÍÍÎÎÎĐĐĐŃŃŃŃŃŃŇŇŇŇŇŇŘŘŘŘŘŘŘŘŘŮŮŮŰŰŰÜÜÜÝÝÝßßßßßßââââââŕŕŕÜÜÜŘŘŘŘŘŘŘŘŘßßßŰŰŰ×××ŐŐŐŐŐŐŐŐŐÔÔÔŇŇŇĚĚĚÉÉÉĘĘĘÎÎÎĐĐĐÎÎÎĐĐĐÔÔÔŇŇŇŃŃŃĐĐĐŃŃŃŇŇŇŃŃŃÍÍÍÉÉÉÉÉÉÉÉÉŇŇŇâââäääÜÜÜÜÜÜäääăăăăăăÜÜÜŰŰŰŰŰŰÜÜÜăăăçççëëëćććęęęÔÔÔ×××ÔÔÔŐŐŐ×××ŐŐŐÔÔÔŇŇŇŃŃŃĐĐĐÍÍÍĚĚĚĚĚĚÇÇÇĹĹĹĆĆĆĆĆĆĹĹĹÇÇÇĹĹĹ···¸¸¸şşş¸¸¸ĂĂĂ···ŔŔŔĽĽĽşşş´´´ÂÂÂÇÇÇĹĹĹĆĆĆŔŔŔĽĽĽĂĂĂľľľÂÂÂÇÇÇÂÂÂÂÂÂŔŔŔ···żżżżżżŔŔŔĽĽĽľľľÉÉÉÎÎÎÍÍÍŃŃŃÍÍÍÍÍÍÎÎÎÎÎÎÍÍÍÉÉÉĆĆĆĂĂĂľľľŔŔŔżżżĽĽĽ»»»żżżĹĹĹĆĆĆŔŔŔżżżľľľľľľĽĽĽĽĽĽĽĽĽľľľżżż¸¸¸şşşÇÇÇŇŇŇŐŐŐ×××ŰŰŰŇŇŇÎÎÎÂÂÂĹĹĹŃŃŃĚĚĚŔŔŔÇÇÇŕŕŕăăăçççęęęăăăŮŮŮŐŐŐ×××ŘŘŘÔÔÔŃŃŃŐŐŐÝÝÝăăăâââÝÝÝÜÜÜŕŕŕääääääâââÝÝÝÜÜÜÜÜÜăăăŕŕŕŕŕŕćććăăăßßßâââčččâââŰŰŰăăăăăăäääíííâââ××׾ľľżżżÂÂÂĹĹĹÉÉÉĘĘĘĘĘĘÉÉÉÉÉÉÉÉÉÇÇÇĹĹĹĂĂĂĂĂĂĹĹĹÇÇÇÍÍÍÎÎÎĐĐĐŃŃŃŃŃŃŃŃŃĘĘĘĂĂĂÉÉÉÔÔÔŰŰŰÜÜÜŰŰŰÜÜÜÜÜÜŮŮŮŘŘŘŮŮŮŘŘŘŃŃŃĐĐĐŰŰŰăăăÝÝÝŘŘŘŮŮŮŘŘŘŇŇŇĐĐĐŃŃŃÔÔÔÔÔÔŃŃŃĐĐĐĚĚĚÇÇÇĹĹĹĆĆĆĘĘĘÎÎÎÍÍÍÎÎÎÎÎÎĐĐĐŃŃŃŃŃŃŇŇŇŇŇŇ××××××ŘŘŘŘŘŘŮŮŮÜÜÜÝÝÝßßßŕŕŕââââââŕŕŕÝÝÝŮŮŮ×××ŐŐŐŮŮŮŐŐŐÔÔÔÔÔÔÔÔÔŃŃŃŃŃŃŇŇŇŘŘŘŃŃŃÎÎÎ×××ÜÜÜŰŰŰŇŇŇÎÎÎŇŇŇŇŇŇŇŇŇÔÔÔŇŇŇŃŃŃÎÎÎĚĚĚÍÍÍÍÍÍŐŐŐÝÝÝßßßŰŰŰÝÝÝäääääääää××××××ÜÜÜÜÜÜŕŕŕŕŕŕçççäääęęęŐŐŐŮŮŮŐŐŐÔÔÔŐŐŐŐŐŐŐŐŐÔÔÔŃŃŃĐĐĐÎÎÎÍÍÍĚĚĚÇÇÇĹĹĹĆĆĆÇÇÇĆĆĆÉÉÉĹĹĹ···¸¸¸ĽĽĽşşşĆĆƵµµĂĂĂĽĽĽşşşłłłĹĹĹĆĆĆÂÂÂĹĹĹżżżşşşŔŔŔĽĽĽÂÂÂÇÇÇÂÂÂÂÂÂżżżµµµľľľľľľŔŔŔĽĽĽżżżĚĚĚÎÎÎÍÍÍŃŃŃÍÍÍÎÎÎÎÎÎÎÎÎÍÍÍÉÉÉĆĆĆĂĂĂŔŔŔĹĹĹĹĹĹŔŔŔżżżÂÂÂĂĂĂÂÂÂľľľĽĽĽĽĽĽĽĽĽ»»»»»»»»»ĽĽĽşşş±±±´´´ĹĹĹŇŇŇŐŐŐŘŘŘÜÜÜŘŘŘŰŰŰŐŐŐ×××ÜÜÜĐĐĐÇÇÇ×××äääăăăäääăăăÜÜÜŇŇŇŃŃŃÔÔÔŮŮŮ×××ÔÔÔŐŐŐŮŮŮÜÜÜŰŰŰŮŮŮ×××ŮŮŮÝÝÝâââăăăăăăăăăăăăäääâââăăăćććâââŮŮŮÝÝÝčččęęęäääíííëëëęęęďďďçççÜÜÜĂĂĂŔŔŔŔŔŔĆĆĆĘĘĘĚĚĚĘĘĘĘĘĘĘĘĘĘĘĘÉÉÉÇÇÇĹĹĹĂĂĂĆĆĆÉÉÉÉÉÉÉÉÉĚĚĚĐĐĐŃŃŃÍÍÍÉÉÉÇÇÇÇÇÇŃŃŃŮŮŮŰŰŰŮŮŮŰŰŰŮŮŮŘŘŘÔÔÔŇŇŇŇŇŇÍÍÍĚĚĚŮŮŮćććŕŕŕŮŮŮ×××ÔÔÔĐĐĐÍÍÍĘĘĘÎÎÎÔÔÔĐĐĐÎÎÎÍÍÍÉÉÉĆĆĆĆĆĆÉÉÉĚĚĚÎÎÎÎÎÎĐĐĐĐĐĐŃŃŃŃŃŃŃŃŃŇŇŇŐŐŐŐŐŐ××××××ŘŘŘŰŰŰÜÜÜÝÝÝŕŕŕßßßÝÝÝÝÝÝÜÜÜŰŰŰŘŘŘ××××××ŇŇŇŃŃŃŇŇŇŇŇŇŃŃŃÔÔÔŘŘŘÜÜÜŐŐŐÔÔÔÜÜÜăăăßßßŘŘŘŇŇŇÔÔÔŐŐŐ×××ŐŐŐÔÔÔŃŃŃĐĐĐÎÎÎĂĂĂÍÍÍŮŮŮââââââÝÝÝŰŰŰÜÜÜâââćććŐŐŐÔÔÔŮŮŮ×××ŰŰŰÜÜÜâââăăăęęę×××ÝÝÝ×××ŃŃŃŇŇŇŐŐŐÔÔÔŇŇŇŃŃŃĐĐĐÍÍÍĚĚĚĚĚĚĘĘĘĹĹĹĹĹĹĆĆĆĹĹĹÉÉÉĆĆƸ¸¸¸¸¸żżż»»»ÉÉɵµµĆĆĆĽĽĽşşş´´´ÇÇÇÉÉÉĂĂĂÉÉɸ¸¸ľľľľľľĂĂĂÉÉÉÂÂÂŔŔŔżżżµµµżżżľľľŔŔŔľľľŔŔŔÍÍÍĐĐĐÍÍÍĐĐĐĘĘĘĚĚĚÍÍÍÎÎÎÍÍÍĘĘĘÇÇÇĆĆĆĂĂĂÉÉÉĘĘĘĆĆĆĂĂĂĹĹĹĂĂĂżżż»»»»»»»»»şşşşşşşşş»»»»»»µµµŻŻŻłłłĆĆĆÔÔÔÔÔÔŇŇŇÔÔÔŐŐŐÝÝÝŰŰŰŘŘŘŘŘŘĘĘĘĚĚĚäääăăăâââŕŕŕßßßŘŘŘŇŇŇÔÔÔŰŰŰ×××ŘŘŘŘŘŘŘŘŘ×××ŘŘŘŮŮŮŰŰŰŘŘŘŘŘŘŮŮŮŮŮŮŰŰŰŰŰŰŮŮŮŘŘŘŮŮŮŘŘŘŰŰŰŕŕŕŰŰŰÔÔÔŰŰŰčččëëëćććďďďëëëćććčččÝÝÝÔÔÔÇÇÇŔŔŔżżżÇÇÇÍÍÍĚĚĚĘĘĘĚĚĚĘĘĘĚĚĚĘĘĘÉÉÉĹĹĹĹĹĹÇÇÇĘĘĘÍÍÍĘĘĘÍÍÍÔÔÔ×××ŃŃŃŃŃŃÔÔÔŇŇŇŰŰŰŕŕŕÝÝÝŮŮŮ×××ÔÔÔŃŃŃŐŐŐÔÔÔŇŇŇÎÎÎĚĚĚÜÜÜčččăăă××××××ŰŰŰßßßŰŰŰŃŃŃÍÍÍĐĐĐÎÎÎÎÎÎÎÎÎĚĚĚÉÉÉÇÇÇÉÉÉĘĘĘÎÎÎĐĐĐĐĐĐĐĐĐĐĐĐŃŃŃŃŃŃŃŃŃŐŐŐŐŐŐŐŐŐŐŐŐŘŘŘŮŮŮŰŰŰÜÜÜŕŕŕÝÝÝŰŰŰŮŮŮŰŰŰÜÜÜŰŰŰŮŮŮŘŘŘŇŇŇĐĐĐŃŃŃŃŃŃĐĐĐŐŐŐÜÜÜÔÔÔÔÔÔŘŘŘßßßŕŕŕÜÜÜŰŰŰÜÜÜÔÔÔŐŐŐŘŘŘ×××ÔÔÔŃŃŃĐĐĐŃŃŃĐĐĐ×××ÜÜÜÜÜÜŮŮŮŮŮŮŰŰŰÜÜÜćććíííÜÜÜŮŮŮÜÜÜ×××ÝÝÝŕŕŕßßßăăăëëëŘŘŘŕŕŕŘŘŘĐĐĐĐĐĐŐŐŐÔÔÔŇŇŇŃŃŃĐĐĐÍÍÍĚĚĚĚĚĚĚĚĚĆĆĆĹĹĹĂĂĂĂĂĂÉÉÉĆĆĆşşş¸¸¸ŔŔŔ»»»ĘĘʵµµÇÇÇĽĽĽşşş···ĚĚĚÍÍÍÉÉÉÎÎÎÇÇÇ»»»ľľľÂÂÂżżżŔŔŔÉÉÉĆĆĆľľľŔŔŔĆĆĆĽĽĽżżżÉÉÉşşşŐŐŐÎÎÎŐŐŐĐĐĐĚĚĚÍÍÍÇÇÇÉÉÉŃŃŃŃŃŃÍÍÍÍÍÍĚĚĚĚĚĚÎÎÎŇŇŇŇŇŇÎÎÎĹĹĹľľľ¸¸¸···¸¸¸şşş»»»şşşµµµłłł¬¬¬°°°ÂÂÂŃŃŃĐĐĐÍÍÍĐĐĐŃŃŃŘŘŘŰŰŰŃŃŃÔÔÔÎÎÎĘĘĘÝÝÝçççŰŰŰăăăÜÜÜÝÝÝ×××ÍÍÍŇŇŇÎÎÎŐŐŐŰŰŰßßßâââßßßŮŮŮ×××ŐŐŐÝÝÝŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰÜÜÜßßßŮŮŮŮŮŮŮŮŮŰŰŰÜÜÜßßßâââäääăăăćććíííîîîççççççâââÔÔÔŐŐŐÎÎÎÂÂÂŔŔŔĚĚĚÎÎÎĚĚĚÎÎÎĘĘĘĘĘĘÉÉÉÇÇÇÇÇÇÇÇÇĆĆĆĆĆĆĘĘĘĐĐĐÔÔÔÔÔÔŇŇŇÔÔÔÔÔÔÔÔÔŕŕŕŮŮŮŐŐŐŐŐŐŐŐŐŇŇŇŇŇŇÔÔÔŇŇŇÎÎÎĐĐĐÍÍÍĆĆĆăăăââââââßßßŕŕŕëëëíííŰŰŰÍÍÍĚĚĚĚĚĚŃŃŃĐĐĐĐĐĐÎÎÎÍÍÍĚĚĚÉÉÉÉÉÉĐĐĐÉÉÉÇÇÇÎÎÎŇŇŇĐĐĐÍÍÍÍÍÍŃŃŃÔÔÔŐŐŐ×××ŮŮŮŰŰŰÝÝÝâââÝÝÝÜÜÜŮŮŮŮŮŮŰŰŰŰŰŰŮŮŮ××××××ŐŐŐŃŃŃÎÎÎÍÍÍÎÎÎŇŇŇŐŐŐÝÝÝÔÔÔŘŘŘŕŕŕŕŕŕßßßßßßŰŰŰŰŰŰÜÜÜŮŮŮŐŐŐŐŐŐŘŘŘŐŐŐÎÎÎĘĘĘÔÔÔÝÝÝÝÝÝÜÜÜÜÜÜÜÜÜŰŰŰăăăÝÝÝăăăčččŕŕŕÜÜÜßßßÝÝÝäääâââččččččŰŰŰŇŇŇŇŇŇŇŇŇŐŐŐ×××××××××ÔÔÔŃŃŃÍÍÍĘĘĘÂÂÂĹĹĹĆĆĆÉÉÉÉÉÉÇÇÇĆĆĆĹĹĹľľľĆĆĆÍÍÍĹĹĹĽĽĽĂĂĂĆĆĆľľľ¸¸¸ĘĘĘĘĘĘĚĚĚÍÍÍÉÉÉÍÍÍÎÎÎĆĆĆżżżÂÂÂĆĆĆĹĹĹżżżĽĽĽĆĆĆľľľľľľĂĂĂ···ŃŃŃĚĚĚŇŇŇĚĚĚĚĚĚŃŃŃÎÎÎÍÍÍŃŃŃÎÎÎĘĘĘÎÎÎĚĚĚÍÍÍĐĐĐŇŇŇŇŇŇÎÎÎÇÇÇÂÂÂĹĹĹĂĂĂÂÂÂŔŔŔŔŔŔĽĽĽ¸¸¸´´´ŻŻŻłłłĆĆĆŇŇŇĘĘĘÉÉÉĐĐĐĐĐĐÔÔÔ×××ŃŃŃŐŐŐĐĐĐÇÇÇÔÔÔŘŘŘŰŰŰÝÝÝŐŐŐŘŘŘÔÔÔÍÍÍŃŃŃĚĚĚÍÍÍÎÎÎĐĐĐĐĐĐÎÎÎÍÍÍĚĚĚĚĚĚÜÜÜÝÝÝÜÜÜŮŮŮ××××××ÔÔÔŇŇŇŘŘŘŘŘŘŘŘŘŮŮŮŰŰŰÝÝÝßßßŕŕŕâââŕŕŕäääççççççęęęćććŮŮŮŘŘŘŐŐŐÉÉÉÂÂÂĘĘĘĚĚĚÉÉÉÉÉÉĘĘĘĘĘĘÉÉÉÇÇÇĆĆĆĆĆĆÇÇÇÉÉÉŃŃŃĚĚĚĘĘĘÎÎÎŃŃŃŇŇŇŘŘŘŕŕŕßßßŮŮŮŐŐŐ××××××ÔÔÔŇŇŇŐŐŐÔÔÔŃŃŃĐĐĐĚĚĚĹĹĹââââââŕŕŕăăăâââçççççç×××ÍÍÍÍÍÍÍÍÍŃŃŃĐĐĐÎÎÎÍÍÍĚĚĚĚĚĚĚĚĚĚĚĚŇŇŇÍÍÍĘĘĘÍÍÍĐĐĐÎÎÎÍÍÍĐĐĐĚĚĚĐĐĐÔÔÔÔÔÔÔÔÔŐŐŐÜÜÜăăăÝÝÝÜÜÜŰŰŰŮŮŮŮŮŮŘŘŘ×××ŐŐŐĐĐĐÎÎÎÍÍÍÎÎÎŃŃŃÔÔÔ×××ŘŘŘŘŘŘŃŃŃŘŘŘăăăâââÝÝÝŮŮŮŇŇŇŕŕŕâââßßßŰŰŰŮŮŮŮŮŮÔÔÔÍÍÍĐĐĐŘŘŘßßßßßßßßßâââăăăâââÝÝÝŘŘŘÝÝÝăăăÝÝÝÜÜÜââââââäääßßßâââÝÝÝĐĐĐÇÇÇĚĚĚÍÍÍŃŃŃŇŇŇŇŇŇÔÔÔÔÔÔŇŇŇŇŇŇŃŃŃÇÇÇĂĂĂżżżľľľľľľĂĂĂÇÇÇĚĚĚ···ĂĂĂÎÎÎÇÇÇ»»»ľľľĂĂĂľľľşşşĚĚĚĘĘĘĘĘĘĚĚĚĆĆĆĘĘĘĚĚĚĚĚĚżżżÂÂÂĹĹĹŔŔŔĂĂĂşşşĆĆĆżżż»»»ľľľ´´´ÍÍÍÉÉÉĐĐĐÉÉÉĘĘĘÔÔÔÔÔÔŃŃŃŃŃŃĘĘĘÇÇÇÎÎÎĘĘĘÍÍÍŇŇŇÔÔÔŇŇŇÎÎÎĘĘĘÉÉÉĚĚĚĘĘĘÇÇÇĆĆĆĹĹĹŔŔŔ»»»¸¸¸ŻŻŻ°°°ÇÇÇŇŇŇĆĆĆĆĆĆŇŇŇŃŃŃŃŃŃŇŇŇÍÍÍĐĐĐÍÍÍÉÉÉŃŃŃÔÔÔÜÜÜŰŰŰŇŇŇÔÔÔŇŇŇĐĐĐÔÔÔĐĐĐŃŃŃÎÎÎĘĘĘÉÉÉÉÉÉĚĚĚÍÍÍÍÍÍŃŃŃŘŘŘŰŰŰŘŘŘŮŮŮßßßßßßŮŮŮŰŰŰŰŰŰŰŰŰÜÜÜÜÜÜÝÝÝßßßßßßâââÜÜÜßßßâââäääëëëëëëâââ×××ŰŰŰĐĐĐĹĹĹÇÇÇĚĚĚÉÉÉÉÉÉÉÉÉĘĘĘĘĘĘÇÇÇĹĹĹĆĆĆÉÉÉÍÍÍŇŇŇĹĹĹŔŔŔĚĚĚÔÔÔŐŐŐÜÜÜčččÝÝÝŘŘŘŐŐŐŘŘŘŘŘŘŐŐŐÔÔÔŐŐŐÔÔÔÔÔÔÎÎÎĘĘĘĂĂĂŕŕŕăăăăăăęęęăăăăăăŕŕŕŇŇŇĚĚĚÎÎÎĐĐĐŃŃŃÎÎÎÍÍÍĘĘĘĘĘĘĚĚĚÎÎÎĐĐĐ×××ŃŃŃÍÍÍÍÍÍÍÍÍÍÍÍÎÎÎŃŃŃĐĐĐŇŇŇ×××ŇŇŇĘĘĘĘĘĘŇŇŇŮŮŮŰŰŰÜÜÜÜÜÜŰŰŰŘŘŘŐŐŐŇŇŇŇŇŇÍÍÍĚĚĚĘĘĘÍÍÍŇŇŇ×××ŘŘŘ×××ÜÜÜ×××ßßßęęęęęęčččćććßßßäääćććäääŕŕŕÝÝÝÜÜÜ×××ŃŃŃŃŃŃ×××ŰŰŰÜÜÜßßßćććččččččŕŕŕŰŰŰÝÝÝâââÝÝÝÝÝÝäääçççęęęäääćććâââŇŇŇÉÉÉĚĚĚÍÍÍŃŃŃŃŃŃĐĐĐĐĐĐŃŃŃŃŃŃŇŇŇÔÔÔÍÍÍÉÉÉĂĂĂżżżŔŔŔĆĆĆÎÎÎÔÔÔ»»»ĆĆĆŐŐŐŃŃŃÂÂÂŔŔŔÇÇÇĹĹĹĽĽĽÎÎÎĚĚĚĘĘĘĘĘĘĹĹĹÇÇÇÉÉÉÎÎÎľľľÂÂÂĂĂĂľľľÉÉɸ¸¸ÉÉÉĂĂĂ»»»»»»µµµĘĘĘÉÉÉÎÎÎÇÇÇĘĘĘŇŇŇŇŇŇŃŃŃŃŃŃĚĚĚĆĆĆĘĘĘĆĆĆÍÍÍŐŐŐ×××ÔÔÔĐĐĐÍÍÍÍÍÍÉÉÉÇÇÇĆĆĆĆĆĆĆĆĆĹĹĹŔŔŔľľľ¬¬¬¬¬¬ĂĂĂŇŇŇÇÇÇĚĚĚ×××ĐĐĐĐĐĐĚĚĚĹĹĹĂĂĂĆĆĆÍÍÍŘŘŘÝÝÝŮŮŮŮŮŮ×××ÔÔÔŃŃŃĐĐĐÔÔÔ×××ŘŘŘŇŇŇÍÍÍĚĚĚÍÍÍŃŃŃŇŇŇÔÔÔÎÎÎŘŘŘŮŮŮŇŇŇÔÔÔŰŰŰŰŰŰŇŇŇâââŕŕŕßßßÝÝÝßßßŕŕŕâââăăăăăăßßßŕŕŕâââŕŕŕćććëëëçççÔÔÔŰŰŰŇŇŇĂĂĂĆĆĆÍÍÍÍÍÍĚĚĚÇÇÇĘĘĘĘĘĘÇÇÇĹĹĹĆĆĆĚĚĚŃŃŃĚĚĚŔŔŔľľľÉÉÉŐŐŐŮŮŮßßßçççÜÜÜŘŘŘ×××ŮŮŮŮŮŮŐŐŐÔÔÔÔÔÔÔÔÔŐŐŐĘĘĘÇÇÇĹĹĹŕŕŕćććęęęńńńçççăăăßßßŇŇŇĚĚĚÎÎÎÎÎÎĐĐĐÎÎÎĚĚĚÉÉÉĘĘĘÍÍÍŃŃŃÔÔÔ×××ÔÔÔŃŃŃĐĐĐÎÎÎÍÍÍÎÎÎĐĐĐŃŃŃĐĐĐŇŇŇÎÎÎĆĆĆĆĆĆÍÍÍĐĐĐŘŘŘŰŰŰÜÜÜŰŰŰ×××ŇŇŇĐĐĐĐĐĐĐĐĐĚĚĚÉÉÉĚĚĚŃŃŃŐŐŐŐŐŐÔÔÔ×××ĐĐĐŇŇŇŰŰŰßßßćććëëëçççääääääăăăâââŕŕŕßßßÜÜÜŮŮŮÎÎÎŇŇŇŐŐŐ×××ÜÜÜćććëëëëëëęęęćććääääääăăăâââçççíííëëëčččíííëëëŰŰŰĐĐĐÎÎÎÍÍÍÔÔÔŇŇŇŃŃŃÎÎÎÍÍÍĚĚĚĚĚĚĚĚĚĘĘĘÉÉÉÇÇÇĆĆĆÇÇÇĘĘĘÍÍÍÎÎÎĂĂĂĆĆĆŇŇŇŇŇŇĹĹĹĹĹĹĚĚĚÇÇÇÂÂÂŇŇŇÎÎÎĚĚĚĘĘĘĹĹĹÇÇÇÇÇÇĐĐĐżżżŔŔŔĹĹĹľľľĚĚĚşşşĚĚĚĹĹĹ»»»ĽĽĽĽĽĽĚĚĚĚĚĚĐĐĐÉÉÉĚĚĚĐĐĐÍÍÍÍÍÍŇŇŇĐĐĐÇÇÇĆĆĆĂĂĂĚĚĚŐŐŐŮŮŮŐŐŐŃŃŃÎÎÎÎÎÎÉÉÉÇÇÇĆĆĆĆĆĆÇÇÇÇÇÇĹĹĹĂĂĂ­­­ŻŻŻÂÂÂŃŃŃÍÍÍĐĐĐŇŇŇĆĆĆÉÉÉÂÂÂľľľşşşżżżĚĚĚ×××ÝÝÝŇŇŇŐŐŐŘŘŘŇŇŇĚĚĚĚĚĚĐĐĐŘŘŘŐŐŐŃŃŃÍÍÍĚĚĚÎÎÎŃŃŃŇŇŇŇŇŇÜÜÜăăăäääÝÝÝßßßęęęëëëćććăăăŕŕŕÝÝÝŰŰŰŰŰŰÝÝÝŕŕŕăăăäääâââććććććÜÜÜÝÝÝçççęęę×××ÜÜÜŃŃŃÂÂÂĹĹĹĚĚĚĚĚĚĘĘĘÇÇÇÉÉÉĘĘĘÇÇÇĆĆĆÇÇÇÎÎÎÔÔÔĹĹĹŔŔŔżżżĂĂĂÎÎÎŮŮŮâââăăăÜÜÜŘŘŘ×××ŮŮŮŮŮŮŐŐŐŇŇŇÔÔÔŇŇŇÔÔÔĹĹĹÉÉÉĘĘĘŕŕŕčččńńńóóóčččćććâââÔÔÔÍÍÍÍÍÍĚĚĚÎÎÎÍÍÍĚĚĚĘĘĘĚĚĚÎÎÎŇŇŇŐŐŐÔÔÔŐŐŐŐŐŐŇŇŇŃŃŃĐĐĐÎÎÎÍÍÍĘĘĘĆĆĆĘĘĘÍÍÍÇÇÇĚĚĚŇŇŇĐĐĐÔÔÔ×××ŮŮŮŮŮŮŐŐŐŃŃŃÎÎÎÎÎÎĐĐĐĘĘĘĆĆĆÇÇÇÍÍÍŇŇŇÔÔÔÔÔÔŮŮŮŇŇŇÔÔÔŮŮŮÝÝÝęęęňňňďďďçççćććäääâââßßßÜÜÜŰŰŰÜÜÜĐĐĐŇŇŇŐŐŐŐŐŐÜÜÜćććëëëëëëëëëčččççççççćććäääčččńńńćććâââćććäääŐŐŐĚĚĚÍÍÍÍÍÍŇŇŇŃŃŃĐĐĐÎÎÎĚĚĚÇÇÇĆĆĆĂĂĂÂÂÂĂĂĂĹĹĹĆĆĆĆĆĆĹĹĹĂĂĂĂĂĂÇÇÇĽĽĽĹĹĹĘĘĘŔŔŔÂÂÂÉÉÉÂÂÂĆĆĆŐŐŐŃŃŃÎÎÎÍÍÍĆĆĆĘĘĘĘĘĘĐĐĐĹĹĹŔŔŔĘĘĘľľľĘĘĘ»»»ÍÍÍĹĹĹ»»»żżżĆĆĆĐĐĐĐĐĐŃŃŃĚĚĚÎÎÎĐĐĐĚĚĚĚĚĚŇŇŇĐĐĐÇÇÇĆĆĆĂĂĂĚĚĚÔÔÔŘŘŘŐŐŐĐĐĐÎÎÎÎÎÎÎÎÎÍÍÍĘĘĘÉÉÉÉÉÉÇÇÇĹĹĹĂĂñ±±¸¸¸ĆĆĆĐĐĐÎÎÎÎÎÎÉÉÉĽĽĽżżż»»»ĽĽĽ···»»»ÇÇÇĚĚĚŃŃŃĚĚĚÎÎÎ×××ŃŃŃÉÉÉĘĘĘĘĘĘŇŇŇŃŃŃĐĐĐÎÎÎÎÎÎĐĐĐŃŃŃŃŃŃŃŃŃĘĘĘĐĐĐŃŃŃÎÎÎŇŇŇÜÜÜŕŕŕÝÝÝÝÝÝŰŰŰŘŘŘŐŐŐŐŐŐŘŘŘŰŰŰÝÝÝâââŕŕŕççççççÜÜÜŮŮŮâââćććßßßÝÝÝÍÍÍżżżĂĂĂÉÉÉÇÇÇĹĹĹĆĆĆÇÇÇÉÉÉÉÉÉÉÉÉĚĚĚĐĐĐŐŐŐĹĹĹĂĂĂŔŔŔľľľĹĹĹŇŇŇÝÝÝâââßßßŮŮŮŐŐŐŘŘŘ×××ŇŇŇŃŃŃŃŃŃĐĐĐĐĐĐÂÂÂŃŃŃ×××ŕŕŕçççőőőńńńçççäääâââÔÔÔÍÍÍĚĚĚĘĘĘÍÍÍĚĚĚĚĚĚÍÍÍÎÎÎĐĐĐŇŇŇÔÔÔŃŃŃÔÔÔŐŐŐŐŐŐÔÔÔŇŇŇÎÎÎÉÉÉÉÉÉĹĹĹÍÍÍŇŇŇĘĘĘĚĚĚŃŃŃĘĘĘÎÎÎŇŇŇŐŐŐŘŘŘ×××ŇŇŇĐĐĐÍÍÍĚĚĚÇÇÇĂĂĂĹĹĹĘĘĘĐĐĐÔÔÔŐŐŐĚĚĚÇÇÇĚĚĚĐĐĐŇŇŇÜÜÜŕŕŕŮŮŮëëëčččçççäääßßßŘŘŘ×××ŘŘŘŐŐŐŮŮŮŰŰŰŰŰŰÝÝÝäääččččččćććçççäääćććčččçççčččňňňčččââââââÜÜÜÎÎÎÉÉÉĐĐĐÔÔÔĐĐĐÎÎÎÎÎÎÍÍÍĚĚĚÉÉÉĆĆĆĆĆĆĹĹĹĹĹĹĹĹĹĂĂĂĹĹĹĆĆĆÇÇÇÇÇÇÎÎλ»»ŔŔŔĘĘĘÂÂÂĹĹĹĚĚĚĂĂĂĆĆĆ×××ŃŃŃÎÎÎÎÎÎÉÉÉÍÍÍÎÎÎŃŃŃÍÍÍĂĂĂĐĐĐżżżĆĆĆ»»»ĘĘĘŔŔŔşşşÂÂÂÎÎÎŇŇŇŇŇŇŇŇŇĚĚĚŇŇŇŐŐŐŃŃŃÎÎÎŃŃŃÎÎÎÇÇÇÉÉÉĆĆĆĚĚĚŃŃŃŇŇŇŃŃŃÎÎÎÎÎÎÎÎÎÎÎÎĚĚĚÉÉÉĆĆĆĆĆĆĹĹĹÂÂÂżżż°°°ÂÂÂÍÍÍÍÍÍÍÍÍÇÇÇŔŔŔżżżĽĽĽ»»»ŔŔŔşşşĽĽĽÉÉÉÉÉÉÍÍÍÎÎÎÍÍÍŐŐŐŃŃŃĐĐĐŃŃŃÉÉÉÍÍÍÎÎÎĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐŃŃŃŇŇŇŃŃŃŇŇŇŃŃŃĐĐĐĐĐĐĐĐĐĐĐĐÎÎÎ××××××ŐŐŐŐŐŐŐŐŐ×××ŘŘŘŮŮŮÜÜÜŘŘŘßßßäääßßßÜÜÜßßßÝÝÝäääŮŮŮĹĹĹ»»»ĂĂĂÉÉÉĹĹĹĹĹĹĹĹĹĆĆĆÇÇÇÉÉÉĚĚĚÎÎÎŇŇŇÔÔÔĂĂĂÂÂÂÂÂÂÂÂÂĂĂĂÇÇÇŇŇŇÝÝÝŕŕŕŮŮŮŐŐŐŐŐŐŐŐŐŃŃŃÎÎÎĐĐĐĚĚĚÍÍÍÂÂÂÝÝÝäääŕŕŕâââňňňčččŕŕŕŕŕŕÝÝÝŃŃŃĘĘĘĚĚĚĚĚĚĘĘĘĚĚĚÎÎÎĐĐĐŃŃŃŃŃŃŃŃŃĐĐĐĐĐĐŇŇŇÔÔÔÔÔÔŐŐŐŐŐŐĐĐĐĆĆĆÉÉÉÉÉÉŮŮŮÜÜÜĚĚĚÇÇÇÍÍÍĆĆĆĘĘĘÍÍÍŃŃŃŐŐŐŘŘŘŐŐŐŃŃŃÍÍÍÉÉÉÇÇÇĹĹĹĹĹĹÇÇÇĚĚĚÎÎÎŃŃŃĐĐĐÎÎÎŇŇŇ×××ŮŮŮâââäääÜÜÜęęęččččččęęęăăăŮŮŮŐŐŐ×××ŮŮŮßßßâââÝÝÝŰŰŰÜÜÜÝÝÝÜÜÜćććęęęčččęęęîîîčččçççńńńîîîćććăăăÝÝÝĐĐĐĚĚĚŇŇŇŘŘŘŃŃŃŃŃŃÎÎÎÍÍÍĚĚĚĘĘĘĘĘĘĘĘĘĘĘĘÇÇÇĆĆĆĹĹĹĆĆĆĘĘĘĐĐĐŇŇŇŃŃŃĽĽĽĆĆĆŇŇŇÇÇÇĆĆĆĐĐĐÉÉÉĹĹĹÔÔÔĐĐĐÎÎÎÍÍÍÉÉÉÎÎÎŃŃŃÔÔÔÔÔÔĹĹĹŐŐŐżżżĂĂĂşşşÇÇÇľľľ¸¸¸ĂĂĂŇŇŇÔÔÔÔÔÔŇŇŇÍÍÍÔÔÔŰŰŰŘŘŘŇŇŇĐĐĐĘĘĘÇÇÇÍÍÍÉÉÉĚĚĚÎÎÎÎÎÎÍÍÍÍÍÍÎÎÎĐĐĐÇÇÇĹĹĹÂÂÂŔŔŔŔŔŔŔŔŔľľľĽĽĽŞŞŞĹĹĹĐĐĐĚĚĚĘĘĘĂĂĂżżżÇÇÇŔŔŔżżżĹĹĹĽĽĽľľľÍÍÍÎÎÎŐŐŐ×××ĐĐĐ×××ŐŐŐŘŘŘÜÜÜÍÍÍĚĚĚÉÉÉĘĘĘĚĚĚĘĘĘÉÉÉÉÉÉĚĚĚÎÎÎÍÍÍÍÍÍÎÎÎŃŃŃŃŃŃÎÎÎÎÎÎÎÎÎÔÔÔŐŐŐ×××ŘŘŘŮŮŮŮŮŮŘŘŘŘŘŘŘŘŘĐĐĐŐŐŐââââââŕŕŕÝÝÝŘŘŘăăăÔÔÔĽĽĽ···ĹĹĹĘĘĘÇÇÇÉÉÉĹĹĹĹĹĹÇÇÇĘĘĘÍÍÍŃŃŃŇŇŇÔÔÔżżżľľľĂĂĂĚĚĚÇÇÇŔŔŔÇÇÇ×××âââŰŰŰŐŐŐÔÔÔŇŇŇÎÎÎÍÍÍĐĐĐĘĘĘĚĚĚĂĂĂçççîîîŕŕŕÝÝÝîîîâââŰŰŰŰŰŰŰŰŰÎÎÎÉÉÉÍÍÍÎÎÎÉÉÉĚĚĚÎÎÎŇŇŇŇŇŇŇŇŇĐĐĐÎÎÎĐĐĐŇŇŇŇŇŇŃŃŃÔÔÔ×××ĐĐĐĆĆĆŔŔŔÇÇÇßßßăăăĚĚĚĆĆĆĐĐĐÍÍÍÇÇÇĘĘĘÎÎÎÔÔÔŘŘŘ×××ŇŇŇÍÍÍĘĘĘĘĘĘÉÉÉÇÇÇĆĆĆĆĆĆÇÇÇÉÉÉŃŃŃÎÎÎŇŇŇŐŐŐŘŘŘäääęęęâââääääääęęęîîîčččÝÝÝŘŘŘŘŘŘŰŰŰŕŕŕăăăÝÝÝ×××ÔÔÔŇŇŇĐĐĐíííńńńďďďďďďóóóëëëćććîîîëëëääääääŕŕŕŃŃŃĘĘĘĐĐĐŇŇŇŘŘŘŐŐŐŃŃŃÍÍÍĘĘĘĘĘĘĚĚĚÍÍÍĂĂĂÂÂÂÂÂÂÂÂÂĆĆĆĘĘĘĐĐĐŇŇŇĘĘʸ¸¸ĆĆĆÔÔÔĹĹĹŔŔŔĚĚĚÇÇÇÂÂÂŇŇŇÎÎÎĚĚĚÍÍÍÉÉÉĐĐĐŃŃŃÔÔÔ×××ÎÎÎĂĂĂŃŃŃşşş¸¸¸ÇÇÇŔŔŔşşşŃŃŃĐĐĐ×××ÔÔÔŇŇŇĐĐĐŃŃŃÔÔÔŐŐŐÎÎÎÎÎÎÎÎÎĆĆĆĐĐĐĆĆĆÎÎÎŃŃŃÍÍÍĘĘĘÎÎÎŃŃŃĐĐĐÇÇÇżżżżżżľľľµµµ···¸¸¸°°°ÎÎÎŐŐŐŃŃŃŔŔŔşşşÂÂÂÇÇÇĂĂĂżżż»»»»»»ÂÂÂÉÉÉÍÍÍĐĐĐÔÔÔÔÔÔÍÍÍÔÔÔŇŇŇŐŐŐŮŮŮĚĚĚĚĚĚŃŃŃĚĚĚĚĚĚĘĘĘÂÂÂŔŔŔĹĹĹŔŔŔĹĹĹĆĆĆĘĘĘĘĘĘĘĘĘÇÇÇĹĹĹĂĂĂĆĆĆÍÍÍĐĐĐÇÇÇĂĂĂÉÉÉŃŃŃ×××ÔÔÔŮŮŮŇŇŇ×××čččçççŰŰŰÝÝÝăăăßßßŮŮŮŇŇŇÍÍÍÉÉÉĆĆĆĂĂĂÂÂÂĂĂĂĆĆĆÉÉÉÍÍÍÔÔÔŰŰŰßßßĹĹĹżżżĂĂĂÇÇÇĹĹĹÉÉÉÍÍÍĆĆĆŘŘŘÜÜÜŃŃŃŃŃŃŇŇŇĐĐĐŐŐŐÉÉÉĚĚĚĽĽĽĂĂĂŕŕŕîîîăăăŕŕŕëëëŘŘŘŇŇŇŐŐŐŇŇŇÔÔÔÔÔÔĆĆĆĹĹĹĐĐĐÍÍÍĚĚĚĘĘĘÍÍÍŇŇŇŘŘŘŰŰŰÎÎÎĐĐĐŃŃŃÔÔÔÍÍÍÔÔÔŰŰŰŔŔŔĹĹĹÎÎÎÜÜÜŮŮŮĘĘĘĘĘĘŃŃŃÍÍÍÉÉÉÉÉÉĚĚĚŃŃŃ××××××ŃŃŃĚĚĚÉÉÉĚĚĚĘĘĘĹĹĹÍÍÍÉÉÉÇÇÇęęęÎÎÎÍÍÍŃŃŃŘŘŘŮŮŮŮŮŮßßßççççççďďďňňňęęęßßßŮŮŮ×××ŐŐŐÜÜÜÜÜÜŮŮŮŐŐŐŃŃŃŃŃŃÔÔÔ×××ŘŘŘăăăíííňňňóóóďďďäääŮŮŮíííăăăęęęçççÍÍÍĆĆĆŃŃŃÎÎÎŃŃŃ×××ŘŘŘŃŃŃÍÍÍÍÍÍĚĚĚÉÉÉŐŐŐŇŇŇĘĘĘĘĘĘÉÉÉŃŃŃÜÜÜÍÍÍľľľÂÂÂĆĆĆŘŘŘĹĹĹÉÉÉÍÍÍżżżŔŔŔ×××ŘŘŘÎÎÎĐĐĐÔÔÔŃŃŃŃŃŃÔÔÔÔÔÔĘĘĘĘĘĘŐŐŐĽĽĽÂÂÂÇÇÇĹĹĹĽĽĽĘĘĘŇŇŇ×××ÔÔÔŇŇŇĐĐĐŘŘŘŘŘŘŰŰŰŘŘŘÜÜÜŮŮŮÇÇÇÇÇÇÎÎÎÎÎÎÍÍÍĘĘĘĘĘĘÍÍÍĚĚĚÉÉÉŔŔŔÉÉÉ×××ÜÜÜ×××ÔÔÔ××××××ŮŮŮÎÎÎÇÇÇÉÉÉÇÇÇŔŔŔľľľżżżĘĘĘĆĆĆĹĹĹÉÉÉÎÎÎÎÎÎŃŃŃÔÔÔĽĽĽľľľĘĘĘÍÍÍŃŃŃŐŐŐÇÇÇĂĂĂĘĘĘÉÉÉĘĘĘĆĆƸ¸¸···»»»»»»»»»ĽĽĽľľľŔŔŔÂÂÂÂÂÂĂĂĂĂĂĂÂÂÂÇÇÇÉÉÉĹĹĹÂÂÂÇÇÇÎÎÎŃŃŃŐŐŐÜÜÜŐŐŐ×××çççćććŮŮŮŰŰŰęęęććććććçççŮŮŮÉÉÉĹĹĹÍÍÍĹĹĹĆĆĆÇÇÇĘĘĘÍÍÍŃŃŃŘŘŘÜÜÜŘŘŘÎÎÎĚĚĚÍÍÍĚĚĚÍÍÍĘĘĘŔŔŔŰŰŰâââŘŘŘ×××ÔÔÔĐĐĐÔÔÔĚĚĚĘĘĘÂÂÂÉÉÉßßßęęęäääŕŕŕćććäääŰŰŰŮŮŮÔÔÔ×××ŮŮŮÎÎÎĚĚĚÍÍÍÍÍÍÍÍÍÍÍÍÎÎÎŃŃŃÔÔÔŐŐŐŮŮŮŮŮŮŘŘŘŘŘŘĘĘĘĘĘĘŐŐŐÂÂÂÇÇÇÇÇÇĚĚĚĚĚĚÇÇÇĚĚĚÍÍÍĹĹĹĹĹĹĹĹĹĆĆĆĚĚĚŃŃŃŃŃŃÍÍÍÉÉÉÇÇÇÇÇÇÉÉÉĂĂĂÇÇÇĆĆĆĹĹĹÜÜÜĐĐĐĐĐĐŇŇŇŮŮŮÜÜÜŰŰŰÝÝÝâââăăăęęęëëëäääÜÜÜŮŮŮŘŘŘ×××ÝÝÝÜÜÜŘŘŘŐŐŐŇŇŇŇŇŇÔÔÔ×××ÔÔÔŰŰŰăăăçççęęęęęęăăăŰŰŰćććßßßÜÜÜÝÝÝ×××ĚĚĚĘĘĘĐĐĐĚĚĚĐĐĐŃŃŃĚĚĚĘĘĘÍÍÍĐĐĐÎÎÎÎÎÎĐĐĐÎÎÎŃŃŃÎÎÎÍÍÍŃŃŃŔŔŔżżżĹĹĹĆĆĆŰŰŰĚĚĚÎÎÎŃŃŃĘĘĘÇÇÇŇŇŇ×××ŇŇŇŇŇŇŇŇŇŇŇŇÔÔÔ×××ĐĐĐĹĹĹÎÎÎŘŘŘŔŔŔÍÍÍÉÉÉÇÇÇľľľżżż××××××ÔÔÔŇŇŇĐĐĐÜÜÜŘŘŘŮŮŮŮŮŮäääăăăĚĚĚÇÇÇÔÔÔÍÍÍÇÇÇÇÇÇĘĘĘÉÉÉĆĆĆĹĹĹżżżÎÎÎŰŰŰßßßÝÝÝ×××ÔÔÔŘŘŘŮŮŮĘĘĘĹĹĹĚĚĚĘĘĘĽĽĽµµµşşşşşş´´´±±±´´´µµµłłł´´´···żżżÂÂÂÇÇÇĂĂĂĹĹĹĚĚĚĆĆĆĂĂĂÉÉÉÇÇÇĚĚĚĹĹŵµµ±±±¸¸¸şşşŻŻŻ°°°±±±µµµşşşľľľŔŔŔÂÂÂżżżĹĹĹĆĆĆĹĹĹĆĆĆĘĘĘÎÎÎĐĐĐÔÔÔŘŘŘÔÔÔŐŐŐăăăăăăŰŰŰßßßććććććęęęëëëßßßĘĘĘŔŔŔÂÂÂĆĆĆÇÇÇĘĘĘĚĚĚÍÍÍĐĐĐŐŐŐŘŘŘßßßŘŘŘÔÔÔŃŃŃĚĚĚÍÍÍĐĐĐĚĚĚÝÝÝăăăßßßÜÜÜŘŘŘŇŇŇŐŐŐŃŃŃĹĹĹÍÍÍŘŘŘŕŕŕăăăââââââăăăíííßßßŮŮŮÔÔÔŘŘŘÝÝÝŇŇŇĐĐĐĘĘĘĚĚĚÍÍÍÎÎÎĐĐĐĐĐĐÎÎÎÎÎÎÉÉÉÎÎÎ×××ŕŕŕÔÔÔÍÍÍÔÔÔÉÉÉĆĆĆÂÂÂÂÂÂÂÂÂĂĂĂÉÉÉĘĘĘĂĂĂĂĂĂĂĂĂĆĆĆĚĚĚŇŇŇ×××ŐŐŐŇŇŇĘĘĘĆĆĆĘĘĘĆĆĆĆĆĆĚĚĚĚĚĚŐŐŐÔÔÔŇŇŇŐŐŐŰŰŰÝÝÝÝÝÝÜÜÜÝÝÝŕŕŕääääääßßßŰŰŰŰŰŰŰŰŰŮŮŮßßßÜÜÜŘŘŘŐŐŐÔÔÔŐŐŐŐŐŐŐŐŐŇŇŇ×××ŰŰŰÝÝÝâââçççćććŕŕŕăăăăăăŮŮŮŘŘŘŰŰŰÇÇÇşşşĹĹĹĘĘĘÍÍÍÍÍÍĘĘĘĘĘĘÎÎÎŇŇŇŇŇŇĚĚĚÎÎÎŃŃŃŇŇŇŃŃŃĆĆĆÇÇÇşşşŔŔŔĆĆĆĹĹĹŰŰŰŇŇŇŃŃŃŇŇŇŐŐŐÉÉÉĆĆĆÎÎÎŐŐŐÔÔÔŇŇŇŘŘŘŰŰŰÜÜÜÇÇÇĹĹĹÍÍÍÔÔÔĹĹĹĐĐĐÉÉÉĆĆĆľľľ···ŘŘŘ×××ŐŐŐŐŐŐÔÔÔÜÜÜ×××ŐŐŐÔÔÔßßßâââŇŇŇŃŃŃÔÔÔĚĚĚĆĆĆÇÇÇĆĆĆÂÂÂÂÂÂÇÇÇÉÉÉÔÔÔŐŐŐ×××ßßßŰŰŰÔÔÔŮŮŮĘĘĘÍÍÍÍÍÍÇÇÇżżżşşş······ľľľ¸¸¸·········łłł´´´···¸¸¸ľľľŔŔŔ»»»ľľľÇÇÇĘĘĘÉÉÉĂĂĂżżżŔŔŔĽĽĽ±±±ŻŻŻłłł±±±¦¦¦©©©¬¬¬łłł¸¸¸ĽĽĽľľľľľľĂĂĂĹĹĹÇÇÇĘĘĘÎÎÎŃŃŃŇŇŇŇŇŇÎÎÎŃŃŃÍÍÍÎÎÎŰŰŰŕŕŕßßßäääÝÝÝăăăçççäääŕŕŕŐŐŐĂĂĂłłłĂĂĂÇÇÇĘĘĘÍÍÍÍÍÍÎÎÎÔÔÔŘŘŘÝÝÝßßßÝÝÝŐŐŐÉÉÉÇÇÇŇŇŇÜÜÜââââââßßßÝÝÝÜÜÜŮŮŮŘŘŘŇŇŇŔŔŔŘŘŘçççăăăÜÜÜßßßääääääćććŮŮŮŐŐŐŇŇŇŘŘŘÜÜÜĐĐĐĚĚĚĘĘĘĚĚĚÍÍÍÎÎÎÎÎÎÍÍÍĘĘĘÉÉÉÇÇÇÉÉÉĐĐĐÜÜÜŇŇŇĆĆĆÉÉÉŔŔŔÂÂÂÂÂÂÂÂÂÂÂÂŔŔŔĹĹĹÇÇÇÇÇÇĂĂĂĹĹĹÇÇÇÎÎÎ×××ÜÜÜßßßÝÝÝÔÔÔÇÇÇÍÍÍĘĘĘĘĘĘ×××ŘŘŘŘŘŘ×××ŐŐŐŐŐŐŮŮŮÝÝÝßßßßßßßßßŕŕŕăăăŕŕŕÜÜÜŰŰŰÝÝÝÝÝÝŰŰŰßßßŰŰŰ×××ŐŐŐ×××××××××ŐŐŐ×××ŮŮŮŰŰŰÜÜÜăăăęęęęęęćććâââëëëćććâââäääÔÔÔÂÂÂĆĆĆÉÉÉĘĘĘĚĚĚÍÍÍÎÎÎĐĐĐŃŃŃŇŇŇÎÎÎĐĐĐĐĐĐÎÎÎÎÎÎżżżĆĆĆľľľŔŔŔÇÇÇÂÂÂŘŘŘÔÔÔĐĐĐÎÎÎŘŘŘĐĐĐÂÂÂÉÉÉŘŘŘŐŐŐŃŃŃŘŘŘŰŰŰßßßÂÂÂÉÉÉĆĆĆĘĘĘÇÇÇĘĘĘÇÇÇ»»»µµµŘŘŘŘŘŘ×××ŘŘŘŘŘŘÜÜÜŮŮŮŮŮŮÔÔÔŰŰŰÝÝÝŇŇŇŘŘŘÍÍÍÉÉÉÇÇÇĆĆĆŔŔŔĽĽĽĂĂĂÎÎÎŘŘŘÝÝÝŮŮŮ×××ÜÜÜŘŘŘŃŃŃŐŐŐÇÇÇĐĐĐĐĐĐĂĂĂĽĽĽżżżľľľ¸¸¸»»»···µµµ···´´´±±±łłł···şşşŔŔŔŔŔŔżżżĽĽĽşşş···ŻŻŻ¸¸¸°°°­­­­­­ŞŞŞ¬¬¬­­­¦¦¦¦¦¦©©©­­­µµµ»»»ľľľ»»»¸¸¸ĂĂĂĂĂĂÇÇÇÍÍÍŃŃŃŇŇŇŇŇŇŇŇŇÎÎÎÎÎÎĘĘĘĘĘĘŇŇŇŘŘŘÜÜÜäääßßßćććęęęęęęčččâââŃŃŃżżżżżżĹĹĹĘĘĘÍÍÍÍÍÍĐĐĐÔÔÔŮŮŮÝÝÝćććçççßßßÔÔÔÎÎÎÔÔÔÝÝÝëëëâââÜÜÜŰŰŰÜÜÜŰŰŰŇŇŇÍÍÍÉÉÉÝÝÝčččâââÝÝÝäääçççŕŕŕŰŰŰŇŇŇŐŐŐÔÔÔŮŮŮŰŰŰĚĚĚĆĆĆĘĘĘĘĘĘĘĘĘĚĚĚĚĚĚĘĘĘĘĘĘÉÉÉĐĐĐÇÇÇżżżÉÉÉĆĆĆľľľĂĂĂżżżÂÂÂÂÂÂŔŔŔŔŔŔÂÂÂÂÂÂĂĂĂĆĆĆĆĆĆĆĆĆÉÉÉÎÎÎÔÔÔŘŘŘŰŰŰÜÜÜßßßÎÎÎĐĐĐÍÍÍĚĚĚŰŰŰÝÝÝŘŘŘŮŮŮŘŘŘ××××××ÜÜÜâââăăăăăăăăăäääâââÜÜÜÜÜÜßßßßßßÜÜÜßßßŰŰŰŘŘŘ×××ŘŘŘŘŘŘŘŘŘ×××ŰŰŰÜÜÜÜÜÜÝÝÝćććíííëëëćććäääęęęčččăăăâââŮŮŮĆĆĆ···ÂÂÂÂÂÂĹĹĹĘĘĘÍÍÍÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍĐĐĐÍÍÍŇŇŇĽĽĽĆĆĆĹĹĹĆĆĆĚĚĚĹĹĹŰŰŰŐŐŐĐĐĐÍÍÍŐŐŐÝÝÝĚĚĚÎÎÎŰŰŰŘŘŘÔÔÔ×××ŘŘŘŘŘŘŔŔŔĐĐĐŔŔŔĂĂĂÉÉÉĆĆĆĆĆĆľľľ¸¸¸ľľľŐŐŐ×××ŐŐŐŮŮŮŮŮŮÜÜÜÝÝÝâââÜÜÜßßßÜÜÜÎÎÎŇŇŇÉÉÉÉÉÉÉÉÉĂĂĂĽĽĽĽĽĽÇÇÇÔÔÔ×××ÝÝÝÝÝÝŘŘŘŃŃŃÉÉÉĹĹĹÉÉÉÎÎÎĚĚĚĆĆĆÂÂÂÂÂÂĂĂĂŔŔŔ»»»ľľľ»»»»»»ĽĽĽ»»»¸¸¸»»»ŔŔŔşşşľľľşşşľľľżżż»»»ĽĽĽ¸¸¸¸¸¸­­­©©©¬¬¬­­­łłł±±±¨¨¨¬¬¬­­­°°°µµµ»»»ľľľ»»»···żżżżżżĂĂĂĘĘĘÎÎÎÍÍÍÍÍÍÎÎÎŃŃŃŃŃŃÍÍÍĘĘĘÍÍÍŃŃŃ×××ÜÜÜŕŕŕăăăęęęîîîęęęŕŕŕŮŮŮ×××»»»ÂÂÂĘĘĘÎÎÎÎÎÎĐĐĐŐŐŐŮŮŮŰŰŰăăăćććçççęęęäääßßßŕŕŕńńńâââÜÜÜ××××××ÔÔÔÇÇÇĹĹĹŘŘŘßßßŕŕŕÜÜÜßßßçççăăă×××ÔÔÔŃŃŃŘŘŘŘŘŘŘŘŘ×××ÉÉÉĆĆĆÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉĘĘĘĘĘĘĚĚĚÍÍÍĹĹĹşşşÂÂÂĂĂĂľľľĂĂĂŔŔŔÇÇÇĂĂĂ»»»»»»ÂÂÂŔŔŔľľľŔŔŔŃŃŃŃŃŃŇŇŇÔÔÔŐŐŐ×××ŘŘŘŘŘŘćććŃŃŃĐĐĐÍÍÍÍÍÍŘŘŘŘŘŘŐŐŐŰŰŰŰŰŰŮŮŮ×××ŰŰŰâââććććććääääääăăăÝÝÝÜÜÜŕŕŕŕŕŕÜÜÜÝÝÝŰŰŰŮŮŮŘŘŘŘŘŘŮŮŮŘŘŘŘŘŘŰŰŰŰŰŰÜÜÜÝÝÝćććíííëëëăăăăăăŕŕŕâââăăăâââŕŕŕŃŃѸ¸¸ľľľ»»»»»»żżżĂĂĂĆĆĆÇÇÇĚĚĚÉÉÉÇÇÇĐĐĐĐĐĐÜÜÜľľľĹĹĹĹĹĹÍÍÍŃŃŃÍÍÍŕŕŕŐŐŐŃŃŃĐĐĐŃŃŃÜÜÜŃŃŃĐĐĐ×××ÜÜÜßßßßßßÝÝÝĚĚĚĆĆĆŇŇŇżżżĂĂĂÇÇÇÇÇÇĂĂĂ»»»···ĘĘĘÔÔÔŐŐŐÔÔÔ×××ŘŘŘŰŰŰÜÜÜßßßŰŰŰÝÝÝŰŰŰĘĘĘÍÍÍÉÉÉĘĘĘÇÇÇżżżĽĽĽÂÂÂÍÍÍÔÔÔŃŃŃĐĐĐÔÔÔŇŇŇÍÍÍĚĚĚÍÍÍĚĚĚĘĘĘĂĂĂżżżŔŔŔŔŔŔĽĽĽ¸¸¸¸¸¸···µµµµµµ···µµµ´´´···ľľľĆĆĆ···żżżŔŔŔ¸¸¸ĽĽĽ»»»ľľľ´´´łłłµµµµµµşşş»»»łłł´´´°°°­­­ŻŻŻ´´´şşş»»»»»»ĽĽĽĽĽĽŔŔŔÇÇÇĘĘĘÇÇÇÉÉÉÍÍÍŃŃŃŇŇŇŃŃŃĐĐĐÎÎÎĐĐĐÔÔÔ×××ŕŕŕâââäääćććäääŕŕŕŕŕŕŕŕŕşşşÂÂÂĚĚĚĐĐĐÎÎÎĐĐĐÔÔÔŮŮŮŘŘŘßßßŕŕŕćććďďďďďďęęęíííęęęÝÝÝŰŰŰŇŇŇÍÍÍĘĘĘŔŔŔĆĆĆßßßŕŕŕÝÝÝŰŰŰÜÜÜÜÜÜŘŘŘŇŇŇŇŇŇŇŇŇŰŰŰŐŐŐĐĐĐÍÍÍĹĹĹĆĆĆĹĹĹĹĹĹÇÇÇÉÉÉĘĘĘĚĚĚÍÍÍÍÍÍÎÎÎÎÎÎĆĆĆÇÇÇĆĆĆżżżĂĂĂżżżÍÍÍĘĘĘÂÂÂľľľŔŔŔĽĽĽĽĽĽĆĆĆŐŐŐ×××ŘŘŘŮŮŮŮŮŮŮŮŮŘŘŘŘŘŘăăăĐĐĐÍÍÍÎÎÎÔÔÔŮŮŮŐŐŐŰŰŰÜÜÜßßßÝÝÝŰŰŰŰŰŰŕŕŕäääăăăŕŕŕăăăâââÝÝÝÜÜÜßßßŕŕŕÝÝÝŰŰŰÜÜÜŰŰŰŰŰŰŮŮŮŘŘŘŮŮŮŮŮŮŰŰŰÜÜÜÜÜÜßßßçççďďďíííćććŕŕŕÜÜÜăăăëëëćććŕŕŕÝÝÝŮŮŮÍÍ͸¸¸···¸¸¸ĽĽĽĂĂĂĚĚĚĆĆĆĹĹĹÍÍÍÎÎÎßßßľľľĂĂĂĹĹĹÍÍÍŃŃŃŃŃŃâââŃŃŃŇŇŇŇŇŇĘĘĘŐŐŐÔÔÔÍÍÍĚĚĚŘŘŘâââßßßŘŘŘÂÂÂĘĘĘÔÔÔÂÂÂĆĆĆĆĆĆĚĚĚ»»»···ÔÔÔŃŃŃŐŐŐŃŃŃÔÔÔ×××ŘŘŘŐŐŐŐŐŐŃŃŃŘŘŘŮŮŮĘĘĘĘĘĘĚĚĚĚĚĚĹĹĹĽĽĽĽĽĽÇÇÇĐĐĐŃŃŃŮŮŮĘĘĘĹĹĹĹĹĹŔŔŔĹĹĹĆĆĆ»»»ĽĽĽľľľżżż»»»µµµ°°°ŻŻŻ±±±´´´łłłłłł´´´łłł±±±´´´»»»µµµłłł­­­ŔŔŔĆĆƸ¸¸şşş···ĽĽĽ······¸¸¸´´´···»»»···şşş±±±©©©¦¦¦¬¬¬µµµĽĽĽľľľľľľľľľÂÂÂÉÉÉĘĘĘÇÇÇÉÉÉÎÎÎÍÍÍĐĐĐÔÔÔŐŐŐŃŃŃŃŃŃŐŐŐ×××äääçççâââŰŰŰâââíííëëëßßß»»»ĂĂĂĚĚĚĐĐĐÎÎÎÎÎÎŇŇŇŘŘŘÝÝÝäääâââßßßăăăäääçççňňňßßßŐŐŐŮŮŮĐĐĐÇÇÇĹĹĹŔŔŔÍÍÍßßßâââăăăÝÝÝÔÔÔÍÍÍÎÎÎÔÔÔŇŇŇŇŇŇŮŮŮĐĐĐĆĆĆĂĂĂľľľĆĆĆÂÂÂĂĂĂĆĆĆÉÉÉĚĚĚÍÍÍÍÍÍÍÍÍÉÉÉÎÎÎĆĆĆĹĹĹĹĹĹĆĆĆŐŐŐŮŮŮŃŃŃŐŐŐÎÎÎĹĹĹżżż···ľľľÔÔÔÍÍÍĐĐĐŇŇŇÔÔÔŐŐŐŐŐŐŐŐŐŐŐŐÝÝÝÍÍÍĚĚĚŇŇŇÜÜÜßßßŰŰŰäääÜÜÜââââââÝÝÝÜÜÜßßßâââŕŕŕŰŰŰŕŕŕŕŕŕÝÝÝÜÜÜßßßŕŕŕßßßŰŰŰÜÜÜÜÜÜŰŰŰŮŮŮŘŘŘŮŮŮŰŰŰÝÝÝÝÝÝÝÝÝŕŕŕęęęóóóňňňëëëäääăăăęęęęęęŇŇҸ¸¸»»»ŃŃŃâââĐĐĐĽĽĽ´´´łłł···ŔŔŔĚĚĚÉÉÉĹĹĹÉÉÉÉÉÉÝÝÝşşşÂÂÂĹĹĹÉÉÉĚĚĚĐĐĐŕŕŕĚĚĚĐĐĐŇŇŇĂĂĂ×××ŰŰŰÍÍÍŔŔŔÎÎÎŘŘŘÎÎÎĹĹĹÂÂÂÔÔÔ×××ĆĆĆĂĂĂŃŃŃĐĐĐżżż···ĽĽĽĐĐĐŮŮŮŃŃŃĐĐĐ×××ŘŘŘÝÝÝĐĐĐÍÍÍÔÔÔÔÔÔÔÔÔŇŇŇĚĚĚÍÍÍĘĘĘĚĚĚĽĽĽ»»»ŃŃŃŐŐŐÍÍÍĘĘĘĆĆĆĹĹĹÇÇÇĘĘĘĆĆĆĽĽĽµµµÂÂÂĽĽĽŻŻŻ»»»ĹĹĹżżżľľľ°°°ŻŻŻŻŻŻŻŻŻŻŻŻ­­­¬¬¬­­­ŻŻŻ´´´±±±ĂĂĂÂÂÂľľľ°°°´´´¬¬¬µµµ°°°ŻŻŻ¬¬¬¬¬¬µµµ»»»´´´´´´ŻŻŻ©©©©©©±±±şşş»»»¸¸¸ľľľżżżĂĂĂĆĆĆÉÉÉĘĘĘĚĚĚĚĚĚÎÎÎĐĐĐŐŐŐÎÎÎŐŐŐŮŮŮĐĐĐŰŰŰŐŐŐäääŘŘŘßßßňňňîîîííííííŕŕŕÂÂÂĘĘĘÍÍÍĐĐĐŘŘŘÎÎÎŰŰŰŘŘŘŰŰŰÝÝÝßßßŕŕŕâââăăăăăăÝÝÝŇŇŇĚĚĚÉÉÉÍÍÍľľľ´´´ŮŮŮ×××ÝÝÝÔÔÔÉÉÉĚĚĚĚĚĚĆĆĆÇÇÇ×××ŇŇŇŰŰŰŐŐŐľľľşşşĂĂĂżżżľľľŔŔŔĹĹĹÉÉÉĚĚĚÍÍÍÍÍÍĚĚĚĚĚĚĘĘĘĆĆĆÍÍÍŰŰŰŘŘŘĐĐĐŇŇŇŇŇŇÎÎÎĐĐĐŐŐŐ×××ŃŃŃĐĐĐŃŃŃŃŃŃÔÔÔ×××ŘŘŘŘŘŘŐŐŐŇŇŇĐĐĐÝÝÝÝÝÝŐŐŐŰŰŰÝÝÝÜÜÜßßß×××ÜÜÜŕŕŕßßßßßßćććäääâââäääÜÜÜŰŰŰŮŮŮŮŮŮŰŰŰÝÝÝŕŕŕâââŕŕŕŕŕŕßßßÝÝÝŰŰŰŮŮŮŮŮŮŘŘŘŕŕŕŕŕŕâââăăăćććęęęíííďďďíííëëëëëëęęęŮŮŮşşş···ŃŃŃÔÔÔµµµ°°°łłłłłł···ĽĽĽĘĘĘÂÂÂŔŔŔŔŔŔĘĘĘĘĘĘÎÎλ»»ĹĹĹÂÂÂÇÇÇŘŘŘßßß×××ŇŇŇŃŃŃÉÉÉÇÇÇŮŮŮŮŮŮÍÍÍÉÉÉĹĹĹĂĂĂĘĘĘÍÍÍÍÍÍÎÎÎĐĐĐÎÎÎÉÉÉĹĹĹĹĹŵµµĘĘĘ×××ŐŐŐĐĐĐĐĐĐÔÔÔŘŘŘÜÜÜÎÎÎĚĚĚĐĐĐÎÎÎÎÎÎĐĐĐĚĚĚĘĘĘĂĂĂĆĆĆľľľľľľĐĐĐĐĐĐÉÉÉĂĂĂÉÉÉÍÍÍĘĘĘÂÂÂĽĽĽĽĽĽŔŔŔşşş­­­ŻŻŻŔŔŔĹĹĹĹĹĹÉÉÉÂÂÂżżżłłł¦¦¦ĄĄĄ°°°¸¸¸¸¸¸´´´şşşľľľÇÇÇ···±±±©©©łłłŻŻŻ¬¬¬ĄĄĄĄĄĄ¨¨¨¨¨¨¬¬¬­­­¨¨¨łłł···±±±©©©¬¬¬···şşşłłłşşşşşş»»»ĽĽĽżżżĹĹĹĘĘĘĐĐĐŇŇŇŐŐŐŰŰŰŐŐŐŘŘŘŮŮŮĐĐĐŮŮŮŕŕŕćććŰŰŰßßßďďďíííčččîîîćććĂĂĂĘĘĘÎÎÎĐĐĐŐŐŐÎÎÎŘŘŘ×××ŮŮŮÝÝÝŕŕŕââââââŕŕŕßßßÝÝÝÔÔÔŃŃŃÍÍÍÇÇǸ¸¸¸¸¸ÝÝÝŘŘŘŐŐŐĚĚĚÇÇÇÍÍÍŃŃŃĐĐĐÎÎÎÎÎÎÍÍÍŘŘŘ×××ÂÂÂľľľÂ»»»ľľľŔŔŔĹĹĹÉÉÉĚĚĚÍÍÍÍÍÍÍÍÍĐĐĐĆĆĆĂĂĂÍÍÍ×××ŰŰŰ×××ÎÎÎŃŃŃÎÎÎÎÎÎĐĐĐÎÎÎĘĘĘÍÍÍŃŃŃÎÎÎÎÎÎŃŃŃÔÔÔ×××ŘŘŘ×××ŐŐŐ×××ßßßÜÜÜŕŕŕÝÝÝ×××ÝÝÝŰŰŰßßßććććććăăăćććŕŕŕÜÜÜâââßßßÝÝÝÜÜÜÜÜÜÝÝÝßßßâââăăăăăăâââŕŕŕßßßÝÝÝÜÜÜÜÜÜÜÜÜŕŕŕââââââăăăćććčččęęęëëëęęęçççäääęęęćććŃŃŃÍÍÍÝÝÝÜÜÜ´´´ŞŞŞłłł···¸¸¸şşşÇÇÇÂÂÂÂÂÂÂÂÂĘĘĘÍÍÍŃŃŃ»»»żżżÇÇÇÇÇÇÔÔÔŰŰŰŐŐŐŇŇŇÔÔÔĐĐĐĹĹĹĐĐĐ×××ŐŐŐŇŇŇĚĚĚĆĆĆĆĆĆŇŇŇÍÍÍÍÍÍŃŃŃŃŃŃÉÉÉÂÂÂŔŔŔŔŔŔ×××ŮŮŮÎÎÎŃŃŃÔÔÔŇŇŇÔÔÔŐŐŐĚĚĚÍÍÍŇŇŇĐĐĐĐĐĐŇŇŇÎÎÎÎÎÎĹĹĹÉÉÉĹĹĹÇÇÇ×××ŇŇŇĘĘĘŔŔŔÉÉÉÍÍÍÇÇÇĽĽĽ¸¸¸ľľľĂĂĂşşş©©©···ĂĂĂĽĽĽĽĽĽŔŔŔŔŔŔĘĘĘşşşŞŞŞŞŞŞ¸¸¸ÂÂÂÂÂÂĽĽĽżżżĆĆĆĆĆĆ°°°···¸¸¸ŔŔŔĽĽĽĽĽĽµµµ···şşşµµµ´´´°°°ĄĄĄ¨¨¨´´´µµµ©©©©©©µµµ»»»´´´şşş»»»ľľľżżżŔŔŔĆĆĆÍÍÍŇŇŇŇŇŇŐŐŐŰŰŰ×××ŘŘŘ×××ÎÎÎÔÔÔćććâââŰŰŰÝÝÝíííîîîçççňňňëëëÂÂÂÉÉÉŇŇŇŃŃŃŐŐŐŃŃŃŐŐŐÔÔÔŘŘŘÜÜÜßßßŕŕŕßßßÜÜÜŮŮŮŃŃŃÍÍÍÎÎÎĹĹĹşşş»»»ÉÉÉăăăäääŐŐŐĚĚĚĘĘĘĚĚĚÎÎÎÍÍÍÇÇÇÍÍÍĘĘĘŇŇŇŇŇŇĹĹĹÂÂÂĹĹĹľľľľľľŔŔŔĹĹĹÉÉÉĚĚĚÍÍÍÍÍÍĚĚĚĘĘĘĹĹĹÍÍÍŐŐŐŐŐŐŮŮŮŮŮŮĚĚĚÔÔÔÔÔÔ×××ŘŘŘŐŐŐŇŇŇŐŐŐŰŰŰŇŇŇĐĐĐĐĐĐŃŃŃŐŐŐŮŮŮŮŮŮŮŮŮŇŇŇŰŰŰŰŰŰßßßŰŰŰÔÔÔŮŮŮŘŘŘŇŇŇÜÜÜŕŕŕâââćććäääâââçççâââŕŕŕŕŕŕßßßßßßŕŕŕăăăäääçççćććăăăâââŕŕŕŕŕŕŕŕŕâââăăăăăăäääććććććçççççççççóóóíííçççëëëîîîäääŰŰŰßßßĐĐб±±­­­łłł´´´······ŔŔŔŔŔŔĂĂĂÂÂÂÉÉÉÍÍÍ××׼ĽĽşşşÇÇÇĆĆĆĐĐĐÜÜÜŮŮŮŇŇŇĐĐĐÍÍÍĘĘĘÎÎÎŮŮŮßßß×××ÍÍÍÉÉÉĆĆĆÍÍÍŐŐŐŇŇŇÉÉÉÉÉÉÎÎÎÇÇÇ···ŐŐŐŰŰŰÔÔÔÍÍÍÔÔÔŮŮŮŇŇŇĘĘĘĚĚĚĘĘĘŇŇŇŮŮŮ×××××××××ŃŃŃĐĐĐÉÉÉĚĚĚĹĹĹÉÉÉÜÜÜŘŘŘĘĘĘĆĆĆĆĆĆÂÂÂĽĽĽ»»»ľľľľľľĽĽĽŻŻŻ©©©şşşşşşłłł¸¸¸···ľľľŔŔŔľľľ»»»ĽĽĽŔŔŔĂĂĂÂÂÂŔŔŔżżżŔŔŔşşş¬¬¬ĹĹĹĘĘĘĘĘĘÂÂÂľľľľľľĂĂĂĹĹĹĹĹĹÉÉÉĹĹĹ´´´¤¤¤±±±µµµ­­­¨¨¨ŻŻŻµµµµµµ···»»»ŔŔŔĹĹĹĹĹĹĆĆĆĘĘĘÍÍÍÎÎÎŃŃŃŐŐŐŇŇŇŃŃŃÎÎÎÍÍÍŃŃŃßßß×××ŘŘŘÜÜÜëëëďďďćććóóóćććŔŔŔÇÇÇ×××ÔÔÔŐŐŐÔÔÔŇŇŇŐŐŐ×××ŮŮŮÜÜÜÝÝÝÜÜÜŘŘŘŐŐŐĐĐĐĚĚĚĘĘĘŔŔŔĽĽĽÎÎÎŕŕŕăăăÜÜÜĚĚĚÉÉÉÎÎÎĚĚĚÍÍÍŃŃŃÎÎÎÍÍÍĆĆĆÇÇÇĆĆĆľľľľľľÂÂÂľľľľľľŔŔŔĹĹĹÉÉÉĚĚĚĚĚĚĚĚĚĘĘĘÂÂÂÍÍÍÜÜÜŕŕŕ×××ÔÔÔÔÔÔĐĐĐÎÎÎĐĐĐŇŇŇ×××××××××ŐŐŐ×××ŮŮŮ×××ÔÔÔÔÔÔ×××ŘŘŘŘŘŘŐŐŐŰŰŰÝÝÝŘŘŘÝÝÝŕŕŕÜÜÜßßßŘŘŘŐŐŐÜÜÜÜÜÜŕŕŕçççäääßßßŕŕŕââââââââââââŕŕŕâââäääćććęęęčččćććäääääääääćććçççćććççççççççççççćććäääăăăúúúňňňííííííďďďęęęŕŕŕÜÜܵµµ°°°···±±±¬¬¬´´´···¸¸¸ŔŔŔĂĂĂŔŔŔĆĆĆÍÍÍŮŮŮżżż¸¸¸ĂĂĂĂĂĂŃŃŃăăăäääŐŐŐĚĚĚÉÉÉĐĐĐÎÎÎÜÜÜäääŘŘŘĐĐĐÔÔÔŐŐŐĐĐĐÔÔÔŃŃŃÉÉÉĆĆĆĘĘĘĆĆĆĽĽĽăăă×××ŇŇŇŇŇŇÔÔÔŐŐŐŇŇŇÉÉÉĚĚĚÍÍÍÔÔÔŘŘŘÔÔÔÔÔÔŐŐŐĐĐĐÇÇÇÇÇÇĘĘĘĽĽĽżżżŘŘŘ×××ÇÇÇÉÉÉĹĹĹĽĽĽ···»»»ŔŔŔľľľµµµ°°°şşşÂ´´´łłłµµµ­­­µµµłłł¸¸¸ľľľŔŔŔŔŔŔżżżżżżŔŔŔĽĽĽµµµŻŻŻŞŞŞĹĹĹĂĂĂÂÂÂľľľÂÂÂĹĹĹĆĆĆżżż»»»ÂÂÂşşşˇˇˇŞŞŞ±±±···´´´ŞŞŞ¤¤¤¨¨¨ŻŻŻ±±±´´´şşşľľľŔŔŔĂĂĂĆĆĆÉÉÉĚĚĚÎÎÎĐĐĐĐĐĐĚĚĚĘĘĘŃŃŃÔÔÔÔÔÔĐĐĐŘŘŘÜÜÜçççëëëâââëëë××׾ľľÉÉÉŘŘŘ××××××ŐŐŐŇŇŇ×××ŐŐŐŐŐŐ×××ŘŘŘŘŘŘŐŐŐŃŃŃŐŐŐÇÇÇÇÇÇŃŃŃ×××âââčččÝÝÝÔÔÔÉÉÉÍÍÍŃŃŃÉÉÉĆĆĆĚĚĚĚĚĚÉÉÉÂÂÂŔŔŔżżż»»»ĽĽĽżżż»»»żżżÂÂÂĹĹĹÉÉÉĘĘĘĘĘĘÉÉÉÉÉÉĚĚĚŮŮŮŕŕŕÝÝÝŘŘŘŃŃŃŃŃŃŮŮŮÜÜÜŘŘŘŇŇŇŇŇŇ×××ŮŮŮ×××ŇŇŇ×××ŐŐŐŇŇŇŇŇŇÔÔÔÔÔÔŇŇŇŃŃŃ×××ŮŮŮŃŃŃŐŐŐ×××ÔÔÔŮŮŮŐŐŐÜÜÜÝÝÝŰŰŰâââďďďńńńçççäääâââăăăäääăăăââââââäääçççęęęęęęčččççççççččččččęęęęęęęęęęęęčččçççćććăăăâââďďďëëëęęęëëëëëëčččäääŕŕŕşşş´´´şşş°°°©©©łłłµµµ···ľľľÂÂÂľľľÂÂÂÉÉÉŮŮŮÂÂÂľľľŔŔŔĂĂĂŃŃŃäääęęęÝÝÝÔÔÔŐŐŐ×××ÎÎÎŘŘŘäääŕŕŕßßßâââÝÝÝŰŰŰÎÎÎĚĚĚŇŇŇÍÍÍżżżŔŔŔŃŃŃŕŕŕŐŐŐ×××ŘŘŘÎÎÎÍÍÍŇŇŇĐĐĐŃŃŃÎÎÎŃŃŃĐĐĐÉÉÉÍÍÍĐĐĐĘĘĘÇÇÇÇÇÇÍÍÍľľľĽĽĽÔÔÔ×××ÎÎÎĆĆĆÇÇÇÂÂÂşşşşşşľľľĽĽĽµµµ¦¦¦¸¸¸şşşµµµÂÂÂÇÇÇÂÂÂĚĚĚ´´´´´´´´´···şşşĽĽĽĽĽĽĽĽĽ´´´ŻŻŻłłł±±±ÂÂÂľľľĂĂĂĆĆĆşşşľľľŔŔŔ»»»»»»ĂĂĂ»»»ˇˇˇ©©©­­­´´´···°°°¦¦¦©©©łłłµµµµµµ···şşşżżżĆĆĆĚĚĚĐĐĐĘĘĘÍÍÍÍÍÍĐĐĐĘĘĘÉÉÉ××××××ÎÎÎĐĐĐ×××ŮŮŮßßßâââßßßâââĹĹĹŔŔŔĘĘĘŐŐŐ×××ŐŐŐŐŐŐŇŇŇ×××ÔÔÔŇŇŇŇŇŇŐŐŐÔÔÔŃŃŃÍÍÍÉÉɸ¸¸ĽĽĽÝÝÝęęęâââßßßŐŐŐŃŃŃÎÎÎŃŃŃÎÎÎĹĹĹľľľżżżŔŔŔÇÇÇĹĹĹĹĹĹÇÇÇÇÇÇÇÇÇĆĆĆÂÂÂÂÂÂĂĂĂĆĆĆÉÉÉÉÉÉÉÉÉĆĆĆĹĹĹßßßßßßŐŐŐŇŇŇ×××ÔÔÔÔÔÔâââńńńčččÜÜÜŇŇŇÔÔÔŮŮŮŮŮŮŐŐŐÎÎÎÎÎÎĐĐĐĐĐĐŃŃŃŇŇŇÔÔÔŐŐŐÔÔÔÜÜÜŘŘŘŘŘŘŇŇŇÍÍÍŮŮŮÝÝÝââââââŕŕŕçççůůů˙˙˙őőőňňňćććčččęęęçççäääâââăăăćććččččččččččččęęęęęęęęęęęęęęęęęęčččçççćććăăăâââŕŕŕčččäääçççęęęćććââââââßßßŇŇҸ¸¸łłł°°°­­­łłł´´´»»»ĽĽĽŔŔŔľľľĂĂĂÇÇÇŇŇŇżżżŔŔŔĂĂĂÇÇÇÎÎÎŰŰŰäääŕŕŕŕŕŕčččäääŰŰŰŮŮŮâââççççççßßßÔÔÔßßßŃŃŃĐĐĐŐŐŐÍÍÍľľľÇÇÇŕŕŕŮŮŮŮŮŮŮŮŮÔÔÔÍÍÍÎÎÎŇŇŇŇŇŇÍÍÍĚĚĚĐĐĐÎÎÎĘĘĘÎÎÎÎÎÎĆĆĆĘĘĘĹĹĹÎÎÎÇÇÇŔŔŔÍÍÍÔÔÔŮŮŮÇÇÇÍÍÍĘĘĘŔŔŔĽĽĽżżżľľľ······»»»···ŔŔŔÎÎÎĘĘĘÉÉÉÎÎÎĆĆĆżżż¸¸¸µµµ¸¸¸şşş¸¸¸µµµŻŻŻŻŻŻľľľĽĽĽĹĹĹÂÂÂÇÇÇľľľ»»»···»»»żżżżżżľľľłłłˇˇˇ¤¤¤ŞŞŞ´´´¸¸¸µµµłłł´´´şşşŔŔŔĽĽĽ»»»ĽĽĽĂĂĂÉÉÉĚĚĚĚĚĚĆĆĆĘĘĘĚĚĚĐĐĐÇÇÇĆĆĆŐŐŐÔÔÔĘĘĘÔÔÔÔÔÔŇŇŇÔÔÔŰŰŰäääăă㸸¸ĆĆĆÍÍÍĐĐĐŇŇŇŇŇŇŇŇŇÔÔÔŐŐŐŇŇŇŃŃŃŇŇŇÔÔÔŇŇŇÍÍÍÇÇÇĹĹĹÂÂÂĆĆĆßßßâââŇŇŇŇŇŇĐĐĐÇÇÇĚĚĚÉÉÉÂÂÂÂÂÂŔŔŔżżżŔŔŔżżżżżżŔŔŔĂĂĂĆĆĆÉÉÉÇÇÇÇÇÇĹĹĹĆĆĆÇÇÇÉÉÉÉÉÉĆĆĆĂĂĂÂÂÂćććŘŘŘÎÎÎŃŃŃÔÔÔŃŃŃŘŘŘćććëëëčččßßßŇŇŇÍÍÍĐĐĐŇŇŇŃŃŃĐĐĐŇŇŇŇŇŇŇŇŇŇŇŇŐŐŐÜÜÜââââââëëëččččččăăăÝÝÝčččëëëďďďńńńîîîďďďřřřöööďďďďďďďďďńńńňňňîîîçççââââââăăăäääćććčččęęęëëëęęęęęęčččččččččćććăăăŕŕŕßßßÝÝÝÝÝÝíííâââäääęęęăăăÝÝÝÜÜÜŮŮŮÔÔÔµµµ°°°°°°ŻŻŻ±±±´´´ľľľĽĽĽżżżŔŔŔÉÉÉĆĆĆĚĚ̸¸¸ŔŔŔĂĂĂÉÉÉÉÉÉĘĘĘŇŇŇŐŐŐŰŰŰçççęęęçççßßßŰŰŰŕŕŕâââŰŰŰŐŐŐŮŮŮÝÝÝÜÜÜĐĐĐĹĹĹĆĆĆŐŐŐăăăŐŐŐÝÝÝŐŐŐĘĘĘĐĐĐ×××ŇŇŇÎÎÎĂĂĂÇÇÇŃŃŃ×××ŐŐŐ×××ŇŇŇĹĹĹĹĹĹ»»»ÇÇÇÉÉÉŔŔŔŔŔŔÉÉÉŮŮŮĚĚĚĐĐĐÍÍÍĂĂĂÂÂÂĹĹĹżżż´´´Â¸¸¸±±±ĘĘĘÔÔÔÇÇÇĚĚĚÎÎÎ×××ŃŃŃÇÇÇŔŔŔşşş···´´´±±±ŻŻŻ°°°ÂÂÂŔŔŔĆĆĆÂÂÂĽĽĽžžž¦¦¦›››¤¤¤···»»»´´´¬¬¬ˇˇˇ¦¦¦±±±¸¸¸¸¸¸···şşşşşş···ŔŔŔľľľ»»»ľľľĂĂĂĂĂĂżżż»»»ŔŔŔĆĆĆÇÇÇÎÎÎĹĹĹŔŔŔŃŃŃĚĚĚĆĆĆŐŐŐŃŃŃÍÍÍÍÍÍŘŘŘíííęęę±±±ĚĚĚĐĐĐĚĚĚĐĐĐÎÎÎĐĐĐŐŐŐÔÔÔŃŃŃŃŃŃŇŇŇŐŐŐŇŇŇĘĘĘĂĂĂ×××ćććăăăßßßŇŇŇĆĆĆÍÍÍĘĘĘÎÎÎÔÔÔĆĆĆ»»»żżżżżż···µµµ°°°ŻŻŻ­­­ŻŻŻ´´´şşşľľľÂÂÂĆĆĆÇÇÇÉÉÉÉÉÉÇÇÇĆĆĆÂÂÂŔŔŔŕŕŕÎÎÎŃŃŃŮŮŮŃŃŃĚĚĚŮŮŮçççâââččččččßßßŐŐŐÔÔÔ××××××ŮŮŮŰŰŰŰŰŰŘŘŘ×××ŮŮŮăăăëëëăăăçççăăăććććććâââçççäääčččďďďďďďďďďóóóňňňďďďőőőöööřřřřřřňňňčččâââŕŕŕâââăăăäääçççęęęëëëęęęčččççççççćććăăăßßßÝÝÝÜÜÜŰŰŰŰŰŰíííÝÝÝßßßčččćććßßßÝÝÝŰŰŰľľľ°°°łłł°°°ŞŞŞ±±±´´´»»»»»»żżżĂĂĂÍÍÍÇÇÇĆĆƱ±±ľľľÂÂÂÉÉÉĹĹĹżżżĂĂĂĆĆĆĚĚĚ×××ÝÝÝčččâââÔÔÔÔÔÔŮŮŮŕŕŕíííĐĐĐŘŘŘŮŮŮĚĚĚÎÎÎâââăăăŰŰŰćććÝÝÝŐŐŐŃŃŃŇŇŇÔÔÔÎÎÎĘĘĘŃŃŃŇŇŇÔÔÔŐŐŐ×××ŐŐŐŐŐŐÔÔÔÎÎÎĆĆĆÂÂÂĽĽĽÂÂÂĹĹĹĆĆĆßßßŐŐŐĆĆĆĐĐĐľľľŔŔŔ»»»­­­żżżżżżĆĆĆĐĐĐŃŃŃÍÍÍÍÍÍŇŇŇŘŘŘ×××ŐŐŐŃŃŃÇÇǸ¸¸°°°°°°©©©±±±żżżÉÉÉÉÉɵµµ­­­ĄĄĄ¤¤¤žžžˇˇˇ©©©¨¨¨¦¦¦ŻŻŻŻŻŻ¸¸¸´´´°°°˘˘˘ŻŻŻ´´´żżżĽĽĽ»»»µµµłłłşşşĆĆĆĘĘĘÇÇÇÇÇÇ···µµµşşşÇÇÇĘĘĘĂĂĂ×××ŘŘŘĐĐĐÍÍÍŐŐŐŘŘŘÔÔÔ×××ÝÝÝßß߸¸¸ÉÉÉĐĐĐĘĘĘÔÔÔÍÍÍÔÔÔ×××ŃŃŃŃŃŃŐŐŐÎÎÎĹĹĹÉÉÉŐŐŐęęęŘŘŘĚĚĚĘĘĘĆĆĆżżżĂĂĂÎÎÎŔŔŔÇÇÇŔŔŔ»»»°°°­­­ĽĽĽŔŔŔÂÂÂżżżŔŔŔÇÇÇÇÇÇľľľ´´´±±±şşşµµµľľľÉÉÉÉÉÉÇÇÇĆĆĆŔŔŔŰŰŰŃŃŃÍÍÍŃŃŃŘŘŘÝÝÝćććďďďßßßâââăăăßßßŘŘŘŐŐŐŘŘŘÜÜÜŃŃŃăăăíííçççäääëëëîîîęęęčččăăăääääääřřřęęęääääääęęęíííďďďńńńďďďďďďńńńóóóřřřňňňőőőęęęâââăăăÜÜÜăăăćććÜÜÜäääńńńęęęâââäääćććääääääâââßßßÜÜÜŮŮŮŘŘŘ×××čččćććăăăâââââââââßßßÜÜÜŘŘŘĽĽĽŻŻŻ°°°¬¬¬°°°ĽĽĽÂÂÂżżżŔŔŔÉÉÉŇŇŇ×××ÔÔÔŃŃŃŃŃŃşşşşşşżżżĆĆĆÇÇÇĆĆĆÇÇÇĚĚĚŮŮŮďďďćććŘŘŘÝÝÝíííóóóßßßßßßŇŇŇĘĘĘÎÎÎŮŮŮŕŕŕÜÜÜ×××ÝÝÝŮŮŮ×××ŐŐŐŃŃŃĚĚĚĚĚĚÎÎÎÔÔÔŐŐŐ×××ŘŘŘŘŘŘŘŘŘ×××ŐŐŐŇŇŇĘĘĘÇÇÇÂÂÂżżż»»»»»»ŇŇŇŐŐŐĆĆĆĐĐĐÂÂÂľľľ¸¸¸»»»şşş¸¸¸ŔŔŔÍÍÍŇŇŇŐŐŐŇŇŇÎÎÎĘĘĘĚĚĚÍÍÍŇŇŇŐŐŐÎÎÎľľľ±±±¬¬¬´´´»»»ĂĂĂÉÉÉÉÉÉĂĂĂ»»»´´´şşş´´´¨¨¨˘˘˘¦¦¦ĄĄĄ¨¨¨łłłłłł»»»¸¸¸łłł©©©­­­±±±···ŔŔŔŔŔŔĽĽĽµµµ···ľľľĹĹĹÇÇÇÇÇÇĹĹĹĂĂĂşşşĽĽĽĹĹĹĹĹĹŐŐŐÉÉÉĚĚĚÔÔÔÜÜÜŘŘŘŃŃŃ×××ääääääľľľľľľŔŔŔÂÂÂĚĚĚÇÇÇÎÎÎŃŃŃÍÍÍĚĚĚĚĚĚÉÉÉĘĘĘ×××çççŕŕŕŐŐŐÎÎÎÎÎÎÎÎÎĘĘĘĚĚĚŃŃѵµµÂÂÂĽĽĽµµµµµµĽĽĽÉÉÉĂĂĂĂĂĂÂÂÂĂĂĂÉÉÉĘĘĘĆĆĆĂĂĂÂÂÂżżż´´´şşşÉÉÉĘĘĘĹĹĹĂĂĂÂÂÂÝÝÝŐŐŐŃŃŃ×××ŕŕŕăăăâââŕŕŕ×××ŰŰŰŕŕŕćććčččęęęęęęęęęÝÝÝćććčččääääääçççäääÝÝÝŰŰŰŰŰŰćććäääíííčččîîîçççďďďíííčččääääääçççíííńńńňňňńńńúúúőőőńńńďďďćććčččëëëäääççççççßßßÝÝÝââââââŕŕŕßßßÜÜÜŮŮŮŘŘŘ×××××××××ŕŕŕŕŕŕâââăăăäääăăăâââŕŕŕćććÍÍÍşşş´´´±±±´´´şşşĽĽĽÂÂÂÂÂÂĹĹĹĚĚĚĐĐĐŃŃŃŐŐŐÜÜÜŕŕŕâââçççëëëäää×××ÍÍÍĘĘĘÂÂÂÝÝÝäääăăăćććÝÝÝÔÔÔĐĐĐÜÜÜĘĘĘĆĆĆÜÜÜęęęăăăÝÝÝÝÝÝÔÔÔŐŐŐ×××ŐŐŐÍÍÍĹĹĹĘĘĘÔÔÔ×××ŘŘŘŮŮŮŮŮŮŮŮŮŮŮŮ××××××ÎÎÎÇÇÇĘĘĘĆĆĆżżżµµµ···ŃŃŃŘŘŘĆĆĆĚĚĚŔŔŔľľľ´´´ĽĽĽÂ¸¸¸ÇÇÇŇŇŇÔÔÔÔÔÔŐŐŐÎÎÎĹĹĹÂÂÂĹĹĹÍÍÍŐŐŐŇŇŇĆĆƸ¸¸łłłżżżŔŔŔĂĂĂĹĹĹĂĂĂŔŔŔĽĽĽşşşÂÂÂľľľ±±±¨¨¨¨¨¨¤¤¤¦¦¦°°°µµµµµµµµµŞŞŞ©©©¨¨¨°°°łłłżżżżżżĽĽĽ···´´´¸¸¸»»»»»»żżżĆĆĆĆĆĆ»»»żżżÇÇÇĽĽĽ¸¸¸ŔŔŔĆĆĆŃŃŃŘŘŘÔÔÔĐĐĐŘŘŘçççóóóŐŐŐľľľ»»»ŔŔŔĂĂĂÂÂÂĆĆĆĚĚĚÇÇÇĂĂĂĂĂĂÉÉÉŇŇŇÜÜÜăăăÔÔÔÎÎÎÇÇÇÂÂÂĽĽĽ¸¸¸´´´±±±ĂĂĂĽĽĽłłłĽĽĽĂĂĂżżżľľľµµµ»»»ĽĽĽľľľľľľżżżĂĂĂÇÇÇÉÉÉĆĆĆ´´´µµµĆĆĆÉÉÉĂĂĂĂĂĂĂĂĂ×××ŐŐŐŇŇŇŇŇŇŮŮŮăăăćććäääÜÜÜÜÜÜÝÝÝăăăçççęęęčččćććíííčččćććçççęęęčččâââŰŰŰłłłĽĽĽŇŇŇ×××ŮŮŮâââńńńčččîîîíííëëëëëëíííďďďďďďńńńîîîďďďůůůůůůřřřöööďďďńńńóóóóóóóóóëëëŕŕŕŕŕŕäääăăăčččćććâââÜÜÜŮŮŮ×××××××××ććććććäääâââŕŕŕßßßßßßŕŕŕŕŕŕŇŇŇ»»»ŻŻŻłłł¸¸¸ľľľĹĹĹĂĂĂĹĹĹĘĘĘĐĐĐĐĐĐÍÍÍÎÎÎÔÔÔŐŐŐŐŐŐŘŘŘÜÜÜÜÜÜŘŘŘŮŮŮÝÝÝĘĘĘŃŃŃâââëëëććć×××ĐĐĐÜÜÜÎÎÎŇŇŇŰŰŰíííîîîâââßßßÝÝÝĐĐĐŐŐŐ×××ŃŃŃÉÉÉÉÉÉĐĐĐ×××ŘŘŘŘŘŘŮŮŮŮŮŮŮŮŮŘŘŘ×××ŐŐŐÍÍÍÇÇÇÍÍÍÇÇÇĽĽĽ´´´şşşÔÔÔŰŰŰĆĆĆĹĹĹ»»»ľľľ¸¸¸żżżĽĽĽĆĆĆÎÎÎÔÔÔŇŇŇŃŃŃĐĐĐĚĚĚĆĆĆĹĹĹĂĂĂÇÇÇĐĐĐŇŇŇĚĚĚĹĹĹÂÂÂÇÇÇÇÇÇĆĆĆĹĹĹĂĂĂÂÂÂŔŔŔżżżľľľÂÂÂľľľ···´´´­­­¨¨¨¬¬¬ĽĽĽµµµ´´´ĄĄĄ¬¬¬ŞŞŞşşşľľľľľľľľľ»»»şşşşşşşşş¸¸¸µµµşşşŔŔŔĽĽĽ´´´ĽĽĽÉÉÉĹĹĹÂÂÂĽĽĽ»»»ľľľÂÂÂĂĂĂĹĹĹÎÎÎŮŮŮäääŘŘŘ»»»¸¸¸żżż¸¸¸şşşĽĽĽµµµµµµ¸¸¸ŔŔŔŇŇŇâââäääÝÝÝĚĚĚĚĚĚÇÇÇÂÂÂÂÂÂĆĆĆĹĹĹŔŔŔşşş´´´°°°ÂÂÂĆĆĆşşşşşş»»»¸¸¸ĽĽĽĽĽĽ¸¸¸···»»»ŔŔŔĂĂĂÉÉɸ¸¸µµµżżżĂĂĂĹĹĹĆĆĆÂÂÂżżżÉÉÉÎÎÎĘĘĘÉÉÉĐĐĐŘŘŘÜÜÜŕŕŕÜÜÜ×××ÔÔÔÔÔÔ×××ŰŰŰÜÜÜëëëăăăŕŕŕćććęęęçççâââŕŕŕ°°°´´´ĽĽĽĽĽĽżżżĐĐĐçççîîîäääćććčččîîîňňňóóóńńńîîîóóóňňňóóóňňňňňňöööůůů˙˙˙óóóöööůůůóóóčččââââââäääßßßÝÝÝŰŰŰŰŰŰÜÜÜŕŕŕăăăćććîîîëëëçççŕŕŕÜÜÜÝÝÝâââćććâââÝÝÝĆĆĆ°°°­­­ŻŻŻłłłżżżĂĂĂĆĆĆĚĚĚŃŃŃÎÎÎĘĘĘĚĚĚŃŃŃŮŮŮÔÔÔĐĐĐĐĐĐĐĐĐŇŇŇÜÜÜćććŰŰŰŔŔŔĐĐĐŰŰŰŃŃŃŇŇŇŘŘŘŕŕŕÉÉÉćććîîîëëëŕŕŕŮŮŮŰŰŰÍÍÍŃŃŃŘŘŘŐŐŐĘĘĘÉÉÉÔÔÔŮŮŮŐŐŐ×××ŘŘŘŘŘŘŘŘŘŘŘŘŐŐŐÔÔÔŇŇŇÔÔÔÍÍÍŃŃŃÇÇǸ¸¸´´´ĽĽĽÔÔÔÔÔÔÉÉÉĆĆƸ¸¸»»»şşşĂĂø¸¸ŇŇŇŇŇŇÔÔÔ×××ŇŇŇÉÉÉĂĂĂĹĹĹÇÇÇĆĆĆÉÉÉĐĐĐÔÔÔĐĐĐÍÍÍĚĚĚĚĚĚĘĘĘÉÉÉÇÇÇĆĆĆĆĆĆĹĹĹĹĹĹżżżÇÇÇÉÉÉĹĹĹ···¬¬¬ŞŞŞ¸¸¸°°°ŻŻŻ¤¤¤ŞŞŞ¨¨¨µµµşşşľľľľľľżżżľľľşşşşşşľľľÂÂÂĽĽĽÇÇÇĹĹĹľľľ»»»¸¸¸ĽĽĽĹĹĹŔŔŔżżżżżżŔŔŔĂĂĂĆĆĆÍÍÍŐŐŐäääëëëŰŰŰÝÝÝćććÝÝÝâââäääçççíííîîîëëëëëëęęęŕŕŕŇŇŇÎÎÎÍÍÍĂĂõµµ°°°łłł±±±ŞŞŞ­­­şşş»»»ĽĽĽµµµ±±±ŔŔŔĆĆĆĹĹĹÇÇÇÇÇÇÂÂÂĽĽĽşşş»»»żżżĆĆĆżżżĽĽĽ¸¸¸şşşĆĆĆĘĘĘżżż»»»ĚĚĚŘŘŘŐŐŐÎÎÎÍÍÍÎÎÎÍÍÍÔÔÔŇŇŇĐĐĐĚĚĚÉÉÉÎÎÎŮŮŮăăăŕŕŕÜÜÜÝÝÝääääääßßßßßßäääßßßÔÔÔľľľłłł±±±ľľľÔÔÔîîîďďďîîîîîîńńńőőőůůůůůůůůůćććčččëëëďďďňňňńńńďďďíííďďďîîîďďďńńńęęęÝÝÝÝÝÝçççććććććäääćććčččíííńńńóóóččččččçççäääăăăăăăčččíííâââçççŮŮŮĂĂĂ···­­­­­­şşşÂÂÂÂÂÂĹĹĹÇÇÇÉÉÉĘĘĘÔÔÔÝÝÝăăăŕŕŕßßßÝÝÝŮŮŮŐŐŐ×××ŰŰŰćććÂÂÂĹĹĹÍÍÍÎÎÎŰŰŰŮŮŮŐŐŐĂĂĂęęęëëëÝÝÝÔÔÔŘŘŘŕŕŕĆĆĆ×××ŘŘŘŃŃŃÉÉÉÎÎÎŰŰŰÝÝÝŐŐŐ×××ŘŘŘŘŘŘŘŘŘ×××ÔÔÔŃŃŃĐĐĐŃŃŃĚĚĚÎÎη··ľľľÉÉÉŘŘŘÉÉÉĘĘĘĚĚĚĽĽĽ¸¸¸µµµĘĘĘŔŔŔ×××ÔÔÔ×××ŮŮŮÔÔÔĆĆĆżżżŔŔŔÇÇÇĆĆĆĚĚĚŇŇŇÔÔÔĐĐĐĘĘĘĘĘĘŔŔŔŔŔŔżżżżżżżżżŔŔŔÂÂÂĂĂĂŔŔŔÉÉÉÇÇÇÂÂÂżżż¸¸¸­­­ŞŞŞľľľ»»»ĽĽĽşşş»»»µµµşşşĽĽĽµµµ¸¸¸»»»···ŻŻŻ¬¬¬¸¸¸ĆĆĆşşşÂÂÂżżżŔŔŔľľľ­­­­­­łłł»»»żżżĹĹĹĆĆĆĆĆĆĆĆĆĚĚĚŇŇŇŐŐŐäääßßßäääęęęăăăććććććŕŕŕęęęďďďçççÝÝÝŘŘŘŇŇŇÎÎÎÇÇÇĆĆĆľľľµµµ´´´şşş»»»¸¸¸şşşĽĽĽµµµ······¸¸¸ÇÇÇĚĚĚĐĐĐÎÎÎÍÍÍĘĘʸ¸¸µµµ»»»ÂÂÂĂĂĂ···łłłĂĂĂĚĚĚżżżĂĂĂĘĘĘĐĐĐŃŃŃĐĐĐŃŃŃŃŃŃÎÎÎÉÉÉÍÍÍŃŃŃŃŃŃÎÎÎŇŇŇÜÜÜäääßßßßßßäääčččçççâââăăăčččńńńčččÍÍÍŔŔŔ······ľľľŘŘŘëëëíííďďďńńńňňňňňňďďďîîîöööőőőíííîîîďďďńńńůůůřřřňňňîîîëëëďďďíííâââäääőőőőőőóóóńńńîîîíííííííííîîîçççčččëëëëëëęęęçççćććäääăăăçççäää×××ĆĆĆ···´´´ĽĽĽÂÂÂÂÂÂĹĹĹÉÉÉĘĘĘĘĘĘĐĐĐŘŘŘŐŐŐŐŐŐŮŮŮÝÝÝÝÝÝŘŘŘŘŘŘŰŰŰęęę×××ĹĹĹĂĂĂÔÔÔßßßÔÔÔÍÍÍľľľăăăäääßßßŮŮŮÜÜÜćććÎÎÎŘŘŘŇŇŇÎÎÎĐĐĐŐŐŐŮŮŮŮŮŮŘŘŘŘŘŘŮŮŮŮŮŮŘŘŘ×××ÔÔÔŃŃŃĐĐĐĚĚĚĆĆĆĘĘĘĽĽĽµµµÇÇÇÔÔÔŮŮŮÇÇÇÇÇÇÇÇÇŔŔŔżżż¸¸¸ŃŃŃÎÎÎŘŘŘŘŘŘ×××ÔÔÔÍÍÍĆĆĆÂÂÂÂÂÂĆĆĆĆĆĆĘĘĘĐĐĐÎÎÎĆĆĆÂÂÂĂĂø¸¸¸¸¸¸¸¸¸¸¸»»»żżżÂÂÂĹĹĹŔŔŔÇÇÇĹĹĹżżżÂÂÂŔŔŔ¸¸¸´´´łłł´´´µµµ»»»µµµ´´´±±±···´´´łłł´´´µµµłłłŻŻŻ°°°µµµ°°°···ŻŻŻµµµ»»»´´´şşşľľľ­­­­­­°°°´´´şşşżżżĂĂĂĹĹĹÎÎÎŘŘŘ×××ŘŘŘÜÜÜŰŰŰŰŰŰŐŐŐÔÔÔŮŮŮÝÝÝÜÜÜŘŘŘŐŐŐÔÔÔŇŇŇľľľĽĽĽşşşşşş»»»żżżżżżľľľşşş···±±±żżżĘĘĘĚĚĚÔÔÔŇŇŇŃŃŃĘĘĘÉÉÉĚĚĚĹĹŵµµłłł»»»ŔŔŔĹĹĹĹĹĹşşş±±±ĽĽĽÉÉÉĂĂĂŔŔŔľľľ»»»ĽĽĽľľľÂÂÂÉÉÉŃŃŃÉÉÉĚĚĚÎÎÎĐĐĐĐĐĐĐĐĐÔÔÔ×××ŮŮŮÜÜÜâââççççççććććććčččßßßäääŰŰŰŇŇŇşşşµµµ´´´ŔŔŔäääčččíííďďďďďďëëëčččćććčččŕŕŕÇÇÇŔŔŔĂĂĂĚĚĚâââçççńńńňňňďďďńńńóóóďďďďďďüüüíííëëëëëëęęęčččęęęęęęęęęëëëëëëëëëęęęčččćććâââÝÝÝîîîâââŮŮŮŃŃŃŔŔŔ´´´µµµ¸¸¸ĂĂĂĂĂĂÇÇÇÎÎÎĐĐĐĘĘĘÉÉÉĘĘĘŐŐŐŐŐŐŮŮŮÝÝÝÝÝÝŰŰŰŰŰŰßßßŕŕŕÝÝÝÇÇÇĂĂĂŇŇŇŇŇŇĚĚĚÇÇÇĽĽĽâââčččďďďćććŮŮŮâââŃŃŃŘŘŘÍÍÍĚĚĚŘŘŘÜÜÜŐŐŐŇŇŇŮŮŮŮŮŮŰŰŰŰŰŰŮŮŮŘŘŘÔÔÔŃŃŃĐĐĐÎÎÎĘĘĘÍÍÍ»»»´´´ÉÉÉŃŃŃĐĐĐÎÎÎĂĂĂľľľŔŔŔÇÇÇżżżŘŘŘŐŐŐŰŰŰÜÜÜ×××ÉÉÉĂĂĂĆĆĆÉÉÉÇÇÇÇÇÇĆĆĆÇÇÇÉÉÉĹĹĹľľľĽĽĽŔŔŔľľľĽĽĽĽĽĽľľľŔŔŔĆĆĆÍÍÍĐĐĐĹĹĹÍÍÍÍÍÍĘĘĘŃŃŃŇŇŇĚĚĚÇÇÇĹĹĹÇÇÇĹĹĹĐĐĐÇÇÇĚĚĚĘĘĘŐŐŐżżżµµµµµµŔŔŔĘĘʱ±±ĄĄĄŻŻŻĹĹĹĆĆĆÉÉÉĹĹĹ···»»»ľľľµµµ¬¬¬ĄĄĄŞŞŞĽĽĽĘĘĘÍÍÍÇÇÇÔÔÔŐŐŐÔÔÔÔÔÔŮŮŮââââââŮŮŮßßßŘŘŘÔÔÔ×××ŮŮŮŐŐŐĘĘĘŔŔŔĂĂĂÂÂÂŔŔŔŔŔŔżżżşşş´´´°°°°°°ÇÇÇĐĐĐŇŇŇĐĐĐÎÎÎŇŇŇÉÉÉŇŇŇÇÇÇĆĆĆÎÎÎÉÉɸ¸¸···ÂÂÂÂÂÂĂĂĂĹĹĹľľľ±±±···ĹĹĹÉÉÉĹĹĹĹĹĹĆĆĆĆĆĆżżż»»»ĹĹĹŇŇŇÉÉÉĆĆĆĹĹĹĆĆĆÉÉÉĘĘĘĘĘĘĘĘĘĘĘĘÎÎÎÔÔÔŮŮŮßßßăăăâââßßßÜÜÜććććććŮŮŮłłłłłł¸¸¸ľľľĽĽĽĽĽĽĽĽĽşşşşşşĽĽĽÂÂÂĆĆĆĂĂĂÉÉÉÂÂÂĘĘĘÍÍÍÇÇÇĘĘĘÂÂÂäääďďďńńńńńńöööőőőďďďňňň˙˙˙˙˙˙úúúřřřőőőňňňńńńďďďëëëçççăăăâââăăăććććććććććććĘĘĘĽĽĽşşşłłłłłłżżżĹĹĹĆĆĆĂĂĂĂĂĂÇÇÇĘĘĘĘĘĘÍÍÍŃŃŃŇŇŇŐŐŐÜÜÜăăăăăăÝÝÝŰŰŰÜÜÜŘŘŘŕŕŕŰŰŰßßßßßßŐŐŐÔÔÔĚĚĚĽĽĽŔŔŔćććęęęŮŮŮääääää×××ŰŰŰÎÎÎĐĐĐŘŘŘŘŘŘŰŰŰÝÝÝŮŮŮŐŐŐŘŘŘŮŮŮŰŰŰŘŘŘŇŇŇÎÎÎĚĚĚŃŃŃÎÎÎżżżşşşÎÎÎŰŰŰÔÔÔÎÎÎÉÉÉÂÂÂÎÎÎĘĘĘĹĹĹŃŃŃ×××ÝÝÝäääŰŰŰŃŃŃÍÍÍÉÉÉĹĹĹĆĆĆĚĚĚĘĘĘĘĘĘĘĘĘÇÇÇĹĹĹÂÂÂľľľĽĽĽÂÂÂżżżľľľĂĂĂÍÍÍŃŃŃĐĐĐĘĘĘÍÍÍÂÂÂÂÂÂĚĚĚĐĐĐŇŇŇÔÔÔÎÎÎÎÎÎÍÍÍŃŃŃ×××ŘŘŘÔÔÔŇŇŇÔÔÔĐĐĐĐĐĐÎÎÎĚĚĚĘĘĘÉÉÉÇÇÇĆĆĆĂĂĂĹĹĹÉÉÉĚĚĚĘĘĘĂĂĂ···ŻŻŻ···ŔŔŔÇÇÇŔŔŔ···µµµŔŔŔĚĚĚĹĹĹŔŔŔĹĹĹĆĆĆÜÜÜĐĐĐĘĘĘĹĹĹĐĐĐÍÍÍĘĘĘĘĘĘĚĚĚĚĚĚĘĘĘÉÉÉĂĂĂľľľŔŔŔşşşşşşłłł¬¬¬ĹĹĹÍÍÍÍÍÍĐĐĐŃŃŃŇŇŇŇŇŇŇŇŇŃŃŃÇÇÇÉÉÉÎÎÎÉÉɸ¸¸łłłĽĽĽÂÂÂŔŔŔÉÉÉÇÇÇĂĂĂľľľ°°°ŻŻŻľľľÉÉÉÇÇÇÇÇÇĹĹĹżżż»»»şşş»»»ŐŐŐĐĐĐĘĘĘÇÇÇĂĂĂÂÂÂÇÇÇÎÎÎĘĘĘĐĐĐŇŇŇŇŇŇŮŮŮăăăäääŕŕŕâââŇŇŇŕŕŕÔÔÔ···µµµşşşĽĽĽľľľÂÂÂĆĆĆĹĹĹÂÂÂŔŔŔĂĂĂĆĆĆĆĆĆÉÉÉÎÎÎÎÎÎĚĚĚÇÇÇĆĆĆĆĆĆÇÇÇÜÜÜíííďďďëëëíííńńńóóóöööőőőňňňňňňóóóöööúúú˙˙˙öööďďďčččçççëëëëëëäääßßß´´´¸¸¸ľľľŔŔŔŔŔŔżżżľľľżżżĹĹĹĹĹĹÇÇÇĚĚĚĐĐĐŃŃŃŃŃŃĐĐĐŃŃŃŐŐŐŰŰŰŕŕŕâââŕŕŕÝÝÝŰŰŰŰŰŰŘŘŘŰŰŰŕŕŕŕŕŕŘŘŘŃŃŃĐĐĐĂĂĂŇŇŇďďďëëëßßßäääßßß×××ÜÜÜŇŇŇÔÔÔÜÜÜŰŰŰŰŰŰŰŰŰŐŐŐŰŰŰŮŮŮŮŮŮ×××ÔÔÔŇŇŇŃŃŃĐĐĐÍÍÍÉÉÉĽĽĽľľľĐĐĐŮŮŮÔÔÔĐĐĐŇŇŇĆĆĆÍÍÍÇÇÇĹĹĹŇŇŇ×××ÜÜÜŮŮŮŇŇŇÎÎÎÎÎÎÍÍÍÉÉÉÇÇÇĘĘĘĚĚĚĘĘĘÉÉÉÇÇÇĹĹĹĂĂĂŔŔŔżżżĹĹĹÂÂÂĂĂĂÇÇÇĐĐĐÔÔÔŇŇŇĐĐĐŇŇŇÉÉÉÇÇÇÍÍÍĚĚĚÎÎÎÔÔÔÔÔÔŇŇŇĚĚĚĹĹĹĹĹĹĹĹĹÇÇÇĐĐĐŘŘŘ××××××ŐŐŐŇŇŇŃŃŃĐĐĐÎÎÎÍÍÍĹĹĹÇÇÇĚĚĚŃŃŃÔÔÔĐĐĐÉÉÉĂĂĂ»»»ĽĽĽżżżĂĂĂľľľµµµµµµĽĽĽÎÎÎĚĚĚÍÍÍÉÉÉŐŐŐĚĚĚĐĐĐÔÔÔÎÎÎÎÎÎÍÍÍÍÍÍĚĚĚĘĘĘĆĆĆĂĂĂ»»»´´´»»»żżżÉÉÉĚĚĚÉÉÉŮŮŮĐĐĐŇŇŇŐŐŐŘŘŘŘŘŘ×××ŐŐŐŇŇŇŐŐŐÎÎÎĚĚĚĂĂĂ···¸¸¸żżżĽĽĽĂĂĂĆĆĆĆĆĆĆĆĆĹĹĹĽĽĽ···¸¸¸ÂÂÂĆĆĆĹĹĹŔŔŔżżżÂÂÂŔŔŔ»»»żżżżżżĂĂĂÉÉÉÉÉÉĆĆĆÇÇÇÍÍÍŇŇŇŃŃŃĐĐĐÍÍÍÍÍÍŃŃŃŇŇŇŇŇŇÜÜÜŘŘŘäääŕŕŕĆĆƸ¸¸şşşľľľŔŔŔĹĹĹÉÉÉĚĚĚĚĚĚÉÉÉĂĂĂŔŔŔÇÇÇĚĚĚÎÎÎĐĐĐÍÍÍĘĘĘÇÇÇÇÇÇÂÂÂÔÔÔăăăççççççęęęďďďňňňóóóńńńîîîîîîîîîńńńňňňňňňëëëÜÜÜÇÇÇşşş···şşşľľľżżżŔŔŔĂĂĂÇÇÇÇÇÇĆĆĆĂĂĂĂĂĂĂĂĂżżżÂÂÂĆĆĆĘĘĘÎÎÎĐĐĐÎÎÎÎÎÎŇŇŇ×××ŰŰŰßßßŕŕŕßßßÜÜÜŮŮŮŰŰŰŘŘŘŮŮŮÝÝÝÝÝÝŐŐŐÎÎÎÍÍÍĂĂĂŕŕŕňňňçççăăăâââ×××ŮŮŮŮŮŮÔÔÔŐŐŐŰŰŰŮŮŮ×××ÔÔÔÎÎÎŘŘŘŘŘŘŘŘŘ×××ŐŐŐŇŇŇŃŃŃÎÎÎÉÉÉÂÂÂĽĽĽĹĹĹÔÔÔŘŘŘŇŇŇŃŃŃŐŐŐÉÉÉÉÉÉĆĆĆÇÇÇŇŇŇŘŘŘÝÝÝĐĐĐÍÍÍĚĚĚÎÎÎĐĐĐÍÍÍĚĚĚĚĚĚĚĚĚĘĘĘÉÉÉÇÇÇĆĆĆĹĹĹĂĂĂĂĂĂĹĹĹĹĹĹĆĆĆĘĘĘÎÎÎŇŇŇŃŃŃĐĐĐĐĐĐĘĘĘĐĐĐÔÔÔÎÎÎÍÍÍŐŐŐŘŘŘĘĘĘĂĂĂżżżŔŔŔŔŔŔŔŔŔĹĹĹĘĘĘÇÇÇÇÇÇĆĆĆĂĂĂÂÂÂżżżľľľľľľ»»»ľľľĂĂĂÉÉÉÎÎÎŃŃŃŃŃŃĐĐĐ»»»ĽĽĽĘĘĘĐĐĐĘĘĘÉÉÉĐĐĐŻŻŻ´´´şşş¸¸¸ÂÂÂľľľÉÉÉ××××××ŇŇŇĚĚĚĹĹĹżżżľľľżżżÂÂÂÉÉÉĽĽĽĂĂĂĚĚĚŃŃŃŐŐŐŃŃŃŇŇŇŃŃŃŇŇŇ×××ŮŮŮŮŮŮ×××ÔÔÔŃŃŃŇŇŇÍÍÍÇÇÇ»»»łłł»»»ĂĂĂżżżÂÂÂżżżżżżĂĂĂĆĆĆÇÇÇŔŔŔ´´´»»»ĹĹĹÇÇÇŔŔŔľľľĂĂĂĂĂĂĽĽĽşşşĽĽĽÂÂÂĘĘĘĚĚĚÇÇÇÇÇÇĚĚĚÉÉÉÇÇÇÉÉÉĘĘĘĚĚĚĘĘĘĚĚĚÎÎÎŐŐŐÜÜÜâââäääÎÎÎłłłłłł»»»ŔŔŔĂĂĂÉÉÉÎÎÎŇŇŇŃŃŃĚĚĚĆĆĆĘĘĘÍÍÍŃŃŃŃŃŃĐĐĐÍÍÍĘĘĘÉÉÉżżżÇÇÇÍÍÍĘĘĘĹĹĹÂÂÂÂÂÂÂÂÂŰŰŰŘŘŘŇŇŇĐĐĐÎÎÎĚĚĚÇÇÇĂĂĂĚĚĚÉÉÉĆĆĆĹĹĹĆĆĆĆĆĆĹĹĹĂĂĂÍÍÍÎÎÎÎÎÎÍÍÍĘĘĘÇÇÇĆĆĆĆĆĆżżżÂÂÂÇÇÇĚĚĚÎÎÎĐĐĐĐĐĐĐĐĐŐŐŐŘŘŘÜÜÜßßßßßßÝÝÝŮŮŮ×××ŮŮŮ×××ŘŘŘŰŰŰŮŮŮŇŇŇĚĚĚÉÉÉ»»»ăăăëëëÜÜÜâââÜÜÜĐĐĐŰŰŰŐŐŐŃŃŃŃŃŃÔÔÔŇŇŇŃŃŃÎÎÎĘĘĘÎÎÎŃŃŃÔÔÔŘŘŘŘŘŘÔÔÔÎÎÎÉÉÉÇÇÇżżżŔŔŔÎÎÎŮŮŮŐŐŐĐĐĐŇŇŇĐĐĐÇÇÇĆĆĆĆĆĆÇÇÇÎÎÎ×××ßßßŃŃŃÎÎÎÍÍÍÍÍÍÎÎÎÎÎÎÍÍÍÍÍÍÍÍÍĚĚĚÉÉÉÇÇÇĆĆĆĆĆĆĆĆĆÇÇÇĹĹĹĆĆĆÇÇÇÉÉÉĘĘĘĘĘĘĘĘĘĘĘĘĹĹĹÇÇÇÔÔÔŰŰŰŃŃŃÍÍÍŇŇŇŐŐŐĆĆĆÂÂÂŔŔŔĂĂĂĂĂĂżżżĽĽĽľľľżżżżżżľľľ»»»şşş¸¸¸···µµµ±±±´´´···ĽĽĽĂĂĂÉÉÉÍÍÍĐĐĐĐĐĐĆĆĆŔŔŔÂÂÂĹĹĹĂĂĂĂĂĂĆĆĆĆĆĆĚĚĚÎÎÎĚĚĚÉÉÉĽĽĽ¸¸¸ÂÂÂĂĂĂÂÂÂŔŔŔľľľľľľÂÂÂÉÉÉĐĐĐĹĹĹĽĽĽĆĆĆŃŃŃŇŇŇŘŘŘŮŮŮŇŇŇ××××××ŘŘŘŮŮŮŮŮŮŘŘŘ×××ŐŐŐĘĘĘÍÍÍĚĚĚĽĽĽ­­­´´´ľľľşşşŔŔŔşşşşşşşşş¸¸¸ľľľ»»»©©©µµµŔŔŔÉÉÉĹĹĹżżżżżżŔŔŔżżżşşş¸¸¸¸¸¸şşş···´´´µµµşşşĽĽĽľľľĆĆĆĐĐĐŇŇŇÎÎÎĚĚĚÎÎÎÎÎÎŰŰŰŰŰŰâââŇŇұ±±łłłŔŔŔĂĂĂĆĆĆÉÉÉÍÍÍÎÎÎĐĐĐÎÎÎÎÎÎĚĚĚÎÎÎŃŃŃÔÔÔŇŇŇĐĐĐÍÍÍĚĚĚÍÍÍÎÎÎĐĐĐÍÍÍÉÉÉĆĆĆĆĆĆĹĹĹÎÎÎÍÍÍÍÍÍĐĐĐŇŇŇÔÔÔŃŃŃÍÍÍĚĚĚÍÍÍŃŃŃÔÔÔÔÔÔŇŇŇŃŃŃĐĐĐŃŃŃŃŃŃĐĐĐÎÎÎĚĚĚÉÉÉÇÇÇÇÇÇĆĆĆÉÉÉĚĚĚÎÎÎĐĐĐŃŃŃŇŇŇÔÔÔŘŘŘŮŮŮÜÜÜßßßÝÝÝÜÜÜŘŘŘŐŐŐ×××ŐŐŐ×××××××××ŃŃŃĚĚĚÇÇÇżżżäääăăăŘŘŘŕŕŕ×××ÍÍÍŰŰŰÔÔÔÔÔÔŃŃŃĐĐĐŃŃŃŇŇŇĐĐĐÎÎÎĘĘĘĚĚĚÎÎÎŇŇŇÔÔÔŇŇŇÍÍÍÇÇÇÇÇÇŔŔŔĆĆĆ×××ÜÜÜŐŐŐĐĐĐŃŃŃÉÉÉÉÉÉÇÇÇÉÉÉÇÇÇĹĹĹÍÍÍ×××ŐŐŐŐŐŐŇŇŇÎÎÎĚĚĚÍÍÍÎÎÎÎÎÎÍÍÍĚĚĚĘĘĘÇÇÇÇÇÇÇÇÇÇÇÇÉÉÉÇÇÇÉÉÉĘĘĘÉÉÉÇÇÇĆĆĆĹĹĹĹĹĹĂĂĂÇÇÇÔÔÔŮŮŮÍÍÍĆĆĆĚĚĚĐĐĐŇŇŇÉÉÉÂÂÂżżżżżżľľľľľľŔŔŔľľľľľľĽĽĽ»»»şşş¸¸¸······µµµ···¸¸¸»»»żżżĹĹĹĘĘĘÎÎÎŇŇŇÔÔÔÍÍÍ»»»ľľľżżżĽĽĽĽĽĽŔŔŔŔŔŔĆĆĆÉÉÉŔŔŔ¸¸¸ĽĽĽ···ľľľĹĹĹĘĘĘĘĘĘÉÉÉÇÇÇÇÇÇşşşľľľĚĚĚŐŐŐŇŇŇŘŘŘŕŕŕŮŮŮÜÜÜŰŰŰŘŘŘ××××××ŘŘŘŮŮŮŰŰŰŇŇŇ××××××ĆĆƵµµµµµµµµŞŞŞ···´´´······µµµÂÂÂÉÉÉŔŔŔµµµµµµĽĽĽĹĹĹĆĆĆÂÂÂżżżÂÂÂÇÇÇĂĂĂŔŔŔŔŔŔĽĽĽ¸¸¸»»»ŔŔŔżżżżżżĆĆĆĐĐĐŃŃŃĚĚĚÇÇÇÉÉÉÉÉÉ×××ŐŐŐŕŕŕŮŮٸ¸¸µµµÂÂÂÂÂÂĆĆĆĚĚĚÍÍÍĘĘĘÉÉÉĘĘĘÎÎÎĚĚĚÎÎÎŃŃŃÔÔÔÔÔÔŇŇŇĐĐĐÎÎÎĘĘĘÉÉÉÉÉÉÉÉÉÉÉÉÇÇÇÉÉÉĘĘĘĆĆĆÇÇÇĚĚĚŃŃŃŐŐŐŘŘŘ×××ÔÔÔ××××××ŐŐŐŇŇŇŃŃŃŇŇŇÔÔÔ×××ŇŇŇŇŇŇŃŃŃŃŃŃĐĐĐÎÎÎÍÍÍĚĚĚÍÍÍÍÍÍÍÍÍÎÎÎĐĐĐŇŇŇÔÔÔŐŐŐŮŮŮŰŰŰÝÝÝßßßÝÝÝŰŰŰŘŘŘŐŐŐŐŐŐŐŐŐŐŐŐŐŐŐÔÔÔŃŃŃÍÍÍÇÇÇÔÔÔčččŕŕŕÜÜÜŕŕŕŇŇŇÍÍÍŘŘŘ×××ŰŰŰ×××ÔÔÔ×××ŘŘŘ××××××ÎÎÎĚĚĚÉÉÉÉÉÉĚĚĚÍÍÍĚĚĚÉÉÉĹĹĹżżżĘĘĘŰŰŰÜÜÜÔÔÔŃŃŃĐĐĐÉÉÉĚĚĚĆĆĆĘĘĘÉÉÉľľľÂÂÂĚĚĚÔÔÔŘŘŘ×××ŃŃŃĚĚĚĚĚĚÎÎÎÎÎÎĚĚĚĚĚĚĘĘĘÉÉÉÉÉÉÇÇÇÇÇÇÇÇÇĚĚĚĚĚĚĚĚĚĘĘĘÉÉÉĆĆĆĹĹĹĂĂĂÉÉÉÉÉÉŃŃŃŃŃŃĹĹĹżżżÇÇÇÍÍÍŐŐŐĘĘĘŔŔŔżżżżżżľľľżżżÂ¸¸¸¸¸¸······µµµµµµµµµµµµ¸¸¸¸¸¸şşş»»»ĽĽĽżżżĹĹĹÇÇÇÇÇÇ×××ÜÜÜŇŇŇÎÎÎŇŇŇŐŐŐŇŇŇĘĘĘÉÉÉľľľĆĆĆĚĚĚÎÎÎĆĆĆĚĚĚÉÉÉĚĚĚÎÎÎÎÎÎĚĚĚĹĹĹżżż»»»»»»ĘĘĘÔÔÔŘŘŘÔÔÔÔÔÔÜÜÜ×××ŘŘŘÔÔÔÎÎÎĘĘĘĘĘĘÎÎÎÔÔÔŘŘŘŰŰŰŘŘŘ×××ĐĐĐÉÉÉÇÇÇżżż­­­ĄĄĄ¦¦¦©©©ŞŞŞŞŞŞ´´´żżżÂÂÂşşş­­­¬¬¬ĽĽĽÉÉÉÇÇÇĂĂĂĂĂĂľľľĽĽĽľľľżżżľľľşşş»»»żżżĹĹĹÂÂÂŔŔŔĹĹĹÇÇÇÉÉÉÇÇÇÉÉÉÇÇÇŃŃŃÔÔÔÝÝÝŘŘŘşşşŞŞŞŻŻŻ´´´ĽĽĽĆĆĆĘĘĘĚĚĚĚĚĚÍÍÍÎÎÎĘĘĘĚĚĚÎÎÎŇŇŇŐŐŐŐŐŐŇŇŇĐĐĐÔÔÔĐĐĐÍÍÍĚĚĚÉÉÉĆĆĆĹĹĹÇÇÇŃŃŃÔÔÔŘŘŘŰŰŰÜÜÜŰŰŰŮŮŮŘŘŘ×××ŘŘŘŰŰŰÜÜÜÝÝÝÝÝÝÝÝÝÝÝÝŐŐŐŐŐŐŐŐŐ×××ŘŘŘŘŘŘŐŐŐÔÔÔĐĐĐÎÎÎÎÎÎĐĐĐÔÔÔŐŐŐ×××ŐŐŐŰŰŰÜÜÜÝÝÝßßßÝÝÝŰŰŰŘŘŘ×××ŐŐŐŐŐŐŐŐŐŇŇŇŃŃŃĐĐĐĘĘĘĹĹĹäääçççÜÜÜßßßÝÝÝÎÎÎĐĐĐÔÔÔŘŘŘßßßÜÜÜ×××ŰŰŰÜÜÜŘŘŘŘŘŘŐŐŐĐĐĐÉÉÉÇÇÇÉÉÉĘĘĘÉÉÉĆĆĆľľľĽĽĽĚĚĚŰŰŰŘŘŘÔÔÔŇŇŇÎÎÎĚĚĚĚĚĚżżżÇÇÇÍÍÍŔŔŔÂÂÂĆĆĆÉÉÉÔÔÔŰŰŰ×××ÎÎÎÍÍÍÍÍÍÍÍÍĚĚĚĚĚĚĚĚĚĘĘĘÉÉÉÇÇÇĆĆĆĹĹĹÉÉÉÉÉÉÇÇÇÇÇÇĆĆĆĹĹĹĂĂĂÂÂÂÇÇÇĹĹĹĘĘĘÍÍÍĂĂĂŔŔŔÇÇÇĚĚĚÉÉÉÂÂÂľľľŔŔŔÂÂÂżżżĽĽĽĽĽĽ¸¸¸¸¸¸¸¸¸şşşşşşşşşşşşşşşµµµ¸¸¸şşşşşşşşş»»»żżżÂÂÂÂÂÂŃŃŃÜÜÜŰŰŰ×××××××××ŐŐŐÔÔÔÎÎλ»»ŔŔŔĂĂĂĚĚĚĹĹĹÎÎÎĘĘĘÇÇÇĹĹĹÂÂÂÂÂÂÂÂÂÂÂÂŔŔŔ´´´ĚĚĚĐĐĐÔÔÔŐŐŐŐŐŐÜÜÜ×××ŇŇŇÍÍÍÇÇÇĂĂĂĂĂĂÉÉÉĐĐĐŐŐŐŮŮŮŇŇŇŇŇŇÔÔÔŇŇŇŇŇŇÍÍÍŔŔŔÇÇÇÉÉÉĆĆĆÂÂÂżżż¸¸¸···ĽĽĽĽĽĽłłł­­­´´´ľľľŔŔŔĂĂĂĹĹĹĹĹĹĂĂĂĹĹĹÇÇÇĹĹĹŔŔŔÂÂÂĆĆĆĹĹĹÂÂÂżżżżżżĹĹĹĚĚĚÍÍÍÉÉÉÉÉÉĘĘĘÔÔÔŮŮŮŘŘŘÇÇÇ´´´±±±µµµ¸¸¸ĽĽĽĂĂĂĘĘĘÎÎÎÎÎÎĚĚĚĆĆĆÇÇÇĚĚĚŃŃŃŐŐŐ×××ÔÔÔŃŃŃĚĚĚÇÇÇĆĆĆÉÉÉÇÇÇĹĹĹĹĹĹÉÉÉÇÇÇÍÍÍÔÔÔŘŘŘŮŮŮŰŰŰÝÝÝŕŕŕÝÝÝÜÜÜŮŮŮŘŘŘŘŘŘŮŮŮŰŰŰŰŰŰŘŘŘ×××ŘŘŘŰŰŰÜÜÜÜÜÜŮŮŮ×××ÔÔÔŃŃŃŇŇŇ×××ßßßâââßßßŰŰŰÜÜÜÝÝÝßßßßßßßßßÜÜÜŮŮŮŘŘŘŐŐŐ×××ŐŐŐĐĐĐÍÍÍĚĚĚĆĆĆľľľëëëŕŕŕÔÔÔßßßŰŰŰĚĚĚŇŇŇŃŃŃŐŐŐŕŕŕÝÝÝŘŘŘÜÜÜŰŰŰÔÔÔÔÔÔ×××ŃŃŃÍÍÍÍÍÍÍÍÍĘĘĘĹĹĹżżż···şşşĘĘĘŘŘŘŐŐŐŇŇŇÔÔÔÎÎÎĚĚĚÇÇǵµµĂĂĂŃŃŃÇÇÇÇÇÇÉÉÉĽĽĽÍÍÍŰŰŰŰŰŰŇŇŇÎÎÎÍÍÍĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚÉÉÉÇÇÇĹĹĹĂĂĂĂĂĂÂÂÂÂÂÂÂÂÂĂĂĂÂÂÂŔŔŔľľľľľľĽĽĽĆĆĆÎÎÎÉÉÉĆĆĆĚĚĚÍÍÍ»»»···»»»ľľľľľľ»»»»»»µµµµµµ······¸¸¸¸¸¸şşşşşş¸¸¸»»»ľľľľľľľľľżżżÂÂÂĹĹĹÂÂÂĘĘĘÔÔÔŰŰŰŮŮŮ××××××ŮŮŮŐŐŐÎÎθ¸¸»»»şşşŔŔŔ»»»ĹĹĹĂĂĂŔŔŔľľľľľľľľľĽĽĽ¸¸¸µµµµµµĐĐĐĚĚĚÍÍÍÔÔÔŇŇŇŐŐŐÎÎÎŘŘŘŇŇŇÍÍÍÉÉÉĘĘĘĐĐĐŘŘŘÜÜÜŘŘŘŇŇŇŐŐŐ×××ĐĐĐÍÍÍÎÎÎĘĘĘÇÇÇĘĘĘĆĆĆĆĆĆĆĆƸ¸¸­­­´´´ľľľľľľşşş±±±ŻŻŻ´´´żżżÇÇÇĘĘĘĆĆĆÂÂÂżżż»»»µµµ···ĽĽĽÉÉÉÇÇÇĹĹĹĂĂĂÉÉÉŃŃŃÍÍÍĂĂĂÉÉÉĂĂĂŇŇŇŰŰŰâââäää×××ÔÔÔĘĘĘ»»»ĽĽĽĹĹĹĘĘĘÇÇÇŔŔŔĹĹĹĆĆĆĘĘĘĐĐĐŐŐŐŘŘŘŐŐŐŇŇŇĐĐĐĚĚĚĘĘĘÍÍÍĚĚĚÇÇÇÉÉÉÎÎÎĚĚĚŇŇŇŮŮŮŰŰŰŮŮŮŘŘŘŰŰŰßßß×××××××××ŮŮŮŰŰŰÜÜÜŰŰŰŘŘŘ××××××ŘŘŘŰŰŰÜÜÜÜÜÜŘŘŘÔÔÔ×××ŐŐŐŘŘŘŕŕŕëëëîîîčččâââÝÝÝÝÝÝßßßŕŕŕßßßÝÝÝŰŰŰŮŮŮ×××ŘŘŘŐŐŐÍÍÍÉÉÉÇÇÇŔŔŔ¸¸¸îîîďďďŮŮŮâââââââââŐŐŐĐĐĐŐŐŐŐŐŐ×××ŮŮŮŰŰŰŮŮŮ×××ÔÔÔÔÔÔĐĐĐÎÎÎĐĐĐÎÎÎÇÇÇĂĂĂĹĹŵµµĚĚĚŮŮŮŐŐŐÔÔÔŮŮŮÔÔÔÉÉÉÎÎÎÇÇÇľľľ´´´±±±µµµŔŔŔÇÇÇÇÇÇĆĆĆĚĚĚÜÜÜăăăÎÎÎĹĹĹŇŇŇĘĘĘĘĘĘĆĆĆŔŔŔĂĂĂÉÉÉĆĆĆżżżĂĂĂÂÂÂŔŔŔżżżľľľľľľľľľľľľÂÂÂŔŔŔľľľĽĽĽĹĹĹĚĚĚÇÇÇżżż¸¸¸¸¸¸şşş»»»»»»»»»şşşşşş¸¸¸···µµµµµµµµµ···¸¸¸şşşşşşľľľ»»»şşşŔŔŔŔŔŔĂĂĂŃŃŃ×××ŮŮŮŰŰŰ×××ŘŘŘŰŰŰŮŮŮŐŐŐŘŘŘÉÉÉ»»»şşşľľľľľľżżżŔŔŔżżżĽĽĽ»»»ĽĽĽżżżľľľ»»»¸¸¸´´´ĹĹĹĐĐĐÎÎÎĘĘĘÍÍÍÎÎÎÎÎÎĐĐĐŃŃŃĚĚĚĹĹĹĘĘĘ×××ŮŮŮŐŐŐ××××××ŐŐŐÔÔÔŃŃŃĐĐĐÎÎÎÎÎÎĘĘĘĚĚĚĆĆĆÇÇÇÉÉÉşşş©©©¬¬¬±±±»»»ŔŔŔ»»»ŻŻŻŞŞŞłłłľľľĹĹĹľľľ¸¸¸µµµ±±±ŻŻŻ´´´ľľľÍÍÍÂÂÂľľľÉÉÉŇŇŇŇŇŇÎÎÎÍÍÍĆĆĆÇÇÇĘĘĘĐĐĐ×××ÜÜÜßßßßßßâââŘŘŘŔŔŔ´´´ĽĽĽżżżĽĽĽŔŔŔżżżÂÂÂĆĆĆÉÉÉÎÎÎÔÔÔŃŃŃĚĚĚÉÉÉĆĆĆĘĘĘĘĘĘĘĘĘĚĚĚÉÉÉÇÇÇĚĚĚÎÎÎŇŇŇÔÔÔŐŐŐ×××ŮŮŮŰŰŰŮŮŮ××××××ŘŘŘÜÜÜÝÝÝÝÝÝÜÜÜŮŮŮŰŰŰÜÜÜÝÝÝßßßÝÝÝÜÜÜŰŰŰÝÝÝŮŮŮŮŮŮăăăîîîńńńçççÜÜÜßßßŰŰŰŘŘŘŮŮŮÝÝÝßßßŰŰŰ×××ŃŃŃ×××ĹĹĹĽĽĽĆĆĆäääâââäääčččíííŮŮŮâââŕŕŕâââŘŘŘÔÔÔŰŰŰŮŮŮŘŘŘŘŘŘŘŘŘ×××ÔÔÔŃŃŃÎÎÎÍÍÍĚĚĚÍÍÍÉÉÉĂĂĂżżżľľľżżżĐĐĐŮŮŮŐŐŐÔÔÔ×××ŃŃŃĆĆĆĘĘĘÇÇÇŔŔŔşşşµµµ···ĽĽĽŔŔŔÇÇÇĂĂĂŔŔŔĚĚĚŰŰŰ×××ĘĘĘÉÉÉÇÇÇĘĘĘÉÉÉĹĹĹĂĂĂĂĂĂĂĂĂÂÂÂŔŔŔŔŔŔżżżĽĽĽ»»»»»»»»»»»»»»»»»»¸¸¸···ĽĽĽÂÂÂżżż¸¸¸µµµ···¸¸¸şşş»»»»»»şşşşşş···············¸¸¸şşş»»»···µµµşşşĆĆĆÍÍÍÇÇÇÉÉÉÔÔÔÍÍÍÎÎÎĐĐĐŇŇŇŮŮŮßßßŘŘŘÍÍÍĂĂĂşşş´´´···ľľľżżżŔŔŔĂĂĂľľľľľľżżżżżżżżżľľľĽĽĽ»»»°°°¸¸¸ŔŔŔĹĹĹĘĘĘÍÍÍÍÍÍĚĚĚ×××ÜÜÜŐŐŐÉÉÉĚĚĚŮŮŮŰŰŰĐĐĐÍÍÍÍÍÍÎÎÎÎÎÎÎÎÎÎÎÎĐĐĐĐĐĐĆĆĆĹĹŵµµ©©©ĄĄĄłłłşşşŔŔŔŔŔŔ»»»······şşş±±±±±±±±±±±±­­­¬¬¬ŻŻŻ´´´ÉÉÉĆĆĆŔŔŔżżżĂĂĂĘĘĘÉÉÉĹĹĹĘĘĘĘĘĘÉÉÉÉÉÉĘĘĘÎÎÎŇŇŇŐŐŐÝÝÝăăăăăăÝÝÝ×××ÉÉÉşşş´´´łłłµµµ¸¸¸¸¸¸ľľľĆĆĆĚĚĚĚĚĚĚĚĚĘĘĘĘĘĘÉÉÉÇÇÇÉÉÉÉÉÉÉÉÉĘĘĘÍÍÍŃŃŃŇŇŇÔÔÔÔÔÔ×××ŘŘŘŘŘŘ××××××ŘŘŘŰŰŰÝÝÝÝÝÝÜÜÜÜÜÜŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰÜÜÜÜÜÜŮŮŮŮŮŮŮŮŮßßßăăăäääŕŕŕÜÜÜÜÜÜŮŮŮŮŮŮŰŰŰßßßßßßŰŰŰ×××ĐĐĐŇŇŇÉÉÉŇŇŇŰŰŰëëëăăăçççÜÜÜăăăÔÔÔßßßâââçççăăăäääçççâââŮŮŮÔÔÔŇŇŇÔÔÔÔÔÔŐŐŐĐĐĐÎÎÎĚĚĚÇÇÇĹĹĹĂĂĂĂĂĂĂĂĂĚĚĚŇŇŇŘŘŘ×××ÔÔÔŇŇŇÍÍÍĂĂĂÇÇÇÇÇÇĆĆĆÂÂÂĽĽĽ¸¸¸······ĆĆĆÇÇÇŔŔŔŔŔŔĐĐĐŰŰŰÔÔÔĘĘĘÇÇÇÉÉÉĘĘĘÉÉÉÂÂÂľľľżżżĹĹĹŔŔŔżżżĽĽĽ»»»¸¸¸¸¸¸······¸¸¸¸¸¸···µµµ···şşş¸¸¸´´´łłł´´´µµµ¸¸¸şşşşşşşşşşşş······¸¸¸¸¸¸¸¸¸şşş»»»»»»żżżµµµĽĽĽĘĘĘĹĹŵµµ°°°µµµşşşżżżÇÇÇÎÎÎÔÔÔŇŇŇÇÇÇ»»»ľľľ»»»»»»żżżÂÂÂÂÂÂŔŔŔÂÂÂżżżĂĂĂĆĆĆĹĹĹÂÂÂŔŔŔľľľľľľ´´´ŻŻŻŻŻŻ¸¸¸ĹĹĹÉÉÉĘĘĘĘĘĘŃŃŃŘŘŘŐŐŐÇÇÇĚĚĚÝÝÝŕŕŕŇŇŇŃŃŃŃŃŃĐĐĐĐĐĐÎÎÎÎÎÎÍÍÍÍÍÍĚĚĚÉÉÉÉÉÉÇÇÇĂĂĂżżżµµµ¨¨¨¬¬¬°°°···ľľľÂÂÂÂÂÂżżżĽĽĽŔŔŔÂÂÂĂĂĂÂÂÂÂÂÂŔŔŔ»»»µµµżżżÇÇÇÇÇÇĽĽĽľľľĚĚĚŃŃŃĚĚĚĆĆĆĆĆĆĂĂĂÂÂÂÂÂÂÇÇÇŇŇŇŰŰŰâââăăăëëëîîîçççäääăăăßßßââââââŮŮŮÉÉÉľľľľľľżżżŔŔŔÂÂÂĆĆĆĹĹĹĆĆĆÇÇÇĆĆĆĆĆĆÇÇÇĘĘĘÍÍÍĐĐĐŃŃŃŃŃŃŃŃŃŇŇŇŐŐŐ×××ŐŐŐŐŐŐŘŘŘŰŰŰÜÜÜÜÜÜÜÜÜßßßÜÜÜŮŮŮ××××××ŘŘŘŰŰŰÜÜÜŮŮŮŰŰŰÜÜÜŰŰŰŮŮŮŮŮŮÜÜÜßßßŘŘŘŘŘŘŮŮŮÜÜÜŕŕŕßßßŮŮŮŐŐŐĐĐĐĚĚĚÇÇÇăăăëëëíííăăăëëëćććíííŮŮŮßßßÜÜÜŕŕŕßßßăăăçççäääßßßÜÜÜŮŮŮŘŘŘÔÔÔŃŃŃŇŇŇŃŃŃĘĘĘĹĹĹĹĹĹĚĚĚŃŃŃŇŇŇŐŐŐÔÔÔ××××××ŇŇŇŇŇŇÎÎÎĹĹĹÇÇÇĘĘĘĘĘĘÇÇÇŔŔŔşşşłłł°°°ĆĆĆÎÎÎÍÍÍĹĹĹÉÉÉÔÔÔŮŮŮŘŘŘÎÎÎĘĘĘÇÇÇÇÇÇÂÂÂĽĽĽżżżĆĆĆŔŔŔżżżľľľ»»»¸¸¸······µµµşşşşşşşşş······µµµµµµ´´´°°°±±±łłłµµµ···¸¸¸şşş»»»¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸żżżşşşĹĹĹÎÎÎŔŔŔ´´´µµµ···şşşľľľľľľşşşµµµµµµ¸¸¸ĽĽĽŔŔŔÂÂÂĹĹĹĆĆĆĹĹĹÂÂÂŔŔŔŔŔŔÂÂÂĹĹĹĹĹĹĂĂĂĂĂĂĂĂĂżżżşşş»»»­­­¨¨¨łłłżżżÂÂÂĆĆĆĚĚĚĚĚĚĚĚĚÉÉÉĂĂĂÇÇÇŘŘŘßßßŐŐŐÔÔÔŇŇŇŃŃŃĐĐĐĐĐĐÎÎÎÍÍÍĚĚĚĘĘĘĆĆĆÇÇÇĆĆĆżżżŔŔŔ»»»©©©¬¬¬­­­°°°´´´¸¸¸»»»ĽĽĽĽĽĽÂÂÂÂÂÂżżżżżżĹĹĹÉÉÉŔŔŔ´´´µµµĂĂĂÉÉÉŔŔŔżżżÉÉÉĐĐĐÍÍÍÎÎÎÎÎÎĚĚĚĹĹĹżżżÂÂÂĘĘĘÔÔÔßßß×××ŰŰŰŕŕŕßßßçççíííçççčččęęęâââĐĐĐŔŔŔ»»»ĽĽĽżżżµµµżżżĽĽĽÂÂÂÉÉÉĹĹĹĹĹĹĂĂĂĘĘĘÍÍÍĐĐĐĐĐĐĐĐĐĐĐĐŃŃŃŇŇŇÔÔÔÔÔÔŐŐŐ×××ŮŮŮŰŰŰÜÜÜÜÜÜßßßÜÜÜŘŘŘŐŐŐÔÔÔŐŐŐ×××ŮŮŮŮŮŮŰŰŰŰŰŰŮŮŮŘŘŘŮŮŮÜÜÜŕŕŕŐŐŐ×××ŮŮŮÝÝÝŕŕŕßßßŮŮŮÔÔÔÎÎÎÇÇÇÂÂÂăăăëëëëëëçççďďďëëëńńńŰŰŰßßßŰŰŰßßßßßßćććÝÝÝâââćććęęęčččŕŕŕÔÔÔĚĚĚÎÎÎĚĚĚÇÇÇÉÉÉÍÍÍŐŐŐŮŮŮŰŰŰ×××ŇŇŇŐŐŐ×××ŃŃŃÔÔÔÔÔÔÉÉÉÉÉÉĚĚĚÍÍÍÉÉÉÂÂÂşşşłłłŻŻŻĆĆĆĚĚĚŃŃŃÍÍÍÇÇÇĚĚĚŐŐŐŰŰŰŘŘŘÍÍÍĹĹĹĂĂĂĂĂĂŔŔŔŔŔŔĆĆĆĂĂĂÂÂÂżżżĽĽĽ»»»şşş¸¸¸¸¸¸»»»şşşşşş¸¸¸µµµłłłłłł´´´°°°°°°±±±łłłµµµ¸¸¸şşş»»»şşşşşş¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸»»»ŔŔŔĚĚĚĘĘĘşşş¸¸¸ÂÂÂĂĂĂĂĂĂĆĆĆÉÉÉÇÇÇÂÂÂĽĽĽĽĽĽżżżŔŔŔĹĹĹÉÉÉÇÇÇĂĂĂĂĂĂĂĂĂĹĹĹşşşşşş¸¸¸¸¸¸żżżĹĹĹŔŔŔµµµµµµŞŞŞŞŞŞ¸¸¸ÂÂÂÂÂÂĹĹĹÍÍÍŇŇŇĹĹĹÂÂÂĹĹĹĹĹĹÍÍÍŘŘŘ×××ÎÎÎÍÍÍĚĚĚÍÍÍĐĐĐŃŃŃĐĐĐÎÎÎĚĚĚÇÇÇÉÉÉÇÇÇŔŔŔĹĹĹĂĂĂ´´´ľľľĽĽĽ¸¸¸±±±­­­ŻŻŻ´´´şşşŞŞŞ°°°´´´´´´şşşĂĂĂĹĹĹŔŔŔłłł»»»ÂÂÂĂĂĂŔŔŔľľľżżżŔŔŔÍÍÍĐĐĐĐĐĐĘĘĘÂÂÂŔŔŔĆĆĆÍÍÍĘĘĘÉÉÉ×××ăăăăăăäääâââŐŐŐäääëëëîîîçççŕŕŕßßßâââäääżżżĆĆĆşşşĽĽĽĆĆĆÂÂÂĹĹĹĹĹĹÉÉÉĚĚĚÎÎÎĐĐĐĐĐĐĐĐĐŃŃŃŇŇŇŃŃŃŇŇŇÔÔÔ×××ŘŘŘŮŮŮŰŰŰÜÜÜÜÜÜŰŰŰŘŘŘ×××ÔÔÔŇŇŇŇŇŇŇŇŇÔÔÔÔÔÔŇŇŇÔÔÔŘŘŘŰŰŰÜÜÜÜÜÜŐŐŐ×××ŮŮŮÜÜÜÝÝÝÜÜÜŘŘŘÔÔÔĚĚĚÉÉÉÂÂÂäääëëëîîîďďďńńńçççîîîŮŮŮŕŕŕÝÝÝäääćććíííăăăăăăăăăäääăăăßßßŮŮŮŐŐŐÇÇÇÂÂÂĂĂĂÎÎÎŘŘŘŮŮŮ×××ŐŐŐÔÔÔŃŃŃŐŐŐŐŐŐĐĐĐŘŘŘŰŰŰÍÍÍĘĘĘĚĚĚĚĚĚÉÉÉÂÂÂşşş´´´±±±ĂĂĂÂÂÂÇÇÇÍÍÍĘĘĘĘĘĘÎÎÎÎÎÎÜÜÜŃŃŃÇÇÇĂĂĂĹĹĹĹĹĹĹĹĹĹĹĹĹĹĹĂĂĂŔŔŔżżżĽĽĽĽĽĽ»»»»»»şşş·········´´´°°°°°°±±±°°°°°°±±±łłł´´´···şşş»»»»»»şşş¸¸¸¸¸¸¸¸¸şşşĽĽĽľľľĆĆĆÍÍÍŃŃŃĹĹŵµµ···ľľľżżżÍÍÍĹĹĹľľľżżżÂÂÂĂĂĂĂĂĂĂĂĂ°°°´´´µµµ°°°ŞŞŞ©©©ŞŞŞŞŞŞ°°°°°°ŻŻŻŻŻŻ¸¸¸ÂÂÂżżż´´´ŞŞŞ¦¦¦¬¬¬ľľľÇÇÇĆĆĆĆĆĆĚĚĚÔÔÔżżżżżżÉÉÉÉÉÉÍÍÍŮŮŮÝÝÝ×××ÔÔÔŃŃŃŃŃŃÔÔÔÔÔÔŃŃŃÍÍÍÍÍÍĘĘĘĘĘĘÇÇÇĹĹĹÇÇÇÉÉÉĹĹĹĘĘĘÉÉÉĂĂĂşşşłłłłłłĽĽĽĆĆĆÇÇÇĐĐĐŇŇŇÉÉÉ»»»µµµşşşżżżµµµ´´´»»»ĆĆĆÇÇÇŔŔŔľľľĂĂĂżżżĆĆĆĚĚĚĘĘĘĆĆĆÂÂÂĹĹĹÉÉÉżżżĆĆĆÔÔÔÝÝÝßßßâââćććäääÝÝÝćććíííëëëččččččçççäääŘŘŘŮŮŮ»»»···ŔŔŔĽĽĽĹĹĹĆĆĆĆĆĆÉÉÉĚĚĚÍÍÍÍÍÍÎÎÎĐĐĐŃŃŃÎÎÎŃŃŃÔÔÔŐŐŐ×××ŘŘŘŰŰŰÜÜÜŰŰŰŰŰŰŘŘŘ×××ÔÔÔŃŃŃÎÎÎÍÍÍÍÍÍĘĘĘÉÉÉÍÍÍŇŇŇ××××××ŐŐŐŘŘŘŘŘŘŮŮŮŰŰŰŰŰŰŮŮŮ×××ŐŐŐĚĚĚÍÍÍÇÇÇëëëńńńóóóřřřňňňńńńöööâââçççâââăăăßßßŕŕŕęęęäääÝÝÝŮŮŮŮŮŮŰŰŰÜÜÜÜÜÜÎÎÎÂÂÂŔŔŔŃŃŃŰŰŰ×××ŃŃŃŃŃŃŃŃŃŃŃŃŘŘŘŐŐŐÎÎÎŰŰŰŕŕŕÎÎÎĘĘĘĚĚĚĚĚĚÉÉÉ»»»···´´´şşş¸¸¸ÂÂÂÍÍÍÎÎÎĐĐĐÍÍÍÂÂÂŮŮŮ×××ĐĐĐÉÉÉĆĆĆĆĆĆĆĆĆĹĹĹĂĂĂÂÂÂŔŔŔżżżľľľľľľĽĽĽĽĽĽşşşµµµ´´´···µµµ±±±ŻŻŻ±±±±±±±±±±±±±±±´´´µµµ¸¸¸şşş»»»şşş¸¸¸şşş»»»ŔŔŔĹĹĹÉÉÉÍÍÍĐĐĐĚĚĚĹĹĹÂÂÂŔŔŔŔŔŔĹĹĹşşş±±±ŻŻŻ´´´şşşşşşµµµłłłŔŔŔĆĆĆĆĆĆľľľ¸¸¸······µµµłłł¸¸¸···±±±´´´ľľľľľľ···¬¬¬¦¦¦©©©···ĂĂĂÇÇÇÇÇÇÉÉÉÎÎÎľľľŔŔŔĘĘĘÉÉÉŃŃŃÜÜÜŰŰŰŮŮŮŐŐŐĐĐĐÎÎÎÎÎÎÍÍÍÉÉÉĂĂĂŔŔŔŔŔŔĽĽĽ»»»ĽĽĽĽĽĽżżżÇÇÇĘĘĘĘĘĘĘĘĘĆĆĆĂĂĂĹĹĹĚĚĚŃŃŃÎÎÎÔÔÔŘŘŘŐŐŐÇÇÇľľľżżżĆĆĆ»»»łłł´´´ŔŔŔĘĘĘÇÇÇĆĆĆĘĘĘĂĂĂÉÉÉÎÎÎÎÎÎÇÇÇŔŔŔľľľĽĽĽĹĹĹÇÇÇĆĆĆÉÉÉĐĐĐ×××ÝÝÝćććŰŰŰŕŕŕćććçççęęęíííęęęäääăăăâââşşşłłłľľľ¸¸¸żżżżżżÂÂÂĹĹĹÇÇÇĘĘĘĘĘĘĚĚĚÍÍÍÎÎÎÍÍÍĐĐĐŇŇŇŐŐŐŐŐŐ×××ŮŮŮÜÜÜŰŰŰŰŰŰŘŘŘŐŐŐŃŃŃÎÎÎÍÍÍĚĚĚÉÉÉÇÇÇÇÇÇĘĘĘÎÎÎŇŇŇŐŐŐŐŐŐŰŰŰŰŰŰŮŮŮŘŘŘ×××ŐŐŐŐŐŐŐŐŐĐĐĐÎÎÎĆĆĆďďďóóóóóóüüüöööîîîőőőăăăęęęççççççßßßÝÝÝăăăŕŕŕßßßÝÝÝÜÜÜŰŰŰ×××ÔÔÔÝÝÝÇÇÇŔŔŔĐĐĐŰŰŰŐŐŐĐĐĐÔÔÔÎÎÎŃŃŃŰŰŰŐŐŐÍÍÍÜÜÜâââÎÎÎÉÉÉĘĘĘĚĚĚÉÉÉĂĂĂĽĽĽ¸¸¸µµµ°°°···ĆĆĆĐĐĐĐĐĐÔÔÔÎÎÎľľľÔÔÔŮŮŮŘŘŘÎÎÎĆĆĆĆĆĆÇÇÇĹĹĹÂÂÂÂÂÂŔŔŔżżżľľľľľľľľľľľľľľľ···µµµ¸¸¸¸¸¸´´´±±±´´´±±±±±±±±±±±±łłłµµµ¸¸¸şşş»»»şşş¸¸¸şşşżżżĆĆĆÍÍÍŃŃŃÉÉÉĆĆĆ»»»»»»ĂĂĂ»»»±±±µµµÇÇÇżżżşşşşşşşşşşşşżżżĆĆĆżżżĆĆĆÉÉÉĹĹĹÂÂÂĹĹĹĹĹĹĂĂĂżżżÇÇÇÇÇÇ»»»µµµşşşĽĽĽşşş¸¸¸ŞŞŞ˘˘˘©©©¸¸¸ĂĂĂĆĆĆĆĆĆÎÎÎÂÂÂĆĆĆĚĚĚĆĆĆÎÎÎŐŐŐĚĚĚÇÇÇĂĂĂżżżżżżÂÂÂÂÂÂľľľşşşżżżżżżşşş¸¸¸ľľľşşşľľľÎÎÎĚĚĚÍÍÍÎÎÎĐĐĐŃŃŃĐĐĐÎÎÎÍÍÍŮŮŮŐŐŐŐŐŐ×××ŃŃŃĂĂĂşşş¸¸¸ÂµµµŻŻŻµµµŔŔŔĂĂĂÂÂÂŔŔŔľľľĹĹĹÍÍÍĐĐĐĚĚĚÇÇÇĂĂĂĂĂĂŔŔŔĹĹĹÂÂÂĚĚĚŕŕŕćććßßßŕŕŕÜÜÜŕŕŕâââăăăčččíííęęęäääÝÝÝÝÝݵµµ±±±żżż···şşşµµµľľľŔŔŔĹĹĹĆĆĆÇÇÇÉÉÉĘĘĘÍÍÍÍÍÍĐĐĐŇŇŇÔÔÔŐŐŐ×××ŮŮŮÜÜÜÜÜÜŰŰŰ×××ÔÔÔĐĐĐÍÍÍĚĚĚĘĘĘĘĘĘĚĚĚĚĚĚĚĚĚĚĚĚĐĐĐŐŐŐŰŰŰÝÝÝÜÜÜŮŮŮŐŐŐÔÔÔÔÔÔŐŐŐ×××ŐŐŐÍÍÍŔŔŔîîîńńńîîîüüüüüüöööúúúúúúňňňçççâââăăăčččăăăŕŕŕÝÝÝŰŰŰŮŮŮŘŘŘŮŮŮŮŮŮŐŐŐĆĆĆÂÂÂĐĐĐŰŰŰ×××ŃŃŃŇŇŇŇŇŇÎÎÎ×××ŇŇŇŘŘŘŕŕŕÎÎÎĹĹĹĆĆĆÇÇÇÇÇÇĆĆĆĂĂĂľľľşşşµµµ±±±···ľľľłłłşşşÎÎÎÍÍÍÇÇǸ¸¸×××ŕŕŕÔÔÔÍÍÍÇÇÇĂĂĂĆĆĆŔŔŔÂÂÂĂĂĂÂÂÂżżżľľľľľľżżżşşşşşşşşş¸¸¸···µµµµµµµµµ±±±···şşşµµµ´´´······´´´´´´···şşşŔŔŔĆĆĆÉÉÉÉÉÉÇÇÇżżż¸¸¸ĽĽĽÂÂÂĽĽĽşşşŔŔŔĹĹĹĆĆĆĹĹĹĂĂĂĂĂĂĆĆĆÉÉÉÉÉÉÉÉÉĆĆĆĹĹĹÂÂÂŔŔŔŔŔŔŔŔŔÂÂÂĂĂĂÂÂÂÂÂÂĂĂĂĹĹĹ´´´¬¬¬ĽĽĽżżż»»»´´´ŞŞŞ¦¦¦©©©´´´żżżÇÇÇÉÉÉÍÍÍÂÂÂĂĂĂĘĘĘĆĆĆĘĘĘĘĘĘÉÉÉĆĆĆĂĂĂżżżĽĽĽĽĽĽĽĽĽľľľÂÂÂľľľ»»»»»»»»»»»»»»»ĽĽĽÍÍÍĐĐĐÎÎÎÉÉÉÂÂÂÂÂÂĘĘĘŇŇŇŮŮŮ×××ŰŰŰÔÔÔĚĚĚÔÔÔĘĘʨ¨¨ŔŔŔÂÂÂĽĽĽ±±±­­­µµµżżżÂÂÂľľľľľľĹĹĹÍÍÍŃŃŃÎÎÎĚĚĚÍÍÍŔŔŔľľľĘĘĘŮŮŮŕŕŕçççćććŰŰŰŘŘŘßßßßßßŕŕŕëëëďďďčččäääâââăăăŐŐŐ»»»°°°µµµ»»»···¸¸¸ĽĽĽĽĽĽÇÇÇĆĆĆĽĽĽĹĹĹÇÇÇĚĚĚŇŇŇŐŐŐŇŇŇŇŇŇ×××ŐŐŐŃŃŃŮŮŮŮŮŮŘŘŘ×××ÔÔÔĐĐĐÍÍÍĘĘĘĘĘĘĘĘĘĘĘĘĚĚĚÎÎÎŃŃŃÔÔÔŐŐŐ×××ÝÝÝŮŮŮŇŇŇÔÔÔŃŃŃĐĐĐ×××ŘŘŘĹĹĹĆĆĆëëëőőőńńń˙˙˙őőőőőőůůůúúúőőőëëëăăăŕŕŕâââŕŕŕŕŕŕÝÝÝÜÜÜŰŰŰŰŰŰŮŮŮŮŮŮ×××ÎÎÎÍÍÍŘŘŘŕŕŕÜÜÜ×××ÔÔÔŃŃŃĐĐĐŇŇŇŃŃŃ×××ŮŮŮĐĐĐÉÉÉĆĆĆÇÇÇÉÉÉÉÉÉĆĆĆżżżşşşµµµ¬¬¬ŻŻŻ···łłł´´´ÂÂÂÉÉÉÔÔÔĆĆĆ×××ÝÝÝŐŐŐÎÎÎĘĘĘĆĆĆĆĆĆÇÇÇÉÉÉÇÇÇĆĆĆĂĂĂżżżľľľĽĽĽĂĂĂŔŔŔ»»»···´´´µµµ¸¸¸şşşşşşĽĽĽşşş´´´łłł¸¸¸ĽĽĽĽĽĽĽĽĽľľľŔŔŔĆĆĆĚĚĚÍÍÍĚĚĚÉÉÉşşşşşşŔŔŔŔŔŔşşşľľľĹĹĹĂĂĂľľľľľľľľľżżżŔŔŔŔŔŔľľľĽĽĽÂÂÂÂÂÂĂĂĂĂĂĂÂÂÂÂÂÂŔŔŔŔŔŔżżżÂÂÂŔŔŔĂĂø¸¸ŻŻŻĽĽĽÂÂÂĽĽĽşşş´´´ŻŻŻ¬¬¬°°°şşşÂÂÂÉÉÉÍÍÍÂÂÂĂĂĂĘĘĘĆĆĆÉÉÉĘĘĘÇÇÇĆĆĆÂÂÂżżżĽĽĽĽĽĽĽĽĽĽĽĽşşşşşşşşşĽĽĽĹĹĹĚĚĚĐĐĐÎÎÎŔŔŔĂĂĂĆĆĆĂĂĂżżżŔŔŔĆĆĆĚĚĚÜÜÜŐŐŐ×××ÔÔÔÎÎÎŐŐŐÎÎΰ°°łłłĽĽĽŔŔŔ¸¸¸­­­¬¬¬´´´ĽĽĽşşşşşşżżżĆĆĆĘĘĘĘĘĘÍÍÍŇŇŇÉÉÉÂÂÂĆĆĆÍÍÍŃŃŃŰŰŰâââÝÝÝßßßăăăÝÝÝÜÜÜçççîîîęęęčččÜÜÜßßßÜÜÜÎÎÎĽĽĽłłłłłł···şşşŔŔŔĽĽĽľľľ»»»şşşĹĹĹĆĆĆĆĆĆĆĆĆĘĘĘŃŃŃ×××ŮŮŮßßßâââÜÜÜŰŰŰŘŘŘŐŐŐŇŇŇÎÎÎĚĚĚĘĘĘĘĘĘĘĘĘĚĚĚÍÍÍÎÎÎĐĐĐŃŃŃŇŇŇŐŐŐŮŮŮŐŐŐÔÔÔŐŐŐÎÎÎÇÇÇĚĚĚŔŔŔľľľÉÉÉćććîîîńńń˙˙˙ďďďóóóöööůůůöööďďďćććßßßÜÜÜßßßÝÝÝÜÜÜÜÜÜŰŰŰŰŰŰŰŰŰŰŰŰŃŃŃŇŇŇŐŐŐŮŮŮÝÝÝŰŰŰŐŐŐĐĐĐŃŃŃĐĐĐÍÍÍŇŇŇŇŇŇÎÎÎÎÎÎĚĚĚĹĹĹÇÇÇĘĘĘĘĘĘÇÇÇŔŔŔşşşµµµ±±±łłł»»»···µµµżżżĂĂĂÎÎÎĂĂĂÍÍÍŮŮŮÜÜÜŇŇŇĚĚĚÍÍÍĚĚĚÇÇÇĆĆĆĂĂĂÂÂÂŔŔŔŔŔŔŔŔŔŔŔŔżżżĽĽĽ»»»»»»ľľľĂĂĂÇÇÇĘĘĘÉÉÉÉÉÉĆĆĆŔŔŔżżżĂĂĂÉÉÉĘĘĘĚĚĚĚĚĚĚĚĚÍÍÍÍÍÍĘĘĘĹĹĹŔŔŔĽĽĽĽĽĽĽĽĽ¸¸¸¸¸¸ĹĹĹĚĚĚÂÂÂŔŔŔľľľ»»»»»»»»»ĽĽĽ»»»»»»ľľľľľľľľľľľľżżżŔŔŔŔŔŔÂÂÂŔŔŔÇÇÇŔŔŔÂÂÂľľľłłłşşşŔŔŔľľľżżżżżż¸¸¸±±±ŻŻŻ´´´şşşÉÉÉÎÎÎÂÂÂĹĹĹĘĘĘĆĆĆÉÉÉÉÉÉÇÇÇĹĹĹÂÂÂżżżĽĽĽ»»»»»»»»»şşşĽĽĽĽĽĽľľľÇÇÇŇŇŇŐŐŐÎÎθ¸¸»»»żżżŔŔŔÂÂÂÂÂÂĹĹĹÇÇÇ×××ŇŇŇ×××ŘŘŘŃŃŃŇŇŇŃŃŃŔŔŔ´´´µµµşşş»»»¸¸¸±±±ŻŻŻŻŻŻĽĽĽ»»»ĽĽĽżżżŔŔŔżżżĆĆĆÍÍÍÉÉÉĂĂĂÂÂÂÂÂÂĹĹĹÎÎÎÜÜÜßßßâââäääÝÝÝÜÜÜçççîîîęęęçççâââßßßââââââŃŃѸ¸¸­­­°°°şşşĆĆĆ»»»µµµ¸¸¸ĹĹĹÂÂÂĘĘĘĆĆĆÇÇÇĐĐĐÔÔÔĐĐĐŃŃŃŘŘŘÜÜÜŰŰŰ×××ŇŇŇĐĐĐĚĚĚĘĘĘÉÉÉÉÉÉĘĘĘÍÍÍÎÎÎĐĐĐŃŃŃĐĐĐĐĐĐÔÔÔŇŇŇÎÎÎĐĐĐĐĐĐÉÉÉÇÇÇÎÎÎĆĆĆÎÎÎÜÜÜęęęëëëööö˙˙˙ńńńóóóőőőööööööňňňëëëăăăÝÝÝÝÝÝÜÜÜŮŮŮŘŘŘŘŘŘŘŘŘŮŮŮŰŰŰÎÎÎ×××ÜÜÜŰŰŰŮŮŮŮŮŮŐŐŐÎÎÎĐĐĐŇŇŇĚĚĚÔÔÔŃŃŃĹĹĹĘĘĘÉÉÉĆĆĆÇÇÇÉÉÉÇÇÇĹĹĹŔŔŔ»»»¸¸¸¸¸¸ĽĽĽÂÂÂşşşľľľÍÍÍÇÇÇ»»»ÂÂÂ×××ăăă×××ĚĚĚÍÍÍĚĚĚÎÎÎÍÍÍĚĚĚÍÍÍÎÎÎŃŃŃŇŇŇÔÔÔŃŃŃŃŃŃŃŃŃŃŃŃĐĐĐĚĚĚĆĆĆÂÂÂĹĹĹĆĆĆÇÇÇĆĆĆĂĂĂĂĂĂĹĹĹĆĆĆÇÇÇĆĆĆĂĂĂÂÂÂÂÂÂżżżĽĽĽşşşŔŔŔşşş´´´łłł¸¸¸ÉÉÉÍÍÍŔŔŔĽĽĽ»»»»»»ĽĽĽľľľĽĽĽşşşµµµżżżľľľĽĽĽ»»»ľľľŔŔŔĹĹĹÇÇÇĹĹĹÎÎÎĹĹĹĂĂĂ´´´µµµĽĽĽŔŔŔÂÂÂŔŔŔľľľ¸¸¸łłł±±±°°°ÉÉÉÎÎÎĂĂĂĹĹĹĚĚĚÇÇÇÉÉÉÉÉÉĆĆĆĹĹĹÂÂÂżżżĽĽĽ»»»»»»»»»»»»żżżĽĽĽ»»»ĂĂĂÎÎÎÍÍÍ»»»ľľľŔŔŔĂĂĂĆĆĆÉÉÉÉÉÉĘĘĘÍÍÍÎÎÎŘŘŘÜÜÜŇŇŇĐĐĐŇŇŇĐĐĐŔŔŔµµµ°°°¸¸¸żżż»»»±±±­­­´´´µµµşşşĽĽĽĽĽĽ»»»żżżÇÇÇżżżżżżŔŔŔŔŔŔÂÂÂĘĘĘ×××ÝÝÝßßßăăăŕŕŕŕŕŕëëëîîîçççăăăçççßßßÝÝÝćććŕŕŕÍÍÍĽĽĽ¸¸¸ŰŰŰäääŕŕŕŘŘŘÉÉÉĽĽĽľľľ···ľľľĽĽĽŔŔŔÉÉÉÍÍÍĚĚĚÎÎÎŇŇŇ×××ŐŐŐŇŇŇÎÎÎĚĚĚÉÉÉÉÉÉÉÉÉÇÇÇĘĘĘÎÎÎŃŃŃŇŇŇŇŇŇŇŇŇŃŃŃÔÔÔÎÎÎĘĘĘÉÉÉĆĆĆĆĆĆŃŃŃăăăäääčččîîîîîîíííööö˙˙˙ńńńóóóóóóóóóóóóňňňîîîčččäääÝÝÝŰŰŰ×××ÔÔÔŇŇŇÔÔÔ×××ŮŮŮÔÔÔßßßäääŕŕŕÜÜÜÜÜÜŮŮŮÔÔÔĐĐĐŇŇŇÍÍÍÔÔÔÎÎÎżżżĹĹĹĂĂĂÇÇÇÇÇÇĆĆĆĂĂĂŔŔŔľľľĽĽĽ»»»şşşĽĽĽÂÂÂĽĽĽŔŔŔĐĐĐĚĚĚĘĘĘĆĆĆÂÂÂĐĐĐßßßŰŰŰÔÔÔŃŃŃÍÍÍĐĐĐŇŇŇŐŐŐŘŘŘ×××ÔÔÔĐĐĐĚĚĚĚĚĚĘĘĘĘĘĘÉÉÉĹĹĹľľľ´´´¬¬¬ŞŞŞŞŞŞ¬¬¬¬¬¬©©©¨¨¨¨¨¨ŞŞŞ©©©¨¨¨¦¦¦¨¨¨¬¬¬ŻŻŻ±±±±±±şşş´´´···ĽĽĽľľľĹĹĹÇÇÇÂÂÂżżżÂÂÂÉÉÉÎÎÎĐĐĐĚĚĚĂĂĂĽĽĽľľľľľľĽĽĽĽĽĽĽĽĽĽĽĽľľľľľľĆĆĆĐĐĐĆĆĆĆĆĆĹĹĹ···¸¸¸ŔŔŔĹĹĹŔŔŔľľľżżżŔŔŔĽĽĽłłłŞŞŞĘĘĘĐĐĐĹĹĹÇÇÇÍÍÍÇÇÇÉÉÉÇÇÇĆĆĆĹĹĹĂĂĂŔŔŔľľľĽĽĽ»»»»»»µµµ»»»»»»şşşÂÂÂÎÎÎĚĚĚŔŔŔĂĂĂÂÂÂĂĂĂĹĹĹÇÇÇĘĘĘĚĚĚĚĚĚĘĘĘÉÉÉĐĐĐ×××ŐŐŐÔÔÔÔÔÔŃŃŃÇÇǸ¸¸ŻŻŻ±±±···¸¸¸······˘˘˘¨¨¨łłłĽĽĽżżżľľľŔŔŔÇÇÇĽĽĽŔŔŔÂÂÂÂÂÂÂÂÂÇÇÇĐĐĐŮŮŮÝÝÝäääâââŕŕŕęęęíííçççäääăăăßßßÝÝÝŕŕŕâââÝÝÝ×××ĐĐĐŘŘŘÝÝÝŮŮŮŰŰŰÎÎλ»»şşş¸¸¸ÂÂÂĆĆĆĆĆĆĂĂĂĂĂĂÉÉÉÎÎÎĐĐĐĐĐĐÎÎÎĚĚĚÉÉÉÇÇÇÇÇÇÇÇÇÇÇÇĆĆĆĘĘĘÎÎÎŇŇŇŐŐŐŐŐŐÔÔÔŇŇŇŇŇŇĐĐĐÍÍÍÉÉÉŔŔŔĆĆĆÜÜÜňňňňňňíííîîîîîîíííňňňńńńęęęňňňńńńďďďďďďîîîíííëëëęęęŕŕŕÜÜÜ×××ŇŇŇŃŃŃŃŃŃŇŇŇŐŐŐŃŃŃÜÜÜăăăßßßŮŮŮŘŘŘŐŐŐŇŇŇÎÎÎŇŇŇŃŃŃŃŃŃĘĘĘŔŔŔŔŔŔÂÂÂÇÇÇĹĹĹÂÂÂżżżĽĽĽ»»»»»»ĽĽĽżżżĽĽĽĂĂĂżżżĽĽĽżżżÂÂÂĐĐĐĐĐĐĂĂĂĂĂĂĐĐĐŰŰŰŕŕŕßßßŮŮŮĐĐĐŐŐŐŮŮŮŮŮŮŃŃŃĹĹŸ¸¸łłłłłł°°°ŻŻŻ±±±µµµ···µµµ´´´»»»¸¸¸µµµµµµłłł±±±´´´şşşµµµ´´´łłłµµµşşşľľľŔŔŔ°°°µµµĹĹĹĘĘĘÂÂÂŔŔŔĹĹĹĹĹĹĚĚĚĚĚĚĚĚĚÎÎÎĐĐĐĐĐĐÍÍÍĘĘĘŇŇŇÔÔÔ×××ŘŘŘŐŐŐĐĐĐĘĘĘĆĆĆĂĂĂĚĚĚĆĆĆÉÉÉĆĆĆĽĽĽĹĹĹĚĚĚÉÉÉÂÂÂľľľŔŔŔĹĹĹĂĂø¸¸­­­ĚĚĚŃŃŃÇÇÇĘĘĘÎÎÎÉÉÉĘĘĘÉÉÉĆĆĆĆĆĆĂĂĂÂÂÂżżżľľľĽĽĽ»»»şşşľľľżżżŔŔŔÇÇÇĐĐĐÎÎÎĹĹĹĹĹĹĂĂĂĂĂĂĂĂĂĹĹĹĆĆĆÇÇÇÇÇÇĚĚĚĂĂĂĂĂĂĚĚĚŐŐŐŮŮŮÔÔÔĚĚĚÎÎÎĽĽĽŞŞŞ©©©±±±¸¸¸¸¸¸···ťťť¤¤¤±±±ľľľÂÂÂżżżľľľŔŔŔŔŔŔĆĆĆĹĹĹŔŔŔŔŔŔÂÂÂÉÉÉÔÔÔßßßäääŕŕŕÜÜÜâââçççčččëëëäääęęęčččŕŕŕÜÜÜÝÝÝßßßÝÝÝŰŰŰÜÜÜŮŮŮăăăâââŮŮŮâââćććâââäääÝÝÝĚĚĚŔŔŔÂÂÂÇÇÇÇÇÇĘĘĘÉÉÉÉÉÉÇÇÇĆĆĆĆĆĆĆĆĆĆĆĆÇÇÇĘĘĘÎÎÎŇŇŇÔÔÔÔÔÔŇŇŇŇŇŇÎÎÎÎÎÎŃŃŃĚĚĚĂĂĂĚĚĚâââďďďîîîçççíííďďďňňňóóóíííëëëďďďďďďíííëëëčččçççččččččâââßßßŰŰŰ×××ÔÔÔŃŃŃĐĐĐĐĐĐĘĘĘÔÔÔÝÝÝÝÝÝŘŘŘŇŇŇÎÎÎÍÍÍÎÎÎĐĐĐŇŇŇĘĘĘĹĹĹĹĹĹÂÂÂĹĹĹĂĂĂÂÂÂżżżľľľ»»»şşşşşşşşşÂÂÂľľľĆĆĆĂĂĂľľľ»»»şşşĆĆĆĐĐĐĘĘĘĂĂĂĆĆĆŇŇŇŮŮŮŰŰŰÝÝÝŰŰŰÝÝÝÝÝÝŐŐŐÉÉÉľľľ¸¸¸···ľľľşşş´´´µµµşşşżżżŔŔŔŔŔŔ»»»¸¸¸···¸¸¸µµµ±±±łłł¸¸¸···µµµ´´´´´´·········µµµµµµżżżĘĘĘÉÉÉÂÂÂÇÇÇÍÍÍÇÇÇĐĐĐĚĚĚÇÇÇĹĹĹĆĆĆÇÇÇÉÉÉÉÉÉĘĘĘĚĚĚÎÎÎĐĐĐÎÎÎĚĚĚÇÇÇĹĹĹĹĹĹÉÉÉÉÉÉÍÍÍĹĹĹľľľÍÍÍŇŇŇÎÎÎÇÇÇĂĂĂĹĹĹÇÇÇĆĆĆżżż···ÍÍÍÔÔÔĘĘĘĚĚĚŃŃŃĘĘĘĘĘĘÉÉÉÇÇÇĆĆĆĹĹĹĂĂĂŔŔŔżżżĽĽĽ»»»żżżŔŔŔĹĹĹÉÉÉÎÎÎŃŃŃÎÎÎÉÉÉÂÂÂÂÂÂĂĂĂĂĂĂĂĂĂĂĂĂĹĹĹĆĆĆÇÇÇĂĂĂżżżÂÂÂĚĚĚÔÔÔŇŇŇÍÍÍĐĐĐĂĂĂ´´´¬¬¬±±±şşşşşş´´´¤¤¤¨¨¨±±±ĽĽĽŔŔŔĽĽĽşşş»»»ľľľĆĆĆĆĆĆĂĂĂĹĹĹÂÂÂĹĹĹÎÎÎŰŰŰăăăâââŰŰŰßßßäääčččďďďęęęîîîíííăăăÜÜÜŰŰŰŰŰŰŰŰŰßßßŕŕŕŰŰŰŕŕŕŕŕŕßßßçççççççççíííëëëßßßÎÎÎÇÇÇÉÉÉÍÍÍÉÉÉÉÉÉÉÉÉÉÉÉÇÇÇĆĆĆĹĹĹĹĹĹÇÇÇĘĘĘÍÍÍÎÎÎĐĐĐÎÎÎÍÍÍÍÍÍÉÉÉÇÇÇĘĘĘĆĆĆĹĹĹ×××çççčččëëëęęęóóóďďďďďďňňňëëëďďďîîîíííëëëčččćććăăăääääääăăăâââßßßÜÜÜŘŘŘŇŇŇÎÎÎĚĚĚĚĚĚŐŐŐŕŕŕäääßßßŐŐŐĐĐĐÎÎÎÎÎÎÍÍÍŇŇŇĹĹĹŔŔŔÉÉÉĹĹĹÉÉÉŔŔŔŔŔŔżżżľľľ»»»şşş······¸¸¸»»»ĆĆĆĹĹĹÇÇÇÍÍÍŔŔŔ»»»ÎÎÎ×××ŃŃŃÇÇÇĆĆĆĂĂĂĹĹĹĐĐĐŰŰŰŮŮŮŃŃŃĹĹŸ¸¸µµµľľľĆĆĆÂÂÂĽĽĽ······»»»żżżżżżľľľşşşşşşĽĽĽÂÂÂżżż···´´´···µµµµµµ···şşş»»»»»»¸¸¸µµµĆĆĆÇÇÇĹĹĹĽĽĽżżżŇŇŇŘŘŘÇÇÇŐŐŐ×××ŮŮŮÜÜÜÜÜÜ×××ĐĐĐĘĘĘÎÎÎÍÍÍÍÍÍÎÎÎĐĐĐŇŇŇ×××ŘŘŘÉÉÉĘĘĘÍÍÍŃŃŃÂÂÂĽĽĽĐĐĐŇŇŇŃŃŃÍÍÍĘĘĘÇÇÇÇÇÇĆĆĆĂĂĂżżżÎÎÎŐŐŐĘĘĘÍÍÍŇŇŇĚĚĚĚĚĚÉÉÉÇÇÇÇÇÇĆĆĆĹĹĹÂÂÂżżżľľľĽĽĽ»»»ĽĽĽÂÂÂĚĚĚŃŃŃŇŇŇŃŃŃŃŃŃŔŔŔÂÂÂĹĹĹĹĹĹĹĹĹĂĂĂĹĹĹĆĆĆżżżĆĆĆĹĹĹżżżżżżÇÇÇĐĐĐÔÔÔÉÉÉÎÎÎĘĘĘĽĽĽ±±±łłł¸¸¸»»»¤¤¤ĄĄĄ­­­¸¸¸żżżżżżżżżŔŔŔ´´´ŔŔŔĹĹĹĆĆĆĘĘĘĆĆĆĂĂĂĘĘĘŇŇŇŕŕŕăăăŕŕŕâââäääćććíííäääăăăăăăăăăăăăâââßßßÜÜÜÜÜÜäääÝÝÝÝÝÝŕŕŕăăăčččßßßŕŕŕçççńńńďďďßßßĚĚĚĆĆĆÍÍÍĚĚĚĚĚĚĚĚĚĘĘĘÉÉÉĆĆĆĹĹĹĂĂĂÉÉÉĘĘĘĚĚĚĚĚĚĚĚĚĘĘĘÉÉÉÇÇÇĹĹĹŔŔŔľľľ»»»ĂĂĂÝÝÝîîîçççíííńńńřřřčččŕŕŕçççäääíííóóóâââęęęćććŕŕŕčččäääŕŕŕÝÝÝßßßŰŰŰăăăÝÝÝÎÎÎĐĐĐĐĐĐĂĂĂŮŮŮßßßŮŮŮŮŮŮ×××ÎÎÎĘĘĘĘĘĘÔÔÔÔÔÔĆĆĆżżżĹĹĹÉÉÉĹĹĹľľľ»»»şşş¸¸¸······¸¸¸»»»±±±¸¸¸ÂÂÂĘĘĘÎÎÎĚĚĚĆĆĆÂÂÂľľľÇÇÇŃŃŃŐŐŐŃŃŃĚĚĚÉÉÉÉÉɸ¸¸µµµµµµşşşľľľżżżżżżżżżşşş¸¸¸¸¸¸şşşľľľŔŔŔżżżľľľŔŔŔ¸¸¸¸¸¸żżżżżż···±±±´´´´´´µµµµµµłłł°°°łłł»»»ÂÂÂĂĂĂÇÇÇĚĚĚĂĂĂÂÂÂÉÉÉĚĚĚÎÎÎ×××ŇŇŇ×××ŰŰŰŃŃŃÎÎÎŐŐŐŘŘŘŕŕŕÝÝÝÝÝÝŇŇŇĆĆĆĚĚĚŘŘŘŘŘŘŮŮŮĐĐĐĚĚĚÉÉÉÇÇÇÍÍÍŇŇŇĐĐĐÔÔÔŇŇŇĆĆĆÉÉÉĚĚĚÉÉÉĚĚĚĂĂĂĐĐĐŘŘŘÝÝÝÔÔÔÉÉÉĐĐĐŇŇŇÉÉÉÇÇÇÉÉÉÉÉÉĹĹĹŔŔŔľľľľľľżżżľľľÂÂÂÍÍÍ×××ĐĐĐŔŔŔĽĽĽĂĂĂĹĹĹĹĹĹĹĹĹĂĂĂÂÂÂŔŔŔŔŔŔżżżżżżľľľľľľĽĽĽľľľżżżÂÂÂÂÂÂĐĐĐŇŇŇÎÎÎÉÉÉĹĹĹşşş´´´ĽĽĽµµµ´´´©©©´´´ÂÂÂżżżŔŔŔŔŔŔĽĽĽĽĽĽĐĐĐĂĂĂÂÂÂÍÍÍŔŔŔĆĆĆÍÍÍÔÔÔŰŰŰÝÝÝßßßâââçççíííóóóîîîçççâââßßßßßßŕŕŕŕŕŕßßßßßßßßßÝÝÝÝÝÝßßßăăăçççčččçççíííîîîŕŕŕĚĚĚÇÇÇŃŃŃÎÎÎĚĚĚÇÇÇĹĹĹĹĹĹĆĆĆĹĹĹÂÂÂÇÇÇĘĘĘÉÉÉĂĂĂÂÂÂĹĹĹĹĹĹŔŔŔĂĂĂşşşÇÇÇĹĹĹÝÝÝčččęęęęęęńńńëëëäääâââăăăçççëëëîîîëëëçççíííëëëçççčččäääâââÝÝÝßßßŘŘŘŰŰŰŘŘŘÎÎÎĐĐĐĘĘĘĚĚĚÜÜÜâââÝÝÝŕŕŕßßßŐŐŐĐĐĐĚĚĚŇŇŇĐĐĐĆĆĆŔŔŔĹĹĹĆĆĆŔŔŔ­­­±±±´´´´´´±±±ŻŻŻŞŞŞ¦¦¦±±±···ŔŔŔÉÉÉÎÎÎÎÎÎĚĚĚÉÉÉĂĂĂĂĂĂÂÂÂżżżľľľŔŔŔĆĆĆĚĚĚĂĂĂÉÉÉÉÉÉĹĹĹĂĂĂĆĆĆĂĂĂĽĽĽÂÂÂŔŔŔŔŔŔÂÂÂĂĂĂŔŔŔĽĽĽşşşŔŔŔ···´´´şşş»»»···¸¸¸ľľľžžžžžžˇˇˇ©©©´´´ľľľŔŔŔÂÂÂľľľĂĂĂÇÇÇÇÇÇÇÇÇÎÎÎÔÔÔŘŘŘăăăŮŮŮŮŮŮŮŮŮÔÔÔÔÔÔÝÝÝâââÜÜÜŰŰŰÝÝÝŰŰŰŇŇŇ×××ŮŮŮŃŃŃŰŰŰŘŘŘŮŮŮŘŘŘÎÎÎĘĘĘĘĘĘĂĂĂ»»»ÂÂÂÂÂÂĚĚĚĐĐĐÍÍÍĐĐĐĘĘĘĹĹĹÎÎÎÝÝÝÝÝÝĐĐĐĐĐĐŇŇŇÉÉÉÉÉÉÉÉÉÉÉÉĆĆĆÂÂÂżżżżżżżżżŔŔŔÂÂÂÉÉÉŃŃŃĚĚĚŔŔŔżżżĆĆĆĹĹĹĹĹĹĂĂĂÂÂÂÂÂÂŔŔŔżżżżżżľľľľľľĽĽĽ»»»ĽĽĽľľľżżżŔŔŔŔŔŔÇÇÇĘĘĘÍÍÍĚĚĚżżżµµµ¸¸¸»»»¸¸¸ŞŞŞłłłÂÂÂŔŔŔÂÂÂŔŔŔĹĹĹŔŔŔĐĐĐĆĆĆĂĂĂĘĘĘľľľĹĹĹĂĂĂŃŃŃßßßŕŕŕŰŰŰŘŘŘÝÝÝäääŮŮŮÝÝÝäääçççćććâââßßßÝÝÝßßßßßßßßßÝÝÝÝÝÝßßßăăăćććîîîëëëíííîîîăăăŃŃŃÇÇÇĆĆĆŇŇŇĚĚĚĆĆĆĹĹĹŔŔŔľľľĂĂĂĚĚĚĹĹĹÇÇÇĆĆĆÂÂÂÂÂÂĹĹĹÂÂÂľľľÇÇÇĂĂĂŘŘŘŰŰŰçççăăăäääëëëňňňîîîçççăăăăăăäääćććçççăăăîîîďďďďďďëëëÝÝÝŘŘŘ×××ÝÝÝăăăŰŰŰŰŰŰŘŘŘÔÔÔŐŐŐĚĚĚĚĚĚ×××ŮŮŮ×××ŰŰŰÜÜÜŇŇŇÉÉÉÍÍÍÎÎÎĘĘĘĂĂĂÂÂÂĹĹĹŔŔŔşşş···ŔŔŔÉÉÉÉÉÉĆĆĆĂĂø¸¸¬¬¬°°°µµµżżżÇÇÇÎÎÎĐĐĐŃŃŃĐĐĐĐĐĐÎÎÎĚĚĚÇÇÇĹĹĹĂĂĂÂÂÂĂĂĂÂÂÂĚĚĚĚĚĚŔŔŔ»»»ŔŔŔÂÂÂľľľľľľľľľżżżŔŔŔÂÂÂÂÂÂżżżĽĽĽşşş±±±¬¬¬­­­¬¬¬¦¦¦ĄĄĄ©©©ŻŻŻŻŻŻłłłşşşŔŔŔĹĹĹÂÂÂľľľÉÉÉĚĚĚÎÎÎŇŇŇŃŃŃĐĐĐŐŐŐŰŰŰÝÝÝŐŐŐŰŰŰÜÜÜÜÜÜŘŘŘÜÜÜ×××ÜÜÜŰŰŰÝÝÝßßßÝÝÝßßßÝÝÝÔÔÔŐŐŐŮŮŮäääćććŰŰŰ×××ŮŮŮ×××ÍÍÍĚĚĚÂÂÂĘĘĘŇŇŇŇŇŇŃŃŃÇÇÇĆĆĆĆĆĆŮŮŮâââÔÔÔŇŇŇŐŐŐĘĘĘĘĘĘĘĘĘĘĘĘÇÇÇĂĂĂŔŔŔŔŔŔŔŔŔĹĹĹÂÂÂĂĂĂÉÉÉĆĆĆŔŔŔÂÂÂÉÉÉĹĹĹĂĂĂĂĂĂÂÂÂŔŔŔżżżżżżľľľĽĽĽ»»»şşşşşşşşş»»»ĽĽĽľľľşşşŔŔŔĆĆĆÍÍÍĐĐеµµµµµŔŔŔĽĽĽŞŞŞ±±±ŔŔŔÂÂÂĹĹĹĂĂĂÉÉÉÂÂÂÍÍÍÇÇÇĆĆĆÇÇÇĽĽĽĹĹĹżżżĚĚĚŮŮŮŕŕŕßßßŰŰŰÜÜÜŕŕŕßßßäääčččęęęçççăăăăăăăăăŕŕŕŕŕŕŕŕŕßßßÝÝÝßßßăăăçççîîîíííííííííčččÝÝÝĐĐĐĂĂĂÎÎÎÇÇÇĘĘĘŐŐŐŐŐŐÇÇÇŔŔŔÂÂÂĆĆĆĹĹĹŔŔŔľľľżżżĂĂĂĂĂĂŔŔŔ»»»ÂÂÂŕŕŕíííńńńäääçççőőőîîîęęęćććăăăăăăääääääăăăßßßöööďďďëëëćććĚĚĚÂÂÂĂĂĂĐĐĐŕŕŕŕŕŕÝÝÝŘŘŘŐŐŐŘŘŘÎÎÎ×××ŰŰŰŮŮŮŮŮŮÜÜÜÝÝÝÔÔÔÉÉÉÎÎÎĘĘĘĹĹĹÂÂÂĂĂĂÂÂÂĽĽĽµµµŻŻŻ»»»ĂĂõµµĄĄĄ±±±¸¸¸ÂÂÂĘĘĘĐĐĐŇŇŇŇŇŇŇŇŇ××××××ŘŘŘŮŮŮ×××ĐĐĐÇÇÇŔŔŔľľľÂÂÂŔŔŔµµµ°°°···ÂÂÂÇÇÇĽĽĽľľľŔŔŔŔŔŔľľľ···°°°¬¬¬µµµ±±±łłł······°°°­­­ŻŻŻ±±±µµµşşşĽĽĽĽĽĽĽĽĽľľľżżżŔŔŔĹĹĹÇÇÇÔÔÔŐŐŐŇŇŇÜÜÜââââââŐŐŐŘŘŘÔÔÔŘŘŘŐŐŐÝÝÝ×××ßßßÝÝÝÝÝÝßßßßßßâââăăăâââŰŰŰÝÝÝäääâââŃŃŃĚĚĚŃŃŃŇŇŇŰŰŰŇŇŇŔŔŔĂĂĂĘĘĘÎÎÎŐŐŐĐĐĐÔÔÔĆĆĆŇŇŇßßßŐŐŐÔÔÔŘŘŘÍÍÍÍÍÍĚĚĚĘĘĘÉÉÉĆĆĆĂĂĂÂÂÂÂÂÂĹĹĹŔŔŔżżżĂĂĂĂĂĂÂÂÂĂĂĂÉÉÉĂĂĂÂÂÂÂÂÂŔŔŔżżżľľľľľľľľľ»»»şşş¸¸¸······¸¸¸şşş»»»ľľľĂĂĂĆĆĆĚĚĚÎÎεµµµµµŔŔŔĽĽĽ©©©­­­ľľľÂÂÂÇÇÇĆĆĆĆĆĆľľľĹĹĹĹĹĹĆĆĆĆĆĆżżżÇÇÇĂĂĂĹĹĹÍÍÍŰŰŰäääćććććććććííííííëëëęęęčččçççççççççăăăăăăăăăŕŕŕŕŕŕâââäääčččëëëîîîîîîííííííëëëßßßŇŇŇĘĘĘÇÇÇÎÎÎâââîîîćććŃŃŃĂĂĂĂĂĂżżżşşş···şşşżżżŔŔŔŔŔŔłłłĂĂĂßßßîîîďďďčččííířřřäääâââââââââäääçççççççççßßßřřřîîîçççŕŕŕĂĂĂ···şşş»»»×××ŕŕŕÝÝÝŐŐŐŇŇŇŮŮŮÔÔÔÝÝÝŰŰŰŮŮŮŘŘŘŘŘŘ×××ÎÎÎĂĂĂÍÍÍĆĆĆÂÂÂÂÂÂÂÂÂżżż¸¸¸´´´···ÂÂÂĆĆĆĂĂĂĆĆĆÉÉÉŔŔŔłłł´´´ĽĽĽÇÇÇĐĐĐŇŇŇŇŇŇŇŇŇŃŃŃŐŐŐÔÔÔŇŇŇÔÔÔ×××ŐŐŐŇŇŇÎÎÎĆĆĆĂĂĂŔŔŔľľľ···µµµżżżÍÍÍĆĆĆżżżµµµ­­­¬¬¬°°°¸¸¸żżżżżżľľľżżżŔŔŔżżżşşş···¸¸¸»»»şşşşşş······¸¸¸ĽĽĽżżżĽĽĽĂĂĂÂÂÂĐĐĐŇŇŇĚĚĚŮŮŮÝÝÝçççŰŰŰÝÝÝŇŇŇŘŘŘÔÔÔŕŕŕŮŮŮÝÝÝŕŕŕââââââŕŕŕŕŕŕćććîîîââââââćććŕŕŕĐĐĐĚĚĚŃŃŃÔÔÔŃŃŃÔÔÔĘĘĘĆĆĆżżż»»»ÇÇÇĚĚĚ×××ĚĚĚ×××ŕŕŕŐŐŐĐĐĐŐŐŐŃŃŃÎÎÎÍÍÍĚĚĚÉÉÉÇÇÇĆĆĆĂĂĂÂÂÂĂĂĂŔŔŔżżżÂÂÂĂĂĂĂĂĂĂĂĂĹĹĹÂÂÂÂÂÂŔŔŔżżżľľľľľľĽĽĽĽĽĽşşş¸¸¸···µµµ···¸¸¸şşş»»»ŔŔŔĆĆĆÉÉÉÍÍÍĐĐĐĂĂĂ······ľľľ»»»¨¨¨ŞŞŞ»»»ÂÂÂÇÇÇĆĆĆĹĹĹ»»»ľľľŔŔŔĂĂĂĂĂĂżżżĹĹĹĆĆĆÂÂÂĆĆĆŇŇŇÝÝÝâââçççëëëëëëčččçççęęęîîîďďďęęęäääččččččçççćććääääääčččëëëëëëňňňóóóďďďîîîńńńíííćććíííęęęććććććíííëëëŮŮŮĆĆĆŔŔŔżżżľľľżżżÂÂÂÂÂÂŔŔŔżżżĹĹĹ×××ăăăęęęčččëëëíííęęęÝÝÝÝÝÝßßßâââćććčččččččččŕŕŕóóóîîîćććŕŕŕÉÉÉşşşľľľ¸¸¸ÔÔÔßßßÝÝÝŐŐŐŐŐŐâââŕŕŕÝÝÝŘŘŘŘŘŘŐŐŐÎÎÎĚĚĚÇÇÇżżżĚĚĚĂĂĂŔŔŔÂÂÂŔŔŔşşş···¸¸¸ĽĽĽŔŔŔÂÂÂŔŔŔĂĂĂÇÇÇĂĂĂşşş¸¸¸ŔŔŔĚĚĚŇŇŇÔÔÔŇŇŇŃŃŃŃŃŃŐŐŐÔÔÔŇŇŇÔÔÔ×××ŘŘŘŐŐŐÔÔÔÎÎÎÉÉÉÉÉÉĚĚĚĂĂĂ···µµµżżż±±±µµµ»»»żżżŔŔŔÂÂÂÂÂÂĂĂĂĹĹĹÂÂÂżżż»»»µµµ±±±±±±´´´ľľľ···łłł···ĹĹĹĐĐĐŐŐŐŐŐŐÍÍÍŐŐŐĐĐĐŘŘŘ×××ÎÎÎÜÜÜÜÜÜăăăŘŘŘÜÜÜĘĘĘÎÎÎÉÉÉŮŮŮŇŇŇŮŮŮŕŕŕćććççççççăăăćććńńńÝÝÝÝÝÝăăăäääÝÝÝßßßćććäääĐĐĐ×××ŇŇŇŇŇŇĚĚĚŔŔŔÂÂÂĽĽĽĘĘĘÎÎÎÜÜÜăăăŘŘŘÎÎÎĐĐĐŇŇŇĐĐĐÍÍÍĘĘĘÉÉÉÉÉÉĆĆĆĹĹĹÂÂÂÂÂÂŔŔŔŔŔŔĂĂĂĂĂĂĂĂĂÂÂÂÂÂÂŔŔŔŔŔŔżżżľľľľľľĽĽĽ»»»»»»······µµµµµµ···¸¸¸»»»ĽĽĽżżżĆĆĆĚĚĚŃŃŃŇŇŇĹĹĹ···¸¸¸»»»ĽĽĽŞŞŞ¬¬¬şşşŔŔŔÇÇÇĹĹĹĆĆĆżżż»»»ĽĽĽŔŔŔÂÂÂżżżżżżĂĂĂÂÂÂĹĹĹĚĚĚÍÍÍÎÎÎŮŮŮčččöööďďďęęęëëëďďďňňňďďďíííîîîîîîíííëëëčččęęęîîîńńńňňňřřřřřřňňňďďďńńńňňňďďďíííóóóňňňęęęęęęńńńîîîäääćććääääääâââŘŘŘÉÉÉĽĽĽ¸¸¸ŰŰŰęęęćććęęęčččńńńîîîâââŕŕŕßßßßßßâââäääććććććäääâââëëëîîîćććŕŕŕŃŃŃľľľŔŔŔĽĽĽÎÎÎŃŃŃŃŃŃÎÎÎŃŃŃăăăćććăăăßßßŕŕŕÝÝÝŃŃŃÍÍÍÎÎÎÉÉÉÉÉÉÂÂÂżżżÂÂÂľľľ´´´µµµľľľÂÂÂÂÂÂÂÂÂĂĂĂÇÇÇÇÇÇĂĂĂĽĽĽľľľĹĹĹÎÎÎŇŇŇŇŇŇŃŃŃŇŇŇÔÔÔÔÔÔŐŐŐŘŘŘŮŮŮŰŰŰŘŘŘŐŐŐŃŃŃĐĐĐĚĚĚÍÍÍĐĐĐĘĘĘżżż¸¸¸¸¸¸żżżĂĂĂÉÉÉĘĘĘÇÇÇĂĂĂŔŔŔżżżÂÂÂÂÂÂÂÂÂľľľ»»»»»»ľľľŔŔŔĂĂĂĽĽĽ···»»»ĆĆĆĐĐĐŃŃŃĐĐĐŇŇŇŕŕŕŘŘŘßßßßßßŰŰŰíííçççęęęŮŮŮÔÔÔ±±±łłł´´´ŐŐŐŰŰŰŰŰŰŕŕŕâââćććëëëçççćććďďďäääÜÜÜÜÜÜÝÝÝŰŰŰßßßŕŕŕŰŰŰŐŐŐŇŇŇÉÉÉĐĐĐ×××ÔÔÔŃŃŃĹĹĹŔŔŔĘĘĘŇŇŇŮŮŮÝÝÝŘŘŘĐĐĐŃŃŃĐĐĐÍÍÍĘĘĘÉÉÉÉÉÉÇÇÇĹĹĹÂÂÂÂÂÂĂĂĂĂĂĂĂĂĂÂÂÂÂÂÂÂÂÂÂÂÂŔŔŔżżżżżżľľľĽĽĽ»»»»»»şşş···µµµµµµµµµ¸¸¸şşşĽĽĽľľľĆĆĆĚĚĚÎÎÎĐĐĐÍÍÍżżż´´´¸¸¸»»»ŔŔŔ±±±±±±»»»żżżĹĹĹÂÂÂĹĹĹŔŔŔşşşşşşżżżĹĹĹĹĹĹľľľÂÂÂżżżÂÂÂÇÇÇĆĆĆĂĂĂÎÎÎÝÝÝöööóóóńńńďďďďďďňňňőőőřřřóóóóóóňňňďďďîîîďďďňňňőőőůůůřřřöööóóóňňňňňňóóóňňňîîîóóóőőőďďďíííîîîîîîęęęçççčččíííîîîčččŕŕŕÜÜÜßßßçççńńńćććďďďëëëńńńíííŕŕŕâââŕŕŕŕŕŕâââäääćććäääăăăăăăćććîîîćććßßßÔÔÔĽĽĽľľľşşşŔŔŔ»»»»»»ľľľĆĆĆŮŮŮÝÝÝßßßÜÜÜßßßÜÜÜÍÍÍÉÉÉÍÍÍĘĘĘÇÇÇŔŔŔŔŔŔÂÂÂĽĽĽ±±±µµµŔŔŔżżżĽĽĽĽĽĽÂÂÂĹĹĹ»»»µµµŔŔŔÇÇÇÎÎÎŇŇŇŃŃŃŃŃŃÔÔÔ×××ÍÍÍÍÍÍĐĐĐŃŃŃÔÔÔ××××××ŘŘŘĐĐĐĐĐĐÎÎÎÎÎÎĐĐĐÎÎÎÇÇÇÂÂÂÇÇÇĘĘĘĘĘĘÉÉÉĹĹĹĂĂĂĂĂĂĹĹĹÇÇÇĘĘĘĘĘĘÇÇÇÂÂÂľľľ»»»şşş¸¸¸şşşĽĽĽÂÂÂÉÉÉĐĐĐŐŐŐŘŘŘŘŘŘçççŰŰŰÜÜÜŮŮŮŐŐŐćććÜÜÜëëëÜÜÜŘŘر±±°°°°°°×××ÝÝÝââââââÜÜÜŕŕŕëëëčččçççńńńňňňăăăŰŰŰŮŮŮŰŰŰŕŕŕâââŮŮŮâââŰŰŰÇÇÇĆĆĆÉÉÉÉÉÉÎÎÎÉÉÉÂÂÂĹĹĹŔŔŔĘĘĘâââäääÔÔÔÍÍÍĐĐĐÍÍÍĘĘĘÉÉÉÉÉÉÇÇÇĹĹĹÂÂÂĂĂĂĹĹĹĹĹĹĂĂĂÂÂÂŔŔŔÂÂÂÂÂÂżżżżżżľľľľľľĽĽĽ»»»şşşşşşµµµµµµµµµ···¸¸¸»»»ľľľŔŔŔŇŇŇÔÔÔĐĐĐÉÉÉĂĂĂ···±±±¸¸¸ĽĽĽĹĹŸ¸¸µµµĽĽĽľľľĂĂĂŔŔŔŔŔŔżżż¸¸¸¸¸¸ŔŔŔĘĘĘĚĚĚĂĂĂĂĂĂĽĽĽĽĽĽĆĆĆÉÉÉÇÇÇĚĚĚŐŐŐŮŮŮăăăďďďőőőőőőóóóőőőůůůřřřřřřöööóóóńńńňňňőőőřřřůůůőőőńńńňňňőőőöööóóóňňňöööńńńëëëëëëëëëíííííííííčččććććććäääŕŕŕÜÜÜâââëëëîîîóóóćććőőőíííęęęâââŮŮŮâââŕŕŕŕŕŕâââäääććććććäääâââęęęćććčččßßßÇÇÇŔŔŔ···ľľľŔŔŔĹĹĹĂĂĂŔŔŔżżżÂÂÂĆĆĆÝÝÝßßß×××ŃŃŃŇŇŇÍÍÍÉÉÉĐĐĐżżżÂÂÂľľľ······ĽĽĽŔŔŔżżżľľľżżż»»»ĆĆĆĹĹĹÍÍÍŔŔŔ»»»ĽĽĽŔŔŔÉÉÉĐĐĐŐŐŐ×××ŐŐŐÔÔÔĐĐĐŃŃŃÔÔÔ×××ŘŘŘŘŘŘ×××ŐŐŐŐŐŐĐĐĐÍÍÍÎÎÎÔÔÔ×××ŇŇŇÍÍÍÎÎÎÍÍÍĘĘĘÇÇÇĆĆĆĹĹĹĆĆĆĆĆĆÇÇÇĆĆĆĂĂĂĂĂĂĂĂĂĂĂĂŔŔŔľľľ»»»¸¸¸ĹĹĹŐŐŐ××××××ŮŮŮŘŘŘŕŕŕäääÝÝÝäää×××ÔÔÔíííÝÝÝçççŕŕŕ×××ŔŔŔ¬¬¬łłłŇŇŇçççÜÜÜćććäääăăăčččćććäääíííăăăîîîíííßßßŮŮŮÝÝÝßßßÜÜÜŘŘŘŰŰŰÜÜÜŮŮŮÔÔÔÍÍÍÉÉÉÇÇÇÇÇÇÉÉÉĹĹĹĐĐĐŇŇŇęęęăăăŇŇŇŃŃŃÎÎÎÍÍÍĚĚĚĘĘĘÇÇÇÇÇÇÉÉÉĹĹĹĂĂĂÂÂÂÂÂÂŔŔŔŔŔŔŔŔŔŔŔŔŔŔŔżżżĽĽĽ»»»şşşşşş¸¸¸¸¸¸şşş¸¸¸¸¸¸µµµµµµ»»»ĹĹĹÍÍÍĚĚĚĚĚĚÍÍÍĘĘĘŔŔŔµµµłłłµµµ¸¸¸żżż¸¸¸±±±şşşŔŔŔľľľĽĽĽĽĽĽĽĽĽ»»»łłłŻŻŻżżżÉÉÉżżżŔŔŔĂĂĂĆĆĆĆĆĆÇÇÇÇÇÇĘĘĘĚĚĚŐŐŐ×××ÝÝÝęęęöööúúúőőőîîîîîîřřřüüüőőőîîîďďďöööúúúňňňňňňňňňňňňóóóőőőööööööóóóňňňďďďîîîíííííííííîîîăăăâââăăăćććäääßßßâââçççîîîďďďńńńîîîčččăăăßßßßßßŕŕŕ×××ŰŰŰăăăâââăăăćććâââíííîîîăăăÝÝÝĚĚ̵µµµµµ±±±ľľľŔŔŔĂĂĂĆĆĆÉÉÉÉÉÉĆĆĆĹĹĹŐŐŐŮŮŮŐŐŐÔÔÔŘŘŘŇŇŇĚĚĚÎÎÎĂĂĂĂĂĂľľľ¸¸¸¸¸¸ľľľŔŔŔľľľŔŔŔÂÂÂżżżÇÇÇĂĂĂÇÇÇĽĽĽ¸¸¸ľľľÂÂÂĘĘĘŃŃŃ×××ŘŘŘŘŘŘ×××××××××ŐŐŐ××××××ŐŐŐÔÔÔŇŇŇÔÔÔŐŐŐ××××××ŐŐŐÔÔÔÔÔÔÔÔÔĚĚĚÍÍÍÍÍÍÍÍÍÍÍÍĘĘĘÉÉÉĆĆĆĹĹĹĆĆĆĆĆĆĹĹĹĂĂĂÂÂÂÂÂÂĂĂĂŔŔŔżżżÇÇÇÎÎÎĚĚĚŃŃŃÜÜÜŕŕŕŕŕŕäääÝÝÝâââŐŐŐ×××íííÜÜÜîîîčččăăăŇŇŇżżżŔŔŔŐŐŐâââŕŕŕâââŘŘŘŃŃŃÜÜÜëëëńńńďďďńńńńńńďďďíííćććÜÜÜ×××ŐŐŐŐŐŐŘŘŘŰŰŰŰŰŰŘŘŘŇŇŇĚĚĚÉÉÉŃŃŃÇÇÇÂÂÂŃŃŃĚĚĚŘŘŘŘŘŘŰŰŰâââÝÝÝŐŐŐĚĚĚÉÉÉĘĘĘÉÉÉĹĹĹÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂżżżżżżĽĽĽ»»»şşşşşş¸¸¸¸¸¸···¸¸¸şşş»»»ĽĽĽÂÂÂĘĘĘŇŇŇÍÍÍÎÎÎÎÎÎĘĘĘżżżµµµşşşÂ¸¸¸łłłĽĽĽÂÂÂżżżÂÂÂżżż···´´´łłł¸¸¸ĆĆĆÉÉÉ»»»ŔŔŔĂĂĂĆĆĆÇÇÇĆĆĆÇÇÇÉÉÉĘĘĘÍÍÍĐĐĐ×××ßßßçççďďďőőőřřřďďďöööřřřóóóďďďńńńóóóóóóďďďďďďďďďďďďńńńóóóőőőöööóóóňňňďďďíííëëëëëëíííîîîčččććććććçççćććăăăćććëëëöööóóóîîîçççăăăŕŕŕŕŕŕâââăăăŰŰŰßßßćććăăăăăăăăăŕŕŕëëëăăăŇŇŇÉÉɸ¸¸¬¬¬´´´şşşżżżżżżĂĂĂĘĘĘŃŃŃŃŃŃĘĘĘĹĹĹÇÇÇÍÍÍÎÎÎĐĐĐ×××ŐŐŐÍÍÍĘĘĘĹĹĹĂĂĂľľľ»»»»»»żżżľľľ»»»żżżÂÂÂŔŔŔÇÇÇÂÂÂÂÂÂşşşşşşŔŔŔĆĆĆÍÍÍŇŇŇ×××ŮŮŮŮŮŮŮŮŮŮŮŮ×××ŐŐŐÔÔÔŐŐŐŐŐŐÔÔÔŃŃŃŐŐŐŐŐŐŐŐŐÔÔÔŃŃŃŃŃŃÔÔÔ×××ĐĐĐĐĐĐĐĐĐÎÎÎĚĚĚĘĘĘÉÉÉÇÇÇĹĹĹĆĆĆÉÉÉĘĘĘÉÉÉĆĆĆÂÂÂŔŔŔżżżÉÉÉŘŘŘÝÝÝ×××ŮŮŮŕŕŕŕŕŕßßßäääÝÝÝÝÝÝŐŐŐŰŰŰíííŰŰŰęęęçççčččăăă××××××ßßßâââçççŇŇŇľľľ···ÂÂÂŘŘŘćććăăăäääçççďďďóóóíííäääßßßÝÝÝŐŐŐÔÔÔŐŐŐŘŘŘŰŰŰŘŘŘŇŇŇĚĚĚĂĂĂĹĹĹĆĆĆŃŃŃĹĹĹĚĚĚĘĘĘĘĘĘÝÝÝŕŕŕÜÜÜŃŃŃĚĚĚĚĚĚĘĘĘĂĂĂĹĹĹĹĹĹĹĹĹĹĹĹĹĹĹĂĂĂÂÂÂÂÂÂżżżľľľĽĽĽ»»»şşşşşşşşşşşşµµµşşşĽĽĽĽĽĽľľľĂĂĂĚĚĚŃŃŃĚĚĚÉÉÉĹĹĹĽĽĽ±±±¬¬¬µµµĂĂĂ»»»łłłµµµľľľľľľ»»»ľľľĽĽĽłłł±±±¸¸¸ŔŔŔÉÉÉÇÇÇľľľŔŔŔĂĂĂĆĆĆÇÇÇĆĆĆĆĆĆĆĆĆÇÇÇÇÇÇĚĚĚĐĐĐŃŃŃÔÔÔÝÝÝíííůůůďďďóóóőőőńńńďďďďďďîîîëëëëëëëëëëëëíííîîîńńńňňňóóóőőőňňňîîîëëëęęęęęęíííîîîîîîëëëęęęęęęčččçççęęęîîîóóóďďďęęęćććăăăăăăăăăăăăçççŕŕŕăăăčččçççăăăâââßßßäääĐĐĐżżżşşş±±±°°°şşşżżżľľľŔŔŔĆĆĆÍÍÍŃŃŃĐĐĐĘĘĘĹĹĹľľľŔŔŔÂÂÂĹĹĹÍÍÍŃŃŃÍÍÍĆĆĆÂÂÂżżżĽĽĽĽĽĽżżżŔŔŔ»»»µµµşşşĽĽĽÂÂÂÇÇÇÂÂÂľľľ»»»ľľľĆĆĆĘĘĘĐĐĐŐŐŐŘŘŘŘŘŘŘŘŘŮŮŮÔÔÔŃŃŃĐĐĐŃŃŃÔÔÔŐŐŐÔÔÔŃŃŃĐĐĐĐĐĐŃŃŃ×××ÜÜÜŰŰŰÔÔÔÍÍÍŇŇŇĐĐĐĚĚĚÉÉÉÉÉÉĚĚĚĐĐĐŇŇŇŃŃŃÍÍÍÉÉÉÇÇÇÇÇÇĆĆĆÂÂÂżżżľľľĘĘĘÝÝÝăăăÝÝÝßßßŕŕŕŘŘŘÝÝÝăăăÝÝÝŮŮŮŐŐŐÝÝÝëëëŰŰŰćććăăăčččęęęââââââäääŕŕŕÜÜÜżżżµµµŔŔŔĹĹĹĆĆĆÇÇÇĂĂĂÇÇÇŘŘŘęęęîîîčččëëëîîîçççŮŮŮÔÔÔĐĐĐŃŃŃŘŘŘŰŰŰ×××ŇŇŇĚĚĚĚĚĚÇÇÇĚĚĚľľľÇÇÇĘĘĘÍÍÍĹĹĹÎÎÎ×××ŘŘŘÔÔÔÍÍÍÉÉÉÇÇÇĘĘĘĘĘĘĘĘĘÉÉÉĆĆĆĂĂĂÂÂÂŔŔŔżżżľľľĽĽĽ»»»şşşşşşşşşşşş¸¸¸ĽĽĽĽĽĽşşş»»»ŔŔŔĆĆĆÉÉÉĘĘĘ···ŻŻŻ¦¦¦¦¦¦±±±żżżżżż´´´°°°şşşĂĂĂżżż¸¸¸şşşµµµ±±±µµµżżżĹĹĹĹĹĹĂĂĂĹĹĹŔŔŔĂĂĂĆĆĆÇÇÇĆĆĆĹĹĹĹĹĹĆĆĆÇÇÇĘĘĘĘĘĘÉÉÉÇÇÇÎÎÎÜÜÜčččëëëďďďňňňńńńíííęęęççççççççççççčččęęęëëëîîîńńńňňňőőőňňňíííęęęčččęęęíííîîîńńńďďďííííííëëëęęęëëëíííćććććććććčččęęęęęęćććâââçççăăăćććęęęčččäääââââââćććĆĆĆ···µµµłłł´´´······ĽĽĽÂÂÂÉÉÉÍÍÍĚĚĚÉÉÉÇÇÇÇÇÇĽĽĽĽĽĽ»»»»»»ÂÂÂĚĚĚÎÎÎÉÉÉĽĽĽşşş»»»żżżÂÂÂżżż¸¸¸łłł¸¸¸»»»ĂĂĂĆĆĆĂĂø¸¸şşşľľľÇÇÇÍÍÍÔÔÔ××××××ŐŐŐŐŐŐŐŐŐÎÎÎÍÍÍÍÍÍĐĐĐŃŃŃŇŇŇŃŃŃÎÎÎĘĘĘŃŃŃßßßëëëďďďčččŰŰŰĐĐĐŃŃŃĐĐĐÎÎÎÎÎÎŃŃŃ×××ÜÜÜŕŕŕßßßŮŮŮĐĐĐĆĆĆżżżżżżĂĂĂÇÇÇĆĆĆÇÇÇÎÎÎÎÎÎÍÍÍ×××ÜÜÜ×××ÜÜÜŕŕŕÜÜÜŘŘŘŐŐŐÝÝÝçççÜÜÜëëëçççęęęëëëäääăăăäääÝÝÝŰŰŰĂĂĂľľľÇÇÇÇÇÇĆĆĆÉÉÉÇÇÇÂÂÂÉÉÉŮŮŮăăăćććíííîîîăăăâââŘŘŘÎÎÎĚĚĚŇŇŇŘŘŘŰŰŰŮŮŮÜÜÜÎÎÎĆĆĆ×××ĘĘĘĚĚĚĚĚĚÔÔÔŔŔŔÂÂÂĚĚĚ×××ŮŮŮŇŇŇĘĘĘÇÇÇÉÉÉÉÉÉÇÇÇĆĆĆĂĂĂÂÂÂŔŔŔżżżľľľĽĽĽĽĽĽ»»»şşşşşş»»»»»»ĽĽĽľľľĽĽĽ¸¸¸»»»ĂĂĂĆĆĆĹĹĹÉÉÉ»»»­­­¨¨¨©©©­­­···ŔŔŔżżż°°°­­­şşşÂÂÂľľľ»»»ľľľ´´´±±±´´´żżżĆĆĆĂĂĂÂÂÂĆĆĆŔŔŔĂĂĂĆĆĆĆĆĆĆĆĆĹĹĹĹĹĹĆĆĆÉÉÉÉÉÉÇÇÇĆĆĆĆĆĆÉÉÉĐĐĐÔÔÔćććëëëńńńńńńęęęäääăăăçççääääääćććçççčččëëëîîîďďďóóóńńńíííęęęčččęęęíííďďďďďďďďďďďďîîîîîîíííęęęçççŕŕŕâââäääčččëëëčččäääßßßăăăăăăäääčččęęęäääăăăćććăăăľľľ´´´······»»»¸¸¸´´´»»»ÂÂÂÉÉÉĚĚĚÉÉÉĆĆĆĆĆĆÉÉÉĂĂĂŔŔŔľľľşşşĽĽĽĘĘĘŃŃŃĚĚĚĽĽĽ»»»ĽĽĽŔŔŔÂÂÂĽĽĽ···łłłĽĽĽĽĽĽĹĹĹĹĹĹĂĂĂłłł´´´şşşĹĹĹĚĚĚÔÔÔŘŘŘ×××ÔÔÔŃŃŃŃŃŃÍÍÍÎÎÎÍÍÍÍÍÍÍÍÍĚĚĚÍÍÍÍÍÍŘŘŘâââíííńńńďďďëëëęęęęęęÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜÜÜÜŰŰŰŰŰŰŘŘŘßßßŕŕŕŘŘŘĘĘĘÂÂÂĂĂĂÉÉÉÎÎÎÉÉÉÇÇÇĆĆĆĆĆĆŇŇŇÝÝÝÜÜÜÜÜÜÝÝÝÜÜÜŘŘŘ×××ÜÜÜâââŕŕŕęęęćććęęęëëëćććçççęęęćććÂÂÂĂĂĂÉÉÉÎÎÎŃŃŃŐŐŐŇŇŇĘĘĘÉÉÉşşşĹĹĹßßßęęęîîîíííâââčččŕŕŕŐŐŐĐĐĐŇŇŇ×××ŰŰŰÜÜÜŐŐŐÎÎÎĘĘĘ×××ÍÍÍŃŃŃĘĘĘĆĆĆŃŃŃÇÇÇĂĂĂÍÍÍŘŘŘŘŘŘĐĐĐĆĆĆĆĆĆĹĹĹĂĂĂŔŔŔżżżżżżżżżżżżľľľĽĽĽ»»»»»»şşş»»»»»»»»»żżżżżżĽĽĽşşşŔŔŔĚĚĚĘĘĘĂĂĂşşşŻŻŻĄĄĄĄĄĄŞŞŞ±±±¸¸¸ŔŔŔĽĽĽ¬¬¬¦¦¦°°°´´´µµµ¸¸¸»»»şşş´´´°°°¸¸¸ĹĹĹĹĹĹŔŔŔĂĂĂÂÂÂĂĂĂĆĆĆĆĆĆĹĹĹĹĹĹÇÇÇÉÉÉÇÇÇĆĆĆĆĆĆĆĆĆÇÇÇÉÉÉĘĘĘĘĘĘăăăçççëëëîîîęęęăăăăăăçççäääääääääćććčččęęęííííííńńńďďďíííęęęęęęíííďďďńńńďďďńńńńńńďďďîîîîîîčččăăăććććććäääăăăăăăâââßßßÝÝÝŕŕŕââââââäääçççăăăâââčččŰŰŰ···µµµ»»»¸¸¸ĽĽĽ»»»ĽĽĽşşşżżżĹĹĹĘĘĘĚĚĚĘĘĘÉÉÉÇÇÇĂĂĂĂĂĂÂÂÂĽĽĽşşşĆĆĆÎÎÎĆĆĆĹĹĹŔŔŔŔŔŔÂÂÂŔŔŔşşşµµµµµµľľľ»»»ĹĹĹĂĂĂĂĂñ±±´´´¸¸¸żżżÇÇÇŃŃŃ×××ŐŐŐŇŇŇŃŃŃĐĐĐÍÍÍÎÎÎÍÍÍĘĘĘÇÇÇÉÉÉÎÎÎÔÔÔćććččččččćććâââăăăíííóóóčččçççćććăăăßßßŮŮŮŐŐŐŇŇŇ×××ÝÝÝäääćććßßßŐŐŐÍÍÍÉÉÉÎÎÎÉÉÉĚĚĚĐĐĐĚĚĚŃŃŃÝÝÝâââÜÜÜŰŰŰŰŰŰŮŮŮŘŘŘŮŮŮÝÝÝäääßßßßßßçççëëëćććçççíííëëëľľľĆĆĆĆĆĆĂĂĂÍÍÍŐŐŐŐŐŐĐĐĐÉÉÉşşşÇÇÇăăăëëëîîîńńńçççíííčččăăăÜÜÜŘŘŘŘŘŘŘŘŘŮŮŮŘŘŘŮŮŮŃŃŃÎÎÎŔŔŔŃŃŃÎÎÎĆĆĆÎÎÎÎÎÎÇÇÇÂÂÂĚĚĚŮŮŮŘŘŘÍÍÍĐĐĐÍÍÍÉÉÉĹĹĹŔŔŔŔŔŔŔŔŔŔŔŔĽĽĽĽĽĽ»»»»»»»»»»»»»»»ĽĽĽżżżżżżĽĽĽĽĽĽĆĆĆÎÎÎÇÇǸ¸¸¬¬¬©©©¨¨¨ŞŞŞ¬¬¬­­­´´´ĽĽĽ»»»­­­ŞŞŞ±±±±±±łłł···µµµĽĽĽ»»»łłł´´´ľľľŔŔŔżżżĹĹĹĂĂĂĹĹĹĹĹĹĹĹĹĹĹĹĆĆĆĘĘĘÍÍÍĘĘĘĚĚĚĚĚĚĘĘĘÇÇÇĆĆĆÇÇÇÉÉÉäääââââââčččëëëčččääääääććććććććććććçççęęęëëëëëëîîîííííííëëëíííďďďńńńóóóňňňóóóňňňîîîîîîďďďęęęăăăçççćććăăăßßßÜÜÜÜÜÜÜÜÜßßßßßßâââŕŕŕŕŕŕäääŕŕŕßßßčččŰŰŰ···şşşĽĽĽ´´´···¸¸¸ľľľ»»»ĽĽĽŔŔŔÉÉÉĐĐĐĐĐĐĚĚĚĆĆĆŔŔŔŔŔŔĂĂĂľľľ¸¸¸ÂÂÂÉÉÉľľľÍÍÍÇÇÇĂĂĂÂÂÂľľľ···µµµ¸¸¸şşşµµµÂÂÂÂÂÂĹĹĹłłł···»»»şşşĂĂĂĐĐĐ×××ŐŐŐŇŇŇŃŃŃĐĐĐĚĚĚĚĚĚĚĚĚÇÇÇĆĆĆĘĘĘŐŐŐÝÝÝâââßßßÝÝÝÜÜÜÝÝÝßßßŕŕŕŕŕŕćććăăăŕŕŕÜÜÜŮŮŮŘŘŘŘŘŘŘŘŘćććßßßŮŮŮÝÝÝäääćććÜÜÜŃŃŃĚĚĚĆĆĆĚĚĚÎÎÎĆĆĆÉÉÉŮŮŮćććÜÜÜŘŘŘŰŰŰŰŰŰŮŮŮ×××ŰŰŰčččÜÜÜßßßčččëëëâââŕŕŕăăăâââĂĂĂĘĘĘÇÇÇĚĚĚŘŘŘŐŐŐĘĘĘĘĘĘĆĆĆÇÇÇÜÜÜęęęäääęęęňňňčččîîîîîîíííçççßßßŮŮŮ××××××ÝÝÝßßßÝÝÝâââĐĐĐÔÔÔÎÎÎĚĚĚşşşĚĚĚÍÍÍľľľŔŔŔ×××ŕŕŕ×××ßßßŰŰŰÔÔÔĚĚĚĆĆĆÂÂÂÂÂÂÂÂÂĽĽĽĽĽĽ»»»»»»»»»»»»»»»ĽĽĽżżżżżżĽĽĽĽĽĽĹĹĹĚĚĚżżżŞŞŞŻŻŻ±±±···¸¸¸łłłŻŻŻ´´´ľľľżżż···ĽĽĽĂĂĂŔŔŔľľľĽĽĽµµµ¸¸¸żżż»»»´´´···¸¸¸ľľľĘĘĘĹĹĹĹĹĹĹĹĹĂĂĂĂĂĂĆĆĆĚĚĚĐĐĐÎÎÎŃŃŃŃŃŃĚĚĚĹĹĹŔŔŔĹĹĹĘĘĘçççÝÝÝŰŰŰäääîîîîîîçççăăăççççççćććççççççčččęęęëëëííííííííííííîîîńńńňňňóóóőőőöööňňňííííííďďďíííćććâââââââââŕŕŕÜÜÜŰŰŰÜÜÜßßßßßßâââßßßÝÝÝâââÜÜÜÜÜÜčč謬¬ľľľżżżşşş»»»»»»···şşşşşşĂĂĂĘĘĘĚĚĚĚĚĚĚĚĚÉÉÉĂĂĂĆĆĆĹĹĹÇÇÇÂÂÂŔŔŔĽĽĽµµµĂĂĂÎÎÎÍÍÍÇÇÇľľľşşş»»»¸¸¸łłłłłłµµµÂÂÂĆĆĆĽĽĽ¸¸¸¸¸¸łłł¸¸¸ÂÂÂÎÎÎÔÔÔŇŇŇÎÎÎÍÍÍĚĚĚÇÇÇĐĐĐÍÍÍŔŔŔŔŔŔĐĐĐÝÝÝŕŕŕŘŘŘŮŮŮŰŰŰŰŰŰŮŮŮŮŮŮÜÜÜßßßÜÜÜâââćććäääßßßŮŮŮ×××ŘŘŘÜÜÜÝÝÝÜÜÜŮŮŮŮŮŮÝÝÝçççîîîÎÎÎÍÍÍĚĚĚĚĚĚĚĚĚÎÎÎŃŃŃŇŇŇĐĐĐÎÎÎŮŮŮÝÝÝÝÝÝŰŰŰŇŇŇŘŘŘâââčččćććçççăăăÝÝÝćććäääÂÂÂĆĆĆĘĘĘĐĐĐŃŃŃŃŃŃĐĐĐÍÍÍÇÇÇżżżççççççďďďóóóęęęîîîńńńčččŕŕŕÜÜÜÜÜÜÜÜÜŰŰŰ×××ŮŮŮ×××ÝÝÝäääŰŰŰĘĘĘÉÉÉÔÔÔŇŇŇŔŔŔÎÎÎĘĘĘşşşżżżĘĘĘ××××××ŘŘŘŮŮŮŐŐŐÉÉÉżżżĹĹĹĐĐĐĐĐĐŔŔŔµµµ···şşşşşş»»»żżżĹĹĹżżżĘĘĘĘĘĘĹĹĹĽĽĽ©©©ŞŞŞ¸¸¸···¸¸¸şşşľľľľľľşşşµµµ¸¸¸ĽĽĽŔŔŔŔŔŔĽĽĽ»»»ľľľŔŔŔŞŞŞŔŔŔľľľ´´´»»»¸¸¸´´´żżżĽĽĽ¸¸¸ŔŔŔÎÎÎŃŃŃÉÉÉÉÉÉŃŃŃĘĘĘĐĐĐŃŃŃĘĘĘĂĂĂĹĹĹĆĆĆĹĹĹÇÇÇĆĆĆ×××ćććäääćććëëëęęęčččççççççćććććććććććććććççççççćććçççëëëńńńöööúúúőőőöööřřřöööóóóńńńňňňňňňâââäääÝÝÝßßßîîîńńńíííďďďďďďîîîëëëęęęíííďďďćććŮŮŮşşş···»»»żżżľľľşşşşşş»»»ĽĽĽĹĹĹĚĚĚĘĘĘĘĘĘĘĘĘÇÇÇĂĂĂĹĹĹÂÂÂĹĹĹŔŔŔÂÂÂżżżµµµÂÂÂÂÂÂĆĆĆĆĆĆżżżşşş···´´´ŻŻŻ¸¸¸···żżżĹĹĹĂĂĂĆĆĆĆĆĆĽĽĽµµµżżżĘĘĘŃŃŃŃŃŃÎÎÎĚĚĚĚĚĚÉÉÉÉÉÉĆĆĆĹĹĹÍÍÍŮŮŮŰŰŰŐŐŐŮŮŮŰŰŰÝÝÝÜÜÜŮŮŮŮŮŮŰŰŰÝÝÝŕŕŕăăăćććăăăÝÝÝŮŮŮŮŮŮÜÜÜŮŮŮŮŮŮŘŘŘÔÔÔŇŇŇŘŘŘŕŕŕčččĚĚĚÍÍÍÎÎÎŃŃŃŃŃŃĐĐĐÍÍÍĚĚĚĐĐĐĘĘĘŇŇŇ×××ŮŮŮŮŮŮĐĐĐÔÔÔŘŘŘăăăăăăçççëëëëëëëëëÜÜÜŔŔŔĂĂĂÉÉÉÍÍÍĐĐĐÎÎÎÍÍÍĚĚĚĂĂĂĂĂĂćććçççńńńňňňîîîęęęäääŕŕŕÜÜÜŰŰŰÜÜÜÝÝÝÝÝÝŰŰŰ×××ŘŘŘŮŮŮÜÜÜŰŰŰŘŘŘŐŐŐŐŐŐÔÔÔŔŔŔĐĐĐŇŇŇľľľşşşĹĹĹ×××ÔÔÔŐŐŐŘŘŘŘŘŘŇŇŇÎÎÎĐĐĐŇŇŇĘĘĘÇÇÇĂĂĂľľľ¸¸¸¸¸¸ľľľĂĂĂĐĐĐĹĹĹĹĹĹĽĽĽ´´´±±±©©©±±±¸¸¸şşş»»»»»»şşş¸¸¸¸¸¸¸¸¸łłłµµµ······µµµµµµşşşĽĽĽŞŞŞşşşĽĽĽ»»»żżżĽĽĽşşşŔŔŔĐĐĐĹĹĹľľľĆĆĆŃŃŃŇŇŇĘĘĘÂÂÂÍÍÍŃŃŃĐĐĐÉÉÉĂĂĂĂĂĂĂĂĂÂÂÂĹĹĹĂĂĂĚĚĚ×××ÜÜÜŕŕŕçççëëëęęęčččçççćććääääääääääääććććććçççčččëëëďďďňňňőőőňňňóóóőőőőőőňňňňňňňňňóóóçççăăăÜÜÜÝÝÝçççëëëčččçççëëëíííęęęčččęęęëëëăăăŮŮŮĚĚ̵µµµµµÂÂÂżżżşşşľľľľľľÂÂÂÇÇÇĘĘĘĘĘĘÉÉÉÉÉÉÇÇÇĹĹĹĆĆĆÂÂÂĂĂĂŔŔŔĂĂĂżżżłłłşşş¸¸¸ÂÂÂÇÇÇĂĂĂ»»»µµµ±±±°°°łłł¸¸¸ÂÂÂĹĹĹÂÂÂÉÉÉÎÎÎĘĘĘ´´´ĽĽĽÇÇÇÍÍÍÎÎÎĚĚĚĘĘĘĘĘĘĆĆĆĹĹĹĆĆĆÍÍÍŘŘŘÜÜÜ×××ĐĐĐŮŮŮÜÜÜŕŕŕßßßŰŰŰŮŮŮŰŰŰßßßăăăääääääâââÜÜÜŰŰŰÝÝÝŕŕŕŰŰŰŰŰŰŘŘŘÔÔÔŃŃŃÔÔÔÝÝÝäääÎÎÎĐĐĐĐĐĐŃŃŃŃŃŃŃŃŃŃŃŃŃŃŃŃŃŃĘĘĘŃŃŃÔÔÔŮŮŮŰŰŰŃŃŃÔÔÔŮŮŮčččäääăăăčččëëëÝÝÝ»»»ľľľŔŔŔĹĹĹÉÉÉĚĚĚĚĚĚĘĘĘÉÉÉĹĹĹÎÎÎčččęęęňňňňňňőőőćććßßßÝÝÝÝÝÝßßßßßßßßßÝÝÝÝÝÝ×××ŰŰŰŮŮŮŐŐŐŰŰŰäääŕŕŕŇŇŇŘŘŘŔŔŔĚĚĚŐŐŐÇÇÇĽĽĽżżżÍÍÍÔÔÔÔÔÔŇŇŇŃŃŃŃŃŃĐĐĐĚĚĚÇÇÇÍÍÍŃŃŃĚĚĚĽĽĽ···żżżÇÇÇĘĘĘÎÎÎĂĂĂĽĽĽŻŻŻ¨¨¨©©©¬¬¬···µµµ······şşş»»»şşş···´´´łłł´´´´´´µµµ···¸¸¸ĽĽĽľľľ¸¸¸»»»ľľľŔŔŔÂÂÂżżżÂÂÂĆĆĆĆĆĆÇÇÇĆĆĆĆĆĆĘĘĘŇŇŇŇŇŇÎÎÎÇÇÇĘĘĘĘĘĘÇÇÇĆĆĆÉÉÉĘĘĘÉÉÉĹĹĹĂĂĂĂĂĂÍÍÍŮŮŮßßßŕŕŕçççęęęčččçççćććăăăăăăââââââăăăäääçççęęęíííîîîďďďďďďňňňóóóóóóóóóďďďîîîíííîîîçççßßßŰŰŰÜÜÜßßßäääçççâââčččččččččççççççćććŕŕŕŰŰŰŘŘŘŔŔŔ···ľľľżżżĽĽĽżżżÂÂÂĆĆĆÉÉÉĘĘĘÉÉÉĆĆĆĆĆĆĆĆĆĆĆĆĚĚĚĹĹĹĹĹĹŔŔŔĂĂĂĽĽĽ­­­±±±ĽĽĽĹĹĹĘĘĘĆĆĆ»»»´´´µµµ¸¸¸´´´µµµľľľÂÂÂŔŔŔÇÇÇĚĚĚĆĆƸ¸¸żżżĆĆĆĚĚĚĚĚĚĘĘĘÇÇÇÇÇÇĹĹĹÇÇÇÎÎÎ××××××ŃŃŃŃŃŃŐŐŐ×××ŰŰŰßßßßßßÜÜÜŰŰŰÝÝÝŕŕŕäääćććäääâââßßßÝÝÝŕŕŕăăăăăăâââßßßŮŮŮŐŐŐŘŘŘŕŕŕçççĐĐĐĐĐĐŃŃŃŇŇŇÔÔÔÔÔÔŐŐŐŐŐŐŇŇŇĐĐĐŮŮŮŮŮŮŰŰŰÝÝÝŐŐŐŘŘŘ×××ęęęçççŕŕŕçççîîîÝÝݵµµşşşĽĽĽŔŔŔĹĹĹÇÇÇÇÇÇĆĆĆĹĹĹŃŃŃŕŕŕńńńîîîóóóńńńúúúăăăăăăäääććććććâââÝÝÝÜÜÜŰŰŰŰŰŰÝÝÝŰŰŰ×××ŰŰŰäääßßßŃŃŃŮŮŮĂĂĂĂĂĂŃŃŃŃŃŃÉÉÉĂĂĂżżżŃŃŃŃŃŃĐĐĐĚĚĚĚĚĚĚĚĚÉÉÉĹĹĹÍÍÍŇŇŇÍÍÍÂÂÂÂÂÂÍÍÍĚĚĚŔŔŔĽĽĽ¸¸¸´´´­­­©©©ŞŞŞ°°°¸¸¸łłł­­­ŞŞŞłłłľľľŔŔŔ···­­­łłłłłł´´´···şşşĽĽĽľľľľľľÇÇÇşşşµµµ···­­­¬¬¬łłł´´´¸¸¸ĂĂĂÍÍÍĚĚĚÇÇÇĚĚĚŐŐŐÝÝÝÔÔÔŃŃŃÍÍÍÇÇÇĹĹĹÂÂÂŔŔŔżżżĹĹĹĹĹĹĂĂĂÍÍÍßßßŕŕŕŮŮŮßßßęęęčččćććăăăâââŕŕŕŕŕŕŕŕŕâââäääçççęęęíííďďďďďďďďďňňňóóóóóóńńńëëëćććäääăăăâââŰŰŰÝÝÝŕŕŕÜÜÜŕŕŕçççăăăäääççççççćććäääăăăŕŕŕÝÝÝßßßÔÔÔŔŔŔ···ĽĽĽŔŔŔÂÂÂĆĆĆÇÇÇÇÇÇÉÉÉÇÇÇĹĹĹĂĂĂĹĹĹĆĆĆÉÉÉĂĂĂÂÂÂľľľżżż»»»¬¬¬łłłĂĂĂÇÇÇÉÉɸ¸¸łłł¸¸¸ŔŔŔĂĂõµµ´´´ľľľÇÇÇÍÍÍĆĆĆ´´´ľľľÂÂÂÇÇÇĘĘĘĘĘĘÇÇÇĹĹĹĂĂĂĚĚĚÎÎÎÔÔÔ×××ĐĐĐÇÇÇÍÍÍŮŮŮÔÔÔŘŘŘÜÜÜÜÜÜÜÜÜÜÜÜŕŕŕăăăăăăäääääääääăăăâââââââââççççççäääßßßŰŰŰŰŰŰâââçççŃŃŃŇŇŇÔÔÔÔÔÔÔÔÔŇŇŇŃŃŃĐĐĐĐĐĐÔÔÔŕŕŕÝÝÝŰŰŰŰŰŰŐŐŐŰŰŰÔÔÔčččăăăŮŮŮÜÜÜäääŮŮٵµµ···¸¸¸ĽĽĽŔŔŔÂÂÂĂĂĂĂĂĂÂÂÂăăăóóóůůůňňňóóóńńń˙˙˙ăăăäääçççčččçççâââÜÜÜŰŰŰŰŰŰÜÜÜÝÝÝÜÜÜÜÜÜÝÝÝÝÝÝŰŰŰ×××ŇŇŇÇÇÇĹĹĹÍÍÍĐĐĐÎÎÎÉÉÉľľľĂĂĂĘĘĘŃŃŃŇŇŇĐĐĐÍÍÍÍÍÍÍÍÍÇÇÇŃŃŃÔÔÔÎÎÎÎÎÎÎÎÎŔŔŔŻŻŻ±±±łłł±±±°°°ŻŻŻŻŻŻ´´´µµµ­­­¨¨¨¤¤¤ŞŞŞ···ľľľşşşłłłŻŻŻ°°°±±±´´´···şşşşşş¸¸¸»»»¬¬¬­­­´´´±±±···ĂĂĂĹĹĹŔŔŔÂÂÂÉÉÉÎÎÎĐĐĐĚĚĚĚĚĚĐĐĐŐŐŐŃŃŃĚĚĚÇÇÇĹĹĹŔŔŔżżżżżżÂÂÂĂĂĂŔŔŔĘĘĘÜÜÜßßßŮŮŮßßßćććäääăăăâââŕŕŕßßßßßßßßßăăăäääçççęęęîîîńńńňňňňňňîîîďďďďďďíííčččăăăŕŕŕßßßßßßßßßçççčččÜÜÜÜÜÜääääääăăăäääććććććäääâââââââââŕŕŕâââÍÍ͸¸¸»»»ŔŔŔÂÂÂĆĆĆÇÇÇĆĆĆĆĆĆĆĆĆĹĹĹÂÂÂÂÂÂĆĆĆŔŔŔĽĽĽľľľşşş»»»şşşłłłżżżĆĆĆĹĹĹÂÂÂľľľ···´´´»»»ĹĹĹÍÍÍ»»»¸¸¸ĹĹĹÉÉÉĆĆĆżżżµµµÂÂÂĹĹĹÇÇÇÉÉÉÉÉÉĆĆĆÂÂÂŔŔŔŘŘŘŇŇŇĐĐĐŃŃŃÎÎÎĚĚĚÎÎÎ×××ŇŇŇÔÔÔ×××ŘŘŘŮŮŮÝÝÝŕŕŕäääâââăăăäääććććććäääăăăâââääääääăăăßßßŰŰŰŮŮŮÝÝÝâââăăăÝÝÝŐŐŐÎÎÎÍÍÍÎÎÎŇŇŇŐŐŐŇŇŇ×××ăăăÜÜÜŘŘŘŮŮŮŐŐŐŮŮŮßßßëëëăăăŰŰŰÜÜÜŕŕŕŮŮŮľľľ´´´µµµşşşĽĽĽżżżżżżŔŔŔżżżîîîůůů˙˙˙óóóóóóďďď˙˙˙ćććŕŕŕăăăäääăăăâââŕŕŕŕŕŕăăăâââÝÝÝÝÝÝŕŕŕßßßŰŰŰŰŰŰßßßÉÉÉÎÎÎĚĚĚÍÍÍĘĘĘÇÇÇÍÍÍĆĆĆ»»»ÂÂÂÍÍÍŇŇŇĚĚĚÂÂÂŔŔŔĆĆĆÎÎÎŃŃŃŇŇŇÍÍÍĆĆĆľľľµµµ°°°łłł···łłłłłłłłł±±±´´´ŻŻŻ¬¬¬ŞŞŞŞŞŞ©©©¬¬¬±±±¸¸¸ĽĽĽłłłµµµ···¸¸¸¸¸¸şşşşşş»»»Â»»»żżżĆĆĆÂÂÂĹĹĹĚĚĚÉÉÉÂÂÂÂÂÂÇÇÇŃŃŃÔÔÔÎÎÎÇÇÇĹĹĹÍÍÍÉÉÉÇÇÇĆĆĆĹĹĹĂĂĂĆĆĆĘĘĘŔŔŔľľľĽĽĽĹĹĹŇŇŇŮŮŮÜÜÜăăăŕŕŕßßßßßßÝÝÝÝÝÝÝÝÝßßßßßßäääćććčččëëëîîîďďďńńńňňňçççčččëëëëëëčččäääăăăăăăäääçççíííëëëŕŕŕÜÜÜßßßŕŕŕŕŕŕßßßâââääääääăăăăăăćććâââćććŰŰŰĆĆĆ»»»ľľľÂÂÂĂĂĂĹĹĹĂĂĂĂĂĂĆĆĆĹĹĹŔŔŔÂÂÂĆĆĆşşşşşşĽĽĽµµµµµµ···µµµÉÉÉÇÇÇĂĂĂŔŔŔżżżľľľľľľÂÂÂĘĘĘĚĚĚĽĽĽŔŔŔĚĚĚĂĂĂ···şşşŔŔŔŔŔŔÂÂÂĹĹĹĆĆĆĆĆĆĂĂĂŔŔŔżżżÜÜÜÔÔÔÍÍÍÍÍÍĐĐĐŃŃŃŃŃŃŇŇŇŐŐŐŇŇŇŇŇŇÔÔÔ×××ÜÜÜßßßâââââââââäääćććććććććäääăăăßßßââââââÝÝÝŮŮŮŘŘŘŮŮŮÝÝÝďďďčččŕŕŕŘŘŘŐŐŐŘŘŘßßßăăăÝÝÝÜÜÜâââŮŮŮŘŘŘßßßŘŘŘŘŘŘëëëîîîäääćććííííííćććŃŃŃłłł´´´···şşşĽĽĽľľľľľľľľľëëëňňňúúúňňňóóóďďďůůůçççââââââăăăäääćććčččîîîńńńďďďçççŕŕŕßßßßßßÜÜÜÜÜÜßßßĘĘĘŃŃŃĚĚĚÍÍÍÇÇÇżżżĚĚĚĐĐĐÂÂÂľľľŔŔŔĹĹĹżżżłłłµµµÂÂÂĐĐĐĆĆĆÂÂÂĹĹĹŔŔŔµµµ±±±µµµ´´´»»»µµµ¸¸¸şşşµµµµµµ©©©¬¬¬±±±´´´łłł­­­¬¬¬°°°µµµ»»»ĽĽĽĽĽĽşşş···¸¸¸ĽĽĽżżż¸¸¸şşşżżżŔŔŔŔŔŔĆĆĆÉÉÉĆĆƸ¸¸ĂĂĂÎÎÎÔÔÔŇŇŇĐĐĐĘĘĘĆĆĆÔÔÔĐĐĐĚĚĚÉÉÉÂÂÂĽĽĽľľľĂĂĂĹĹĹŔŔŔĹĹĹÍÍÍĐĐĐŐŐŐÜÜÜâââŰŰŰŰŰŰŰŰŰŰŰŰÜÜÜÝÝÝßßßŕŕŕäääçççęęęíííîîîíííëëëęęęćććčččííííííëëëčččçççćććëëëíííčččććććććâââÝÝÝÝÝÝÜÜÜŮŮŮŰŰŰŕŕŕăăăâââăăăćććăăăăăăâââŇŇŇ»»»şşşÂÂÂŔŔŔĂĂĂÂÂÂÂÂÂĆĆĆĹĹĹżżżŔŔŔĆĆĆ»»»»»»ľľľ´´´±±±±±±µµµĚĚĚÉÉÉĂĂĂÂÂÂĆĆĆÉÉÉÇÇÇĘĘĘĐĐĐÍÍ͸¸¸şşşÇÇÇŔŔŔ±±±···ĂĂĂľľľżżżŔŔŔÂÂÂĂĂĂÂÂÂŔŔŔľľľŘŘŘÔÔÔĐĐĐÍÍÍĐĐĐŇŇŇŇŇŇŃŃŃ×××ÔÔÔĐĐĐĐĐĐŐŐŐŰŰŰÝÝÝÝÝÝââââââăăăääääääćććääääääÝÝÝŕŕŕâââßßßŰŰŰŘŘŘŮŮŮÜÜÜčččëëëďďďňňňńńńîîîęęęçççëëëăăăŕŕŕŘŘŘÜÜÜćććßßßŰŰŰńńńęęęÜÜÜâââçççÝÝÝŃŃŃ»»»±±±´´´µµµ¸¸¸»»»ĽĽĽľľľľľľäääçççöööďďďňňňďďďöööčččçççççççççčččíííňňňřřřüüü˙˙˙ňňňäääÜÜÜÜÜÜÝÝÝÝÝÝŰŰŰŇŇŇŃŃŃĹĹĹÍÍÍĘĘĘľľľÉÉÉŃŃŃÎÎÎľľľµµµşşş¸¸¸łłłľľľŇŇŇĂĂĂłłłłłłÇÇÇÎÎÎżżżŻŻŻ­­­±±±»»»¸¸¸żżżĂĂĂĽĽĽ¸¸¸ĄĄĄŻŻŻ´´´»»»ľľľşşş±±±©©©ĄĄĄ»»»»»»¸¸¸łłłŻŻŻ°°°···ĽĽĽşşşŔŔŔŔŔŔ»»»ĽĽĽĂĂĂĆĆĆĆĆĆşşşÉÉÉŇŇŇŃŃŃŃŃŃŐŐŐÍÍÍżżżŇŇŇÎÎÎĚĚĚÉÉÉ»»»ľľľĆĆĆĘĘĘÇÇÇŇŇŇŰŰŰŐŐŐŐŐŐŰŰŰŮŮŮ××××××ŘŘŘŮŮŮŰŰŰÝÝÝŕŕŕâââäääçççëëëîîîîîîëëëćććâââęęęíííďďďďďďíííęęęçççćććîîîíííŕŕŕßßßęęęčččßßßÝÝÝŮŮŮŐŐŐ×××ÝÝÝâââââââââćććßßßçççßßßßßßŰŰ۱±±ĽĽĽżżżŔŔŔĹĹĹĹĹĹÂÂÂŔŔŔĂĂĂĂĂĂŔŔŔşşşľľľ°°°ĽĽĽ»»»­­­ÂÂÂÇÇÇĆĆĆĘĘĘÎÎÎŃŃŃŃŃŃĐĐĐÎÎÎÎÎÎĚĚĚľľľ»»»şşşĹĹĹ°°°°°°şşşµµµşşşľľľÂÂÂÂÂÂŔŔŔÂÂÂÂÂÂ×××ŮŮŮÉÉÉĚĚĚŃŃŃĘĘĘÎÎÎÎÎÎÎÎÎĘĘĘŃŃŃÔÔÔĐĐĐÔÔÔÜÜÜŮŮŮßßßŕŕŕăăăäääääääääăăăâââćććâââŕŕŕâââßßßŘŘŘŐŐŐ×××ßßßăăăććććććăăăâââäääčččęęęäääăăăäääăăăÝÝÝÝÝÝâââëëëëëëâââęęęÜÜÜĐĐеµµ±±±´´´µµµµµµ»»»ĽĽĽĂĂĂĽĽĽâââćććňňňííííííîîîęęęőőő˙˙˙ćććäääćććíííőőőůůůůůůöööóóóńńńëëëăăăŰŰŰŘŘŘŘŘŘŮŮŮŇŇŇćććÍÍÍĹĹĹŐŐŐÎÎÎĘĘĘÎÎÎÍÍÍĘĘĘľľľľľľ»»»¸¸¸ĘĘĘÔÔÔÍÍÍÍÍÍŃŃŃÎÎÎÉÉÉĚĚĚĂĂĂ­­­±±±łłł»»»ľľľ»»»ľľľ¸¸¸ŞŞŞ°°°ľľľÂÂÂşşş···şşşłłł¨¨¨ĽĽĽ»»»´´´©©©¨¨¨ŻŻŻµµµµµµ»»»···şşşÂÂÂżżżµµµµµµĽĽĽÂÂÂÍÍÍŃŃŃĐĐĐŃŃŃŐŐŐÍÍÍŔŔŔÎÎÎÍÍÍĂĂĂĘĘĘÉÉÉľľľĂĂĂÂÂÂÉÉÉŃŃŃŮŮŮŘŘŘŐŐŐÔÔÔÔÔÔÔÔÔÔÔÔÎÎÎÎÎÎŐŐŐŰŰŰŰŰŰÜÜÜâââääääääçççíííďďďíííçççăăăâââćććëëëďďďďďďîîîëëëëëëíííćććßßßŰŰŰŘŘŘŘŘŘâââíííŕŕŕÜÜÜŮŮŮŰŰŰŕŕŕćććçççćććëëëńńńćććäääăăă···şşş»»»żżżÂÂÂÂÂÂľľľľľľŔŔŔŔŔŔľľľĽĽĽľľľ°°°şşş¸¸¸ŻŻŻĹĹĹÍÍÍÉÉÉĚĚĚŃŃŃŇŇŇŇŇŇŃŃŃĐĐĐĐĐĐĐĐĐĹĹĹÂÂÂľľľĆĆĆ´´´´´´ĽĽĽ···şşşľľľŔŔŔŔŔŔżżżŔŔŔÂÂÂĘĘĘŇŇŇÉÉÉÉÉÉÎÎÎĚĚĚŃŃŃŃŃŃÉÉÉÉÉÉĐĐĐŇŇŇÎÎÎŇŇŇŰŰŰŰŰŰßßßŕŕŕâââăăăäääăăăâââŕŕŕçççäääăăăćććäääßßßÝÝÝŕŕŕäääććććććäääâââăăăčččîîîćććăăăâââăăăăăăâââćććíííęęęëëëćććäääÍÍÍĂĂĂ···µµµ´´´µµµłłł»»»ľľľŔŔŔşşşâââçççńńńęęęčččëëëčččňňňúúúćććëëëňňňřřřůůůřřřöööőőőőőőňňňëëëăăăÜÜÜŮŮŮÜÜÜŕŕŕ×××âââĘĘĘĹĹĹÔÔÔĐĐĐĚĚĚĘĘĘĹĹĹÍÍÍÍÍÍĐĐĐĆĆĆĽĽĽĘĘĘŐŐŐŃŃŃŃŃŃÔÔÔÔÔÔĐĐĐĐĐĐĹĹĹ­­­±±±łłłşşşĽĽĽ»»»ŔŔŔ¸¸¸¬¬¬¸¸¸ĂĂĂŔŔŔ»»»µµµ°°°¬¬¬­­­¬¬¬¨¨¨˘˘˘¦¦¦±±±¸¸¸»»»żżżşşşşşşľľľ»»»łłłµµµľľľĆĆĆĐĐĐÔÔÔŃŃŃŇŇŇŐŐŐÎÎÎÂÂÂÍÍÍÍÍÍÉÉÉĚĚĚĚĚĚĆĆĆÂÂÂşşşĘĘĘ×××ßßßŰŰŰŘŘŘŰŰŰŐŐŐĚĚĚĹĹŵµµ´´´ĘĘĘÜÜÜÝÝÝŰŰŰÜÜÜâââćććčččçççäääćććďďďřřřóóóďďďëëëčččëëëîîîńńńňňňßßßŮŮŮ××××××ŐŐŐÔÔÔŘŘŘÝÝÝăăăßßßŮŮŮŰŰŰŕŕŕćććččččččëëëîîîŕŕŕŰŰŰßßß···şşşżżżľľľżżżľľľşşşşşşľľľľľľ»»»ĽĽĽľľľ±±±¸¸¸µµµ°°°ÉÉÉÔÔÔĚĚĚĐĐĐÔÔÔŐŐŐÔÔÔŇŇŇŇŇŇŇŇŇŃŃŃĚĚĚÉÉÉżżżĆĆƵµµ¸¸¸ľľľşşşĽĽĽľľľľľľľľľľľľżżżŔŔŔÇÇÇ×××ŃŃŃÍÍÍÎÎÎÍÍÍŃŃŃĐĐĐÎÎÎĐĐĐŐŐŐŐŐŐŃŃŃŇŇŇŮŮŮŰŰŰßßßßßßâââââââââŕŕŕßßßßßßăăăââââââććććććăăăăăăćććäääçççčččçççćććçççëëëďďďëëëęęęęęęčččäääŕŕŕâââćććëëëëëëęęęßß߼ĽĽµµµşşş»»»şşş»»»´´´»»»ŔŔŔşşşµµµßßßćććíííăăăâââćććăăăíííňňňćććďďďřřřůůůóóóîîîďďďňňňőőőóóóîîîćććÝÝÝŰŰŰßßßäääÜÜÜÝÝÝÍÍÍÉÉÉŃŃŃŃŃŃÍÍÍÇÇǸ¸¸ĹĹĹĘĘĘŃŃŃÉÉÉĽĽĽĂĂĂĹĹĹÔÔÔÔÔÔŐŐŐŐŐŐÔÔÔÔÔÔÉÉɵµµ´´´´´´şşşĽĽĽşşşŔŔŔĆĆƬ¬¬łłłżżżĆĆĆżżżłłłŻŻŻłłłłłł°°°ŞŞŞ¦¦¦ŞŞŞ´´´¸¸¸¸¸¸ŔŔŔĽĽĽ»»»ĽĽĽşşşµµµĽĽĽÉÉÉĘĘĘŃŃŃÔÔÔŇŇŇÔÔÔŐŐŐÎÎÎĂĂĂĐĐĐĘĘĘÉÉÉĂĂĂĹĹĹĘĘĘÇÇÇĆĆĆÔÔÔÜÜÜŮŮŮĚĚĚĆĆĆÉÉÉŔŔŔ°°°łłł¨¨¨¦¦¦¸¸¸ÎÎÎŮŮŮÜÜÜÜÜÜŰŰŰÝÝÝâââăăăăăăćććččččččőőőďďďëëëëëëďďďńńńńńńďďďăăăÝÝÝŮŮŮŮŮŮŘŘŘ××××××ŘŘŘćććŕŕŕŰŰŰŰŰŰŕŕŕćććęęęęęęäääçççßßßŮŮŮÜÜÜ···¸¸¸ŔŔŔżżżŔŔŔĽĽĽ¸¸¸¸¸¸ľľľľľľ»»»ĽĽĽľľľ´´´¸¸¸···µµµĚĚĚŘŘŘĐĐĐŇŇŇ×××ŘŘŘ×××ŐŐŐŐŐŐŐŐŐŃŃŃÎÎÎĚĚĚľľľÂ´´´···ĽĽĽĽĽĽľľľľľľĽĽĽ»»»ĽĽĽľľľŔŔŔŔŔŔÔÔÔÔÔÔĘĘĘÉÉÉĘĘĘĘĘĘĘĘĘÉÉÉÍÍÍŃŃŃŇŇŇŃŃŃÔÔÔŰŰŰßßßßßßßßßŕŕŕŕŕŕßßßßßßÝÝÝÜÜÜÜÜÜŮŮŮÜÜÜŕŕŕâââßßßßßßâââÜÜÜâââčččííííííëëëëëëëëëăăăćććęęęëëëčččćććäääćććďďďëëëîîîÝÝݸ¸¸µµµÂÂÂÂÂÂÂÂÂÂÂÂşşşľľľĂĂõµµµµµÝÝÝëëëńńńäääăăăčččçççîîîňňňíííňňňőőőňňňíííęęęîîîóóóóóóóóóńńńčččŕŕŕÜÜÜßßßăăăßßßÜÜÜŐŐŐŇŇŇĐĐĐĐĐĐĐĐĐĚĚĚ»»»ľľľşşşĂĂĂÉÉÉÂÂÂżżżłłłĚĚĚŃŃŃÔÔÔÔÔÔŇŇŇÔÔÔÎÎÎĹĹŵµµµµµĽĽĽżżż»»»żżżĹĹĹ´´´°°°···ÂÂÂŔŔŔ´´´±±±şşş´´´°°°ŞŞŞ¬¬¬±±±¸¸¸»»»şşş°°°­­­­­­°°°ŻŻŻ°°°şşşĆĆĆÉÉÉÍÍÍŃŃŃŃŃŃŇŇŇÔÔÔÎÎÎĆĆĆŘŘŘÎÎÎÎÎÎĂĂĂĽĽĽżżżĽĽĽÇÇÇÜÜÜŘŘŘÉÉÉ···±±±µµµ°°°¤¤¤­­­´´´łłłŻŻŻ···ĚĚĚŮŮŮŰŰŰÝÝÝßßßÜÜÜŰŰŰÝÝÝăăăäääăăăëëëííííííîîîîîîîîîííííííëëëäääŰŰŰ×××ÔÔÔŇŇŇŃŃŃŃŃŃäääßßßŰŰŰŰŰŰŕŕŕćććççççççăăăăăăćććŕŕŕÜÜÜşşş¸¸¸żżżĹĹĹĂĂĂżżż»»»ĽĽĽŔŔŔŔŔŔĽĽĽ»»»ĽĽĽ¸¸¸şşşşşş»»»ÍÍÍŘŘŘÔÔÔ×××ŮŮŮŮŮŮŘŘŘ××××××ŘŘŘÔÔÔŃŃŃÍÍÍľľľĂĂõµµ¸¸¸ľľľľľľżżżľľľĽĽĽ»»»»»»ľľľŔŔŔĆĆĆŘŘŘÜÜÜŃŃŃĐĐĐŇŇŇĐĐĐŃŃŃÜÜÜßßßßßßÜÜÜŮŮŮŘŘŘŰŰŰßßßßßßßßßßßßÝÝÝÜÜÜŰŰŰŰŰŰŮŮŮŘŘŘ×××ŘŘŘÜÜÜÝÝÝŰŰŰŰŰŰÝÝÝŮŮŮßßßćććëëëííííííëëëëëëäääçççęęęčččçççćććććććććóóóëëëďďďâââĹĹĹľľľÉÉÉĹĹĹĂĂĂĂĂĂľľľÂÂÂĆĆƵµµŔŔŔŕŕŕćććëëëÝÝÝÝÝÝăăăâââçççęęęďďďďďďńńńďďďîîîîîîďďďňňňďďďňňňňňňîîîćććßßßÜÜÜÜÜÜßßßÜÜÜßßßŰŰŰŃŃŃÎÎÎĐĐĐŃŃŃÍÍÍĆĆĆ···ĽĽĽÇÇÇÇÇÇĆĆƸ¸¸şşşĆĆĆŃŃŃÔÔÔŐŐŐÔÔÔĐĐĐÎÎα±±łłłĽĽĽĂĂĂżżżľľľŔŔŔľľľżżż±±±­­­¸¸¸żżżşşş¸¸¸żżżżżż¸¸¸±±±°°°°°°°°°­­­ŞŞŞŻŻŻŻŻŻ°°°łłł´´´µµµľľľĆĆĆĂĂĂÇÇÇĘĘĘÍÍÍĐĐĐŃŃŃÎÎÎÉÉÉŔŔŔ»»»ÉÉÉĘĘĘĹĹĹŔŔŔżżżŃŃŃÔÔÔÉÉÉ»»»µµµµµµ···¸¸¸¸¸¸µµµŔŔŔŔŔŔ±±±­­­»»»ÇÇÇĘĘĘÍÍÍŮŮŮââââââßßßăăăçççččččččíííîîîëëëçççćććęęęîîîďďďëëëäääßßßÝÝÝÜÜÜŘŘŘŐŐŐŕŕŕÜÜÜŰŰŰÜÜÜŕŕŕäääăăăâââăăăŇŇŇÔÔÔÎÎÎÉÉÉ···ĂĂĂĘĘĘÉÉÉÇÇÇĂĂĂżżżÂÂÂĆĆĆĂĂĂżżżĽĽĽĽĽĽ»»»»»»ĽĽĽÂÂÂÎÎÎ××××××ŮŮŮŰŰŰŰŰŰŮŮŮŘŘŘŮŮŮŮŮŮŮŮŮŇŇŇÎÎÎÂÂÂÇÇǸ¸¸»»»ÂÂÂżżżżżżżżżľľľĽĽĽĽĽĽżżżÂ»»»ÉÉÉŇŇŇĐĐĐŐŐŐÝÝÝŰŰŰŕŕŕßßßâââßßßÜÜÜÝÝÝŰŰŰŮŮŮÝÝÝßßßÝÝÝÝÝÝÜÜÜŮŮŮŘŘŘŘŘŘ×××ŮŮŮŘŘŘŮŮŮÝÝÝßßßÜÜÜÜÜÜßßßßßßŕŕŕăăăćććçççęęęíííîîîîîîîîîęęęääääääçççčččçççőőőëëëńńńçççŐŐŐĹĹĹĘĘĘĆĆĆŔŔŔżżżŔŔŔĂĂĂĹĹŸ¸¸ŃŃŃäääâââčččÜÜÜÝÝÝăăăŕŕŕäääçççääääääçççęęęíííëëëčččćććíííďďďňňňňňňíííäääÜÜÜŘŘŘÜÜÜŰŰŰăăăßßß×××ŃŃŃÎÎÎÔÔÔÔÔÔŃŃŃŔŔŔĽĽĽľľľŔŔŔÉÉÉĹĹĹ­­­ĽĽĽĘĘĘŇŇŇŘŘŘŐŐŐÎÎÎÎÎΰ°°ŻŻŻşşşĂĂĂŔŔŔŔŔŔÂÂÂľľľĹĹĹ´´´ŞŞŞŻŻŻ»»»żżżżżżżżż»»»···´´´¸¸¸»»»»»»şşş»»»żżżżżżŔŔŔÂÂÂĂĂĂĹĹĹÇÇÇĘĘĘÂÂÂĂĂĂĆĆĆĘĘĘÍÍÍĐĐĐÎÎÎĘĘĘżżżľľľĆĆĆÉÉÉĂĂĂľľľżżżÍÍÍŔŔŔşşş···ĽĽĽżżżĽĽĽľľľĂĂĂŔŔŔŔŔŔŔŔŔĽĽĽµµµłłłłłł´´´±±±ŔŔŔÎÎÎ×××ÝÝÝäääâââŰŰŰÜÜÜäääíííîîîęęęääääääćććęęęíííďďďîîîîîîëëëćććßßßÝÝÝÜÜÜŰŰŰÜÜÜŕŕŕăăăâââßßßŕŕŕ»»»şşşşşş»»»şşşĐĐĐĐĐĐĚĚĚĘĘĘÇÇÇĂĂĂĆĆĆÉÉÉĆĆĆżżżżżżľľľ»»»şşşľľľÇÇÇĐĐĐ×××ŮŮŮŰŰŰÜÜÜÜÜÜŰŰŰŮŮŮŮŮŮŰŰŰÜÜÜĐĐĐÉÉÉÂÂÂĘĘʸ¸¸şşşĂĂĂľľľżżżŔŔŔżżżľľľżżżŔŔŔĂĂĂĆĆĆÇÇÇĚĚĚĹĹĹÇÇÇÇÇÇşşşżżżľľľĂĂĂĂĂĂÇÇÇÔÔÔŘŘŘŮŮŮŕŕŕßßßÝÝÝÜÜÜŮŮŮŘŘŘ×××ŐŐŐŐŐŐŰŰŰŮŮŮŰŰŰŕŕŕâââßßßŕŕŕăăăäääääääääćććçççčččęęęęęęäääćććäääćććíííőőőöööóóóňňňęęęňňňëëëŕŕŕĂĂĂÂÂÂĹĹĹŔŔŔĽĽĽĹĹĹĹĹĹżżż¸¸¸ŰŰŰŕŕŕčččńńńçççčččîîîęęęîîîńńńâââăăăćććčččččččččćććäääëëëîîîňňňóóóňňňëëëâââŮŮŮŰŰŰ×××ÝÝÝÜÜÜÜÜÜŘŘŘĘĘĘŃŃŃĐĐĐÔÔÔÉÉÉľľľ······ĆĆĆÇÇÇ···ĽĽĽľľľĆĆĆÔÔÔŐŐŐÍÍÍÍÍ͸¸¸łłł¸¸¸ŔŔŔżżżżżżŔŔŔżżżżżż¸¸¸°°°­­­···ĂĂĂĂĂĂĽĽĽĹĹĹŔŔŔŔŔŔĂĂĂĂĂĂŔŔŔżżżŔŔŔľľľĽĽĽĽĽĽľľľŔŔŔÂÂÂĂĂĂÂÂÂĂĂĂĂĂĂĹĹĹÉÉÉÍÍÍÎÎÎÍÍÍĚĚĚżżżĂĂĂŔŔŔŔŔŔÂÂÂÇÇÇĚĚĚĆĆĆłłłµµµ»»»ŔŔŔżżżĽĽĽĽĽĽľľľÂÂÂżżżżżżŔŔŔľľľµµµ°°°­­­°°°łłł±±±µµµĂĂĂŇŇŇŃŃŃĆĆĆĂĂĂÍÍÍŰŰŰćććëëëęęęăăăßßßÝÝÝćććëëëëëëęęęčččăăăÝÝÝŕŕŕÝÝÝŰŰŰÜÜÜŕŕŕăăăăăăŕŕŕâââłłł¸¸¸ŔŔŔĂĂĂĹĹĹŃŃŃÂÂÂĚĚĚĚĚĚÉÉÉĆĆĆÇÇÇĚĚĚĆĆĆżżżĂĂĂľľľ»»»¸¸¸ľľľÉÉÉĐĐĐ×××ŰŰŰÜÜÜÝÝÝÜÜÜŰŰŰŮŮŮŮŮŮŰŰŰŮŮŮĘĘĘĂĂĂľľľÇÇÇ´´´µµµŔŔŔľľľżżżŔŔŔŔŔŔżżżŔŔŔÂÂÂĂĂĂĆĆĆĂĂĂÇÇÇĹĹĹÍÍÍĐĐĐÂÂÂÉÉÉĂĂĂÇÇÇĂĂĂÇÇÇÔÔÔŮŮŮ×××ÜÜÜßßßÝÝÝŰŰŰŮŮŮ×××ŐŐŐŐŐŐÔÔÔŮŮŮŘŘŘŮŮŮŕŕŕâââŕŕŕâââććććććçççęęęëëëëëëęęęćććăăăâââćććęęęîîîöööüüüöööíííďďďęęęňňňíííäääżżż»»»ĂĂĂĂĂĂżżżÉÉÉĆĆĆşşş´´´ÜÜÜŘŘŘßßßčččâââăăăçççăăăçççęęęîîîńńńńńńďďďííííííńńńőőőęęęíííńńńőőőöööńńńćććßßßŰŰŰÔÔÔŘŘŘŘŘŘŕŕŕÜÜÜÇÇÇĚĚĚŃŃŃŘŘŘÎÎÎĂĂĂşşş¸¸¸ĆĆĆÇÇÇÉÉÉ´´´¸¸¸ĚĚĚÔÔÔÎÎÎÎÎÎĹĹĹşşşşşşżżżĽĽĽĽĽĽżżżľľľ¸¸¸»»»···°°°µµµĹĹĹĹĹĹşşşżżżľľľżżżĂĂĂĂĂĂŔŔŔżżżĂĂĂşşş¸¸¸¸¸¸»»»żżżĂĂĂĂĂĂÂÂÂĆĆĆĹĹĹĆĆĆĘĘĘÍÍÍÍÍÍĚĚĚĘĘĘĂĂĂŃŃŃÇÇÇĹĹĹÉÉÉÍÍÍÇÇÇ©©©­­­şşşÂÂÂŔŔŔżżżŔŔŔÂÂÂŔŔŔżżżĂĂĂĂĂĂżżżĽĽĽĽĽĽşşşµµµ­­­´´´µµµłłłµµµżżżľľľ´´´µµµ¸¸¸ÂÂÂŃŃŃâââęęęčččăăăăăăęęęîîîęęęççççççćććâââäääŕŕŕÜÜÜÜÜÜŕŕŕääääääăăăÔÔÔĹĹĹşşşĽĽĽĹĹĹÉÉÉÉÉÉÉÉÉÍÍÍĘĘĘÇÇÇÇÇÇÉÉÉÉÉÉÇÇÇĆĆĆĂĂĂĆĆĆŔŔŔĂĂĂŔŔŔľľľĐĐĐŮŮŮŕŕŕÝÝÝŘŘŘŃŃŃĐĐĐÔÔÔŮŮŮÜÜÜŐŐŐĐĐĐżżżżżżĘĘĘ»»»ŻŻŻľľľ»»»ŔŔŔÂÂÂľľľľľľĂĂĂÇÇÇĆĆĆĘĘĘÉÉÉÉÉÉĘĘĘÍÍÍÍÍÍĚĚĚÉÉÉÇÇÇÇÇÇÇÇÇÂÂÂŮŮŮŘŘŘŮŮŮŘŘŘÝÝÝŕŕŕßßßŘŘŘÔÔÔŐŐŐ×××ÔÔÔŰŰŰÜÜÜÜÜÜÝÝÝŕŕŕäääçççčččëëëčččâââäääîîîčččăăăęęęńńńőőőöööőőőőőőřřřřřřóóóřřřúúúřřřŕŕŕÂÂÂľľľĹĹĹżżżÂÂÂżżżĹĹĹĘĘĘĽĽĽ­­­···ÎÎÎŮŮŮçççŰŰŰŮŮŮÍÍÍŔŔŔŘŘŘŰŰŰčččççççççčččććććććëëëóóóńńńíííńńńďďďęęęńńńňňňćććÜÜÜŘŘŘ×××ŐŐŐŰŰŰßßßŐŐŐĚĚĚĚĚĚŐŐŐŃŃŃĐĐĐżżżÍÍÍĐĐĐÉÉÉĘĘĘÂÂÂÂÂÂĚĚĚŇŇŇĐĐĐÎÎÎĐĐĐĚĚĚŃŃŃĘĘĘ»»»µµµĽĽĽÂÂÂżżżĽĽĽĂĂĂşşşŻŻŻşşşĆĆĆĂĂĂżżżŔŔŔÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂŔŔŔŔŔŔľľľ¸¸¸···ĽĽĽżżżľľľľľľŔŔŔĂĂĂĂĂĂĆĆĆÉÉÉĆĆĆĂĂĂÉÉÉÔÔÔĐĐĐĘĘĘÉÉÉÔÔÔÎÎÎĐĐĐşşş´´´···¸¸¸ľľľĆĆĆÉÉÉĆĆĆĹĹĹĆĆĆÇÇÇĆĆĆĂĂĂÂÂÂŔŔŔżżżżżżľľľĽĽĽ»»»»»»ľľľÂÂÂĂĂĂĂĂĂÂÂÂŔŔŔşşşµµµ»»»ÉÉÉŰŰŰćććëëëćććăăăäääďďďëëëçççíííŕŕŕŰŰŰßßßŕŕŕÔÔÔßßßŰŰŰŕŕŕăăăĂĂĂżżżŔŔŔÇÇÇĘĘĘÉÉÉÇÇÇÉÉÉĐĐĐÍÍÍĚĚĚĚĚĚÍÍÍÍÍÍĚĚĚÉÉÉÇÇÇÉÉÉŔŔŔĂĂĂŔŔŔżżżŃŃŃÜÜÜâââßßßŘŘŘŇŇŇĐĐĐŃŃŃŐŐŐ×××ŮŮŮŐŐŐĆĆĆŔŔŔĂĂĂ»»»´´´ĽĽĽşşşżżżŔŔŔľľľĽĽĽŔŔŔÂÂÂÂÂÂĘĘĘĘĘĘĘĘĘĘĘĘĚĚĚĚĚĚĘĘĘÉÉÉÉÉÉĹĹĹÇÇÇÇÇÇŰŰŰŇŇŇ×××ÜÜÜŰŰŰÝÝÝÝÝÝŮŮŮ×××ŘŘŘŮŮŮŘŘŘŘŘŘŘŘŘŰŰŰßßßćććččččččćććäääíííîîîîîîďďďíííîîîúúúäääëëëďďďďďďďďďńńńďďďëëëęęęďďďíííŰŰŰÇÇÇĹĹĹÇÇÇĂĂĂľľľ»»»ŔŔŔÇÇÇŔŔŔłłł´´´żżż···Â¸¸¸ľľľ»»»łłłŔŔŔ»»»ŮŮŮÜÜÜŕŕŕăăăŕŕŕÝÝÝäääîîîőőőőőőöööóóóďďďňňňňňňëëëçççäääÝÝÝ××××××ŰŰŰ×××ŃŃŃÍÍÍŇŇŇŃŃŃŃŃŃ»»»ÂÂÂĆĆĆĘĘĘÍÍÍľľľşşşĚĚĚ×××ŃŃŃÍÍÍŃŃŃÎÎÎŇŇŇĐĐĐŔŔŔ´´´´´´»»»żżżżżżÂ¸¸¸łłłľľľĆĆĆĂĂĂÂÂÂŔŔŔÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂŔŔŔŔŔŔľľľşşş¸¸¸ĽĽĽľľľľľľŔŔŔĹĹĹ»»»»»»ĽĽĽżżżľľľżżżĹĹĹĚĚĚĐĐĐĆĆĆĘĘĘŇŇŇĐĐĐŃŃѱ±±­­­»»»şşşľľľĹĹĹÇÇÇĹĹĹĹĹĹÇÇÇŔŔŔĂĂĂÇÇÇÇÇÇĂĂĂĽĽĽ»»»ľľľľľľĂĂĂÇÇÇĘĘĘÉÉÉĆĆĆĹĹĹĹĹĹŔŔŔľľľşşş¸¸¸»»»ĆĆĆŇŇŇÜÜÜäääçççćććîîîîîîëëëíííßßßßßßÜÜÜßßßÝÝÝňňňčččâââŰŰŰ···ľľľÇÇÇÎÎÎÎÎÎĘĘĘĚĚĚĐĐĐŇŇŇŃŃŃĐĐĐŃŃŃŃŃŃŃŃŃĐĐĐÎÎÎĚĚĚĚĚĚÂÂÂĂĂĂŔŔŔżżżŃŃŃÜÜÜâââÝÝÝŘŘŘŐŐŐŇŇŇĐĐĐĐĐĐŃŃŃŮŮŮŮŮŮŃŃŃĆĆĆżżżľľľşşş´´´ľľľżżżľľľ¸¸¸¸¸¸ľľľĂĂĂĆĆĆÉÉÉĘĘĘĚĚĚÍÍÍĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĂĂĂÇÇÇĚĚĚÜÜÜĐĐĐŐŐŐÜÜÜŮŮŮÜÜÜÝÝÝŮŮŮŘŘŘŮŮŮŰŰŰŰŰŰ×××ŘŘŘÜÜÜâââäääčččëëëďďďňňňöööóóóőőőüüüüüüőőőňňňęęęďďďďďďëëëćććććććććăăăęęęęęęÜÜÜÇÇÇżżżĂĂĂĆĆĆÉÉÉÇÇÇĹĹĹĹĹĹÇÇÇĆĆĆŔŔŔĽĽĽľľľµµµĽĽĽ´´´ŔŔŔĆĆĆżżżÂ´´´···ĽĽĽÉÉÉ×××ÝÝÝŕŕŕćććíííëëëňňňóóóďďďďďďďďďďďďňňňčččćććÝÝÝ××××××ÜÜÜâââŕŕŕÎÎÎŃŃŃŇŇŇÔÔÔ»»»żżżĂĂĂÎÎÎÍÍÍşşş···ÍÍÍŰŰŰÔÔÔÎÎÎŇŇŇÍÍÍŇŇŇŃŃŃĂĂĂ´´´°°°¸¸¸ÂÂÂÂÂÂżżż······ÂÂÂĆĆĆĂĂĂĂĂĂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂŔŔŔżżż»»»¸¸¸¸¸¸»»»ľľľŔŔŔĆĆĆÍÍÍŃŃŃŃŃŃÍÍÍĆĆĆĂĂĂĆĆĆÇÇÇĆĆĆÇÇÇŔŔŔĚĚĚŇŇŇŇŇŇŇŇұ±±±±±ľľľ»»»ľľľÂÂÂĹĹĹĹĹĹĆĆĆĘĘĘĚĚĚÇÇÇÇÇÇĚĚĚĘĘĘĂĂĂŔŔŔĂĂĂżżżÂÂÂĹĹĹĆĆĆÇÇÇĆĆĆĂĂĂÂÂÂÉÉÉÉÉÉÇÇÇĂĂĂľľľşşş¸¸¸¸¸¸ŘŘŘçççăăăăăăćććăăăäääÝÝÝňňňčččćććâââëëëŃŃŃŔŔŔ···ľľľĂĂĂĘĘĘÎÎÎÎÎÎÎÎÎŇŇŇ×××ÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔŇŇŇŇŇŇĚĚĚĚĚĚĂĂĂĹĹĹÂÂÂżżżÎÎÎ×××ÝÝÝŘŘŘŐŐŐŐŐŐÔÔÔĐĐĐÎÎÎÎÎÎŃŃŃ×××ŮŮŮĚĚĚľľľŔŔŔľľľŻŻŻ···şşşşşşşşşşşşľľľĂĂĂÇÇÇÇÇÇĘĘĘÎÎÎĐĐĐÎÎÎÎÎÎĐĐĐŇŇŇŃŃŃÇÇÇĘĘĘĘĘĘŮŮŮŇŇŇ×××ŐŐŐŰŰŰÜÜÜÜÜÜŮŮŮŘŘŘŘŘŘŮŮŮŰŰŰŮŮŮÜÜÜŕŕŕăăăăăăćććňňň˙˙˙úúú˙˙˙üüüööööööůůůřřřóóóóóóńńńćććÔÔÔĆĆĆÂÂÂŔŔŔżżżÜÜÜÜÜÜÉÉɸ¸¸ľľľĹĹĹÉÉÉĐĐĐŃŃŃÎÎÎÉÉÉĆĆĆĆĆĆĆĆĆĆĆĆĂĂĂĹĹĹÇÇÇżżżÉÉÉĐĐĐÉÉÉÇÇÇşşş···´´´µµµŔŔŔÍÍÍŐŐŐÝÝÝăăăîîîůůůřřřńńńńńńëëëčččńńńňňňďďďŕŕŕŘŘŘ×××ŘŘŘÜÜÜŐŐŐÍÍÍŃŃŃ×××ŐŐŐŔŔŔĚĚĚĘĘĘŃŃŃĹĹĹĽĽĽżżżĐĐĐŰŰŰ×××ŃŃŃŇŇŇĘĘĘŃŃŃÍÍÍĽĽĽ±±±µµµżżżĹĹĹÂÂÂşşş´´´şşşÂÂÂĂĂĂÂÂÂĂĂĂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂŔŔŔżżżżżżµµµµµµ···şşşĽĽĽĂĂĂÍÍÍÔÔÔÍÍÍÍÍÍÉÉÉÂÂÂĂĂĂÉÉÉĘĘĘĆĆĆĆĆĆĘĘĘŃŃŃŘŘŘŐŐŐĆĆĆ´´´···żżż»»»»»»ŔŔŔĂĂĂĹĹĹÉÉÉÎÎÎĆĆƸ¸¸°°°şşşĹĹĹÇÇÇĆĆĆĆĆĆÎÎÎÎÎÎÎÎÎÍÍÍĚĚĚĘĘĘĘĘĘĘĘĘÇÇÇĹĹĹĹĹĹÇÇÇĚĚĚÇÇÇżżż······ŕŕŕďďďîîîęęęćććďďďöööîîîçççčččâââßßßľľľ···żżżÉÉÉĘĘĘĚĚĚÎÎÎŃŃŃŐŐŐ×××ŘŘŘÔÔÔÔÔÔŐŐŐŐŐŐŐŐŐÔÔÔŐŐŐŐŐŐÉÉÉĘĘĘĂĂĂĆĆĆĂĂĂżżżĘĘĘÎÎÎŐŐŐŃŃŃĐĐĐŐŐŐ×××ŇŇŇÎÎÎĐĐĐÎÎÎŇŇŇŮŮŮÍÍÍ»»»żżżÂÂÂłłł©©©­­­´´´şşşĽĽĽĽĽĽľľľżżżĹĹĹÉÉÉÍÍÍÎÎÎĐĐĐŃŃŃÔÔÔ×××ŐŐŐÍÍÍÎÎÎĆĆĆŐŐŐŘŘŘŰŰŰÎÎÎŘŘŘŘŘŘŮŮŮŮŮŮŘŘŘŘŘŘŰŰŰÝÝÝâââÝÝÝŕŕŕçççëëëďďďřřř˙˙˙üüüúúúőőőďďďňňňřřřöööíííçççćććÜÜÜÎÎÎĆĆĆĹĹĹĆĆĆĆĆĆŔŔŔĹĹĹĽĽĽşşşÇÇÇĐĐĐĐĐĐÔÔÔĐĐĐĐĐĐÍÍÍÇÇÇĹĹĹĆĆĆĆĆĆĆĆĆĘĘĘĚĚĚĹĹĹÉÉÉÉÉÉĆĆĆĆĆĆŔŔŔĂĂĂ»»»´´´±±±´´´żżżŃŃŃâââćććďďďďďďíííďďďęęęçççďďďóóóńńńÝÝÝŮŮŮŰŰŰŘŘŘŘŘŘÉÉÉÍÍÍŇŇŇŘŘŘŃŃŃÂÂÂ×××ÎÎÎÉÉÉľľľĆĆĆÎÎÎŐŐŐŮŮŮŮŮŮŐŐŐŃŃŃÎÎÎŃŃŃĆĆĆłłł°°°ľľľĹĹĹżżżÂ´´´°°°şşşŔŔŔÂÂÂŔŔŔŔŔŔŔŔŔÂÂÂÂÂÂŔŔŔŔŔŔżżżľľľĽĽĽ···¸¸¸şşşşşş»»»ÂÂÂĘĘĘĐĐĐÉÉÉĘĘĘĹĹĹżżżŔŔŔÇÇÇÇÇÇÂÂÂÎÎÎâââŰŰŰâââŐŐŐ°°°łłłµµµĽĽĽşşşşşşżżżÂÂÂĹĹĹĘĘĘŃŃŃŔŔŔµµµ°°°»»»ĚĚĚÔÔÔŐŐŐŐŐŐÎÎÎŃŃŃŃŃŃĐĐĐÍÍÍĚĚĚÍÍÍÎÎÎĐĐĐĘĘĘĹĹĹĹĹĹĘĘĘÍÍÍĘĘĘÇÇÇşşşŘŘŘßßßăăăęęęçççćććŕŕŕçççăăăçççßßß×××´´´µµµĆĆĆÍÍÍÎÎÎĐĐĐŃŃŃŐŐŐŮŮŮŘŘŘÔÔÔÔÔÔŐŐŐŐŐŐÔÔÔÔÔÔÔÔÔ×××ŘŘŘÉÉÉĘĘĘĂĂĂÇÇÇĹĹĹżżżÇÇÇĘĘĘĐĐĐÉÉÉĘĘĘÔÔÔŘŘŘÔÔÔĐĐĐŇŇŇĐĐĐŇŇŇŐŐŐĚĚĚşşşşşşÂÂÂżżż¬¬¬ŞŞŞ¬¬¬ŻŻŻ°°°łłłşşşŔŔŔżżżÂÂÂĆĆĆÉÉÉĚĚĚÎÎÎĐĐĐŃŃŃÔÔÔĐĐĐŇŇŇĹĹĹĐĐĐ×××ßßßĐĐĐ××××××ŘŘŘŰŰŰŰŰŰŰŰŰßßßăăăäääÝÝÝßßßîîîúúúüüüöööőőőöööňňňňňňööööööńńńŕŕŕĘĘĘŔŔŔĹĹĹĹĹĹĂĂĂĆĆĆĚĚĚÎÎÎĚĚĚŔŔŔÂÂÂľľľľľľÉÉÉĐĐĐŇŇŇŐŐŐĐĐĐÔÔÔ×××ÔÔÔĐĐĐÍÍÍĚĚĚĘĘĘÉÉÉÉÉÉĆĆĆĹĹĹĂĂĂÂÂÂĆĆĆÇÇÇżżżŔŔŔÂÂÂľľľ´´´łłłĂĂĂŐŐŐâââćććčččîîîňňňîîîëëëďďďíííîîîŰŰŰÜÜÜßßßŰŰŰÝÝÝĚĚĚÎÎÎÔÔÔŮŮŮĚĚĚĽĽĽŘŘŘÉÉÉżżżÂÂÂŃŃŃÜÜÜŮŮŮŘŘŘŰŰŰŮŮŮŃŃŃŐŐŐŃŃŃŔŔŔ°°°łłłŔŔŔĂĂĂ»»»ÂÂÂłłłŻŻŻ···ľľľÂÂÂĂĂĂżżżŔŔŔŔŔŔŔŔŔżżżżżżĽĽĽ»»»»»»»»»ľľľĽĽĽşşş»»»żżżÂÂÂÂÂÂŐŐŐŇŇŇÎÎÎÉÉÉÉÉÉĘĘĘÇÇÇĂĂĂÍÍÍçççŰŰŰâââ××ץĄĄµµµşşş»»»¸¸¸şşşżżżĂĂĂĹĹĹÉÉÉĐĐШ¨¨ŞŞŞ°°°´´´¸¸¸ĽĽĽľľľľľľŔŔŔ»»»şşşĂĂĂŇŇŇŮŮŮŐŐŐÍÍÍŇŇŇŇŇŇĐĐĐĚĚĚÇÇÇĹĹĹĆĆĆÇÇÇ»»»ľľľłłł»»»ŃŃŃâââęęęăăăäääŕŕŕćććŕŕŕŕŕŕÂÂÂŔŔŔÍÍÍÍÍÍŃŃŃŇŇŇŃŃŃŇŇŇŘŘŘŘŘŘŐŐŐ×××××××××ŐŐŐÔÔÔŐŐŐŮŮŮÜÜÜÍÍÍĚĚĚĹĹĹÇÇÇĆĆĆżżżÇÇÇĘĘĘĚĚĚĹĹĹĆĆĆŃŃŃŘŘŘÔÔÔŃŃŃÔÔÔŃŃŃŃŃŃ×××ŇŇŇĂĂø¸¸ĽĽĽĹĹĹ»»»µµµ°°°ŻŻŻ­­­ŻŻŻ···ŔŔŔşşşşşşĽĽĽżżżĂĂĂĹĹĹĹĹĹĹĹĹĐĐĐÍÍÍŐŐŐÉÉÉĚĚĚĐĐĐâââÝÝÝßßßÜÜÜÝÝÝŕŕŕßßßÜÜÜÝÝÝăăăâââÝÝÝäääóóó˙˙˙řřřňňňóóóďďďóóó˙˙˙üüüäääŃŃŃÉÉÉÂÂÂÎÎÎĐĐĐĐĐĐÎÎÎŃŃŃŐŐŐŇŇŇĚĚĚÔÔÔÍÍÍÉÉÉĆĆĆĹĹĹĘĘĘŇŇŇÔÔÔŮŮŮŘŘŘŮŮŮŰŰŰŰŰŰ×××ŇŇŇŇŇŇÇÇÇĆĆĆĆĆĆĂĂĂÂÂÂĂĂĂĹĹĹÇÇÇĹĹĹĘĘĘÎÎÎÎÎεµµ´´´»»»äääŕŕŕćććńńńóóóńńńíííçççňňňřřřäääâââÝÝÝŐŐŐßßßŃŃŃŇŇŇŇŇŇŰŰŰĚĚĚ»»»ÔÔÔÇÇÇĆĆĆŇŇŇŰŰŰßßßÜÜÜŰŰŰÜÜÜŮŮŮÔÔÔŐŐŐÉÉÉ»»»···şşşľľľżżżżżżĂĂĂ´´´°°°µµµĽĽĽĹĹĹÇÇÇżżżżżżżżżżżżľľľĽĽĽ»»»şşş¸¸¸şşşĽĽĽĽĽĽ»»»»»»żżżľľľ¸¸¸ÍÍÍĘĘĘÉÉÉĚĚĚĚĚĚÉÉÉÉÉÉÉÉÉĹĹĹÜÜÜŇŇŇŮŮŮ××צ¦¦···ľľľ»»»¸¸¸»»»ŔŔŔĂĂĂĂĂĂĹĹĹÉÉɬ¬¬···żżżĽĽĽľľľÂÂÂĹĹĹĂĂĂĂĂĂşşşłłłĽĽĽĐĐĐÜÜÜÜÜÜŐŐŐÎÎÎĐĐĐŃŃŃŃŃŃÍÍÍĘĘĘÉÉÉÉÉÉĆĆĆÇÇÇľľľĽĽĽşşşÂÂÂŰŰŰâââęęęääääääÜÜÜßßßĆĆĆĂĂĂĘĘĘÍÍÍŇŇŇÔÔÔÎÎÎĚĚĚŇŇŇŮŮŮŰŰŰŮŮŮŮŮŮŘŘŘŐŐŐÔÔÔŐŐŐŰŰŰßßßŃŃŃÎÎÎĆĆĆÇÇÇĆĆĆŔŔŔÉÉÉĚĚĚĚĚĚĂĂĂĹĹĹŃŃŃŘŘŘÔÔÔŃŃŃÔÔÔÍÍÍŃŃŃŮŮŮÝÝÝĐĐĐşşş···ĂĂĂľľľĽĽĽľľľŔŔŔĽĽĽ´´´łłłµµµµµµ´´´´´´···»»»ĽĽĽ»»»şşşĘĘĘÉÉÉ×××ÎÎÎĘĘĘÉÉÉâââëëëčččćććääääääŕŕŕŰŰŰŰŰŰßßßÝÝÝŕŕŕíííöööóóóëëëďďďúúú˙˙˙óóóďďďäääÍÍÍÂÂÂĚĚĚŇŇŇÔÔÔŃŃŃÎÎÎĚĚĚŃŃŃŘŘŘ×××ŃŃŃÔÔÔÎÎÎŇŇŇÔÔÔĚĚĚÎÎÎÔÔÔŃŃŃßßßŐŐŐĐĐĐÔÔÔ×××ŐŐŐÔÔÔÔÔÔŐŐŐŇŇŇŇŇŇĐĐĐĐĐĐŃŃŃĚĚĚĚĚĚĘĘĘĹĹĹĂĂĂÇÇÇĘĘĘĆĆĆŔŔŔżżżşşşłłłŔŔŔŘŘŘäääëëëíííćććëëëöööćććăăăÜÜÜ×××ęęęćććÔÔÔŃŃŃÜÜÜĐĐĐĽĽĽÔÔÔĚĚĚ×××âââßßßÜÜÜÝÝÝÝÝÝÜÜÜŮŮŮ×××ŃŃŃżżż···ľľľŔŔŔ»»»ľľľÇÇÇĹĹŵµµ±±±µµµ»»»ĆĆĆĘĘĘŔŔŔľľľľľľľľľľľľĽĽĽşşş¸¸¸···´´´¸¸¸şşşşşşľľľÂÂÂľľľ···ÔÔÔÎÎÎÍÍÍĐĐĐĚĚĚĂĂĂŔŔŔĂĂĂĹĹĹŐŐŐÎÎÎŇŇŇŐŐŐ¨¨¨ŻŻŻµµµ»»»şşşĽĽĽÂÂÂĂĂĂÂÂÂÂÂÂĹĹű±±ĽĽĽÂÂÂÂÂÂĚĚĚÜÜÜăăăÝÝÝĆĆĆĂĂĂľľľ···łłłşşşÉÉÉŐŐŐäääŰŰŰŃŃŃĚĚĚĚĚĚĚĚĚÉÉÉĆĆĆĚĚĚĆĆĆĂĂĂÇÇÇľľľ¸¸¸ŔŔŔ···şşş¸¸¸ľľľ»»»ĆĆĆ»»»ĂĂĂŃŃŃŇŇŇ×××ŇŇŇŇŇŇŰŰŰŮŮŮŐŐŐŮŮŮŘŘŘßßßŇŇŇŃŃŃ××××××ŰŰŰŮŮŮŇŇŇĐĐĐÇÇÇĹĹĹÇÇÇĂĂĂÂÂÂĚĚĚÍÍÍŔŔŔĂĂĂŃŃŃÔÔÔŇŇŇŇŇŇŇŇŇÎÎÎĐĐĐŮŮŮÜÜÜĐĐĐĹĹĹľľľ±±±ĹĹĹĂĂĂÂÂÂÂÂÂŔŔŔĽĽĽ´´´ŻŻŻ°°°łłłĹĹĹŃŃŃĹĹĹşşş¸¸¸µµµŔŔŔÇÇÇĘĘĘÉÉÉÇÇÇĘĘĘĘĘĘÇÇÇĚĚĚÍÍÍčččÜÜÜăăăăăăÜÜÜÝÝÝÜÜÜŕŕŕíííďďďîîîööö˙˙˙öööüüüăăăÉÉÉĘĘĘÔÔÔŃŃŃŇŇŇÔÔÔŃŃŃÔÔÔÎÎÎŐŐŐŮŮŮÔÔÔ×××ÔÔÔÍÍÍĐĐĐŃŃŃĐĐĐÍÍÍÍÍÍŇŇŇŘŘŘŰŰŰŘŘŘ××××××ÔÔÔŃŃŃ×××ŕŕŕßßßÜÜÜ×××ŃŃŃÎÎÎÍÍÍĐĐĐŇŇŇŃŃŃŐŐŐÉÉÉÎÎÎÔÔÔŃŃŃĐĐĐ»»»żżżşşşĆĆĆżżżżżżÜÜÜîîîöööďďďńńńóóóëëëÜÜÜŕŕŕćććßßß×××ÎÎÎÔÔÔŃŃŃĆĆĆĐĐĐŃŃŃżżżăăăŕŕŕßßßŕŕŕŕŕŕßßßŰŰŰŘŘŘÇÇÇżżżşşşşşş»»»»»»ľľľÂÂÂÂÂÂĂĂĂŞŞŞŞŞŞľľľżżżŔŔŔĹĹĹżżżľľľĽĽĽ»»»şşş¸¸¸¸¸¸¸¸¸şşşşşşľľľĂĂõµµ»»»···ĘĘĘĂĂĂĚĚĚĐĐĐĚĚĚÇÇÇĆĆĆĹĹĹÂÂÂÂÂÂÇÇÇĐĐĐÍÍÍŃŃŃÉÉɱ±±ŻŻŻĽĽĽ······ĹĹĹľľľĽĽĽĚĚĚĽĽĽ±±±´´´ľľľÎÎÎŃŃŃâââŮŮŮâââÝÝÝÍÍÍĆĆƸ¸¸···»»»şşşŮŮŮŘŘŘÔÔÔÍÍÍÍÍÍÎÎÎĘĘĘĂĂĂĚĚĚĚĚĚĚĚĚĘĘĘÇÇÇĂĂĂżżżĽĽĽşşş»»»ĽĽĽľľľŔŔŔĹĹĹĘĘĘĐĐĐŐŐŐŘŘŘÔÔÔÔÔÔŰŰŰŰŰŰŮŮŮßßßÝÝÝëëëâââÜÜÜßßßÝÝÝŮŮŮÍÍÍŇŇŇĐĐĐÇÇÇĂĂĂĆĆĆÂÂÂÂÂÂĚĚĚÍÍÍÂÂÂĆĆĆÔÔÔÔÔÔŃŃŃŇŇŇŃŃŃĚĚĚÉÉÉŃŃŃŘŘŘÔÔÔŃŃŃÉÉÉ»»»ĽĽĽ»»»»»»ľľľŔŔŔĂĂĂÂÂÂŔŔŔÇÇÇĹĹĹĘĘĘĐĐĐÇÇÇÂÂÂŔŔŔşşşĹĹĹĘĘĘĚĚĚÉÉÉÇÇÇĘĘĘĚĚĚĘĘĘĚĚĚÎÎÎëëëßßßćććäääÜÜÜÝÝÝăăăćććîîîńńńíííňňňöööńńńÜÜÜÔÔÔÉÉÉÉÉÉĐĐĐÔÔÔ×××ŐŐŐŃŃŃŮŮŮÔÔÔ×××ŘŘŘŰŰŰÝÝÝÔÔÔŐŐŐÔÔÔŃŃŃĐĐĐŃŃŃŐŐŐŰŰŰÝÝÝőőőćććŘŘŘ××××××ĐĐĐĆĆĆżżżżżżżżżľľľşşşşşşĂĂĂŐŐŐäääŇŇŇÝÝÝ×××ÔÔÔĚĚĚÇÇÇĐĐĐÍÍÍĆĆĆĹĹĹÉÉÉľľľĽĽĽĘĘĘ×××íííóóóďďďůůůůůůćććÝÝÝßßßŘŘŘçççŘŘŘŮŮŮ×××ĘĘĘŇŇŇÜÜÜŇŇŇŰŰŰßßßßßßŰŰŰŮŮŮÜÜÜÜÜÜ××׿żżşşş¸¸¸»»»ĽĽĽĽĽĽżżżĹĹĹĂĂĂĹĹĹ­­­¬¬¬ľľľľľľĽĽĽľľľÂÂÂŔŔŔľľľ»»»¸¸¸·········¸¸¸şşşĽĽĽŔŔŔ···ÂÂÂĽĽĽĘĘĘĆĆĆÍÍÍĐĐĐĘĘĘĆĆĆĆĆĆĆĆĆĹĹĹÇÇÇÂÂÂĚĚĚÎÎÎĐĐĐÎÎÎĽĽĽ´´´şşş¸¸¸şşşÂÂÂżżżĹĹĹĚĚĚ´´´´´´´´´¸¸¸ÂÂÂĆĆĆŰŰŰŐŐŐÝÝÝâââÎÎÎĂĂĂÂÂÂżżżżżżŔŔŔĽĽĽÇÇÇŃŃŃŐŐŐŃŃŃĘĘĘÉÉÉĘĘĘÉÉÉÉÉÉĘĘĘĚĚĚĚĚĚĘĘĘĆĆĆÂÂÂżżżÂÂÂÂÂÂÂÂÂĂĂĂÇÇÇĚĚĚŃŃŃÔÔÔŐŐŐŰŰŰŰŰŰŰŰŰÝÝÝÜÜÜŘŘŘŮŮŮÔÔÔŕŕŕĐĐĐĹĹĹĚĚĚ×××ŮŮŮÎÎÎÔÔÔĐĐĐĆĆĆÂÂÂĂĂĂŔŔŔŔŔŔĘĘĘĘĘĘĂĂĂĘĘĘŐŐŐÔÔÔĐĐĐĐĐĐÎÎÎĚĚĚÇÇÇĚĚĚÔÔÔŮŮŮŮŮŮÎÎÎżżżŔŔŔľľľĽĽĽĽĽĽżżżÂÂÂĂĂĂĹĹĹĐĐĐĘĘĘÉÉÉÉÉÉÉÉÉĚĚĚĆĆĆ»»»ĆĆĆĘĘĘĚĚĚĘĘĘÉÉÉĚĚĚÍÍÍÍÍÍÍÍÍŃŃŃîîîâââçççäääÜÜÜÝÝÝäääçççîîîńńńîîîńńńóóóďďďĂĂĂĘĘĘÎÎÎĚĚĚÎÎÎŘŘŘŰŰŰ×××ŇŇŇßßßŘŘŘŮŮŮŘŘŘßßßŕŕŕŇŇŇ×××ÔÔÔŃŃŃŃŃŃŐŐŐŘŘŘŰŰŰŰŰŰĂĂĂÇÇÇÉÉÉĆĆĆĽĽĽşşşĂĂĂĐĐĐâââäääćććŕŕŕ×××ÍÍÍÉÉÉÇÇÇĚĚĚ×××ŘŘŘŮŮŮÔÔÔĐĐĐŐŐŐŇŇŇÎÎÎĐĐĐĚĚĚÂÂÂżżżĽĽĽĂĂĂäääöööîîîőőőůůůčččßßßăăăäääŕŕŕŃŃŃ×××ÜÜÜÎÎÎĐĐĐÜÜÜ×××ĐĐĐÜÜÜŕŕŕŰŰŰŮŮŮÝÝÝŰŰŰŃŃŃşşş···¸¸¸»»»ĽĽĽ»»»żżżĹĹĹĹĹĹĹĹĹŻŻŻ°°°żżżżżżżżżľľľÂÂÂŔŔŔľľľşşş¸¸¸µµµµµµµµµ»»»ĽĽĽĽĽĽľľľ¸¸¸ÉÉÉŔŔŔĆĆĆÉÉÉÍÍÍÎÎÎĘĘĘĹĹĹĆĆĆÇÇÇÉÉÉÇÇÇ»»»ÉÉÉŇŇŇŃŃŃĐĐĐľľľ¬¬¬¸¸¸şşşĽĽĽÂÂÂÂÂÂÉÉÉÇÇǬ¬¬°°°łłł´´´ĽĽĽÂÂÂßßßŰŰŰßßßâââÔÔÔÍÍÍĘĘĘĆĆĆĂĂĂĂĂĂŔŔŔşşşĘĘĘŘŘŘŐŐŐĘĘĘĹĹĹÇÇÇÍÍÍÇÇÇÉÉÉĚĚĚÍÍÍĚĚĚĘĘĘÇÇÇĹĹĹĂĂĂÂÂÂÂÂÂĂĂĂÇÇÇÍÍÍŃŃŃÔÔÔÜÜÜßßßÝÝÝŮŮŮŘŘŘŘŘŘ×××ŐŐŐâââäääĚĚĚżżżÉÉÉŇŇŇÜÜÜ×××ŇŇŇĐĐĐĹĹĹŔŔŔÂÂÂżżżżżżÉÉÉÇÇÇĹĹĹÎÎÎŘŘŘŇŇŇÍÍÍÍÍÍĚĚĚÎÎÎÍÍÍĐĐĐ×××ŮŮŮŐŐŐÉÉÉ»»»ĆĆĆĂĂĂżżżĽĽĽĽĽĽľľľżżżŔŔŔĆĆĆĆĆĆĹĹĹÂÂÂĹĹĹÇÇÇżżż±±±ŔŔŔĹĹĹÉÉÉĚĚĚĚĚĚÍÍÍÎÎÎÎÎÎĐĐĐŇŇŇďďďâââäääăăăÜÜÜßßßßßßăăăčččîîîńńńóóóőőőóóóĚĚĚĘĘĘÔÔÔŇŇŇĐĐĐŮŮŮŘŘŘŐŐŐ×××ŕŕŕßßßęęęăăăęęęęęęŕŕŕëëëęęęäääÝÝÝŐŐŐÍÍÍÇÇÇĂĂĂÉÉÉĆĆĆĆĆĆĚĚĚÔÔÔŘŘŘŘŘŘ×××ÂÂÂŔŔŔĹĹĹÎÎÎŮŮŮââââââßßßĐĐĐÍÍÍÉÉÉĐĐĐŮŮŮŰŰŰŐŐŐĘĘĘŃŃŃĐĐĐÍÍÍÍÍÍĚĚĚżżżÂÂÂÜÜÜîîîńńńőőőóóóíííääääääííí×××ĚĚĚĐĐĐŰŰŰÎÎÎÉÉÉŮŮŮŮŮŮÍÍÍŐŐŐŰŰŰÝÝÝßßßÝÝÝŇŇŇĆĆĆ»»»şşşşşş»»»¸¸¸···»»»ÂÂÂĂĂĂĂĂĂ°°°±±±ľľľżżżÂÂÂÂÂÂľľľĽĽĽ»»»¸¸¸······µµµ···ľľľŔŔŔĽĽĽ»»»¸¸¸ÎÎÎĂĂĂÂÂÂÉÉÉÍÍÍĐĐĐÍÍÍÉÉÉĆĆĆÇÇÇĘĘĘĘĘĘĽĽĽĹĹĹĘĘĘÍÍÍÉÉɵµµ¨¨¨şşşşşşżżżĂĂĂżżżŔŔŔĽĽĽŞŞŞŞŞŞ°°°´´´»»»ĂĂĂŕŕŕŮŮŮ×××ÜÜÜŰŰŰŰŰŰŘŘŘÍÍÍĂĂĂĂĂĂÇÇÇ»»»ÇÇÇÔÔÔŐŐŐĐĐĐĚĚĚĘĘĘĚĚĚĚĚĚĚĚĚĚĚĚÍÍÍÍÍÍĚĚĚĘĘĘĘĘĘĆĆĆĹĹĹĹĹĹĆĆĆĘĘĘÎÎÎŇŇŇŐŐŐâââŕŕŕÜÜÜÔÔÔŃŃŃ×××ÜÜÜŮŮŮÜÜÜÜÜÜÍÍÍŃŃŃÜÜÜŰŰŰÝÝÝÜÜÜŇŇŇÎÎÎĹĹĹŔŔŔÂÂÂľľľľľľÇÇÇĆĆĆĆĆĆŃŃŃŘŘŘŇŇŇÍÍÍÎÎÎĚĚĚÍÍÍŇŇŇ×××ŮŮŮŘŘŘÍÍÍżżż¸¸¸żżżżżżľľľľľľľľľżżżÂÂÂĂĂĂĹĹĹÉÉÉĆĆĆŔŔŔŔŔŔŔŔŔ»»»łłłµµµ»»»ĹĹĹĚĚĚÎÎÎÎÎÎÎÎÎĐĐĐŇŇŇŇŇŇëëëÜÜÜŕŕŕâââÜÜÜŕŕŕÜÜÜßßßäääëëëńńńóóóóóóőőőŕŕŕÉÉÉÎÎÎŇŇŇŃŃŃ×××ŇŇŇŐŐŐÝÝÝßßßŮŮŮčččŃŃŃÉÉÉĂĂĂľľľÂÂÂĹĹĹĆĆĆĂĂĂżżżľľľÂÂÂĆĆĆÉÉÉĚĚĚÎÎÎŇŇŇ×××ÔÔÔĘĘĘÂÂÂßßßŐŐŐĚĚĚÉÉÉÍÍÍĐĐĐÎÎÎĚĚĚçççŰŰŰĐĐĐÎÎÎÔÔÔŮŮŮ×××ÔÔÔÎÎÎĚĚĚĚĚĚŐŐŐÔÔÔÇÇÇĆĆĆĐĐĐÜÜÜöööúúúőőőöööęęęŰŰŰâââăăăŰŰŰŃŃŃ×××ÎÎÎĆĆĆŮŮŮăăăŐŐŐÍÍÍĚĚĚÔÔÔŮŮŮŇŇŇĹĹĹĽĽĽľľľşşş¸¸¸¸¸¸···µµµĽĽĽĂĂĂÂÂÂŔŔŔ°°°ŻŻŻµµµµµµ»»»»»»···············¸¸¸¸¸¸¸¸¸»»»ľľľ»»»şşşşşşŃŃŃÇÇÇĂĂĂÇÇÇĚĚĚĐĐĐŃŃŃÎÎÎÉÉÉÇÇÇÉÉÉÎÎÎĹĹĹĂĂĂĂĂĂÉÉÉĹĹű±±łłłľľľ¸¸¸ŔŔŔĹĹĹľľľµµµ°°°ŻŻŻ­­­±±±łłł¸¸¸żżżŰŰŰŇŇŇĐĐĐŘŘŘŰŰŰÝÝÝßßßŘŘŘÍÍÍÇÇÇĚĚĚĂĂĂĂĂĂÉÉÉŃŃŃŘŘŘŘŘŘŇŇŇÎÎÎŇŇŇŃŃŃÎÎÎÍÍÍĚĚĚÍÍÍÍÍÍÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎŇŇŇ×××ŰŰŰÝÝÝÜÜÜÝÝÝŕŕŕßßßÝÝÝăăăâââŐŐŐĘĘĘÍÍÍĆĆĆÔÔÔŕŕŕŰŰŰŮŮŮŰŰŰĐĐĐÍÍÍĹĹĹŔŔŔÂÂÂĽĽĽ»»»ĂĂĂĘĘĘĘĘĘŐŐŐŰŰŰŐŐŐŇŇŇŇŇŇÎÎÎĚĚĚŐŐŐŰŰŰŰŰŰ×××ÉÉÉľľľ»»»ľľľżżżŔŔŔŔŔŔżżżŔŔŔÂÂÂĹĹĹĹĹĹÉÉÉĆĆĆŔŔŔĂĂĂĹĹĹĹĹĹĆĆĆŻŻŻµµµŔŔŔĚĚĚĐĐĐÎÎÎÎÎÎĐĐĐŇŇŇĐĐĐććć×××ÝÝÝŕŕŕÜÜÜßßßÝÝÝŕŕŕâââčččńńńńńńîîîńńńęęęŔŔŔÂÂÂÍÍÍĐĐĐÔÔÔÎÎÎŘŘŘŕŕŕŕŕŕÝÝÝóóóŐŐŐÍÍÍĚĚĚÍÍÍŃŃŃĐĐĐĚĚĚĆĆĆŔŔŔĂĂĂĘĘĘŃŃŃÍÍÍŘŘŘÝÝÝŘŘŘĐĐĐÍÍÍŇŇŇ×××ÍÍÍĐĐĐÔÔÔ×××ŘŘŘŘŘŘŮŮŮŰŰŰĐĐĐÍÍÍĐĐĐĘĘĘĂĂĂĂĂĂĆĆĆŃŃŃĚĚĚĐĐĐÍÍÍÔÔÔÔÔÔĚĚĚÉÉÉĹĹĹÍÍÍíííöööńńńöööíííßßßäääçççëëë×××ŘŘŘ×××ĹĹĹÎÎÎŰŰŰÝÝÝĘĘĘżżżĹĹĹĚĚĚĹĹĹĽĽĽ»»»ľľľ¸¸¸µµµ···¸¸¸şşşŔŔŔÇÇÇĂĂĂĂĂĂ´´´°°°­­­¨¨¨ŻŻŻ­­­­­­°°°łłłµµµ¸¸¸¸¸¸¸¸¸¸¸¸µµµ¸¸¸¸¸¸¸¸¸¸¸¸ŃŃŃÉÉÉÉÉÉĆĆĆĘĘĘŃŃŃ×××ŇŇŇĘĘĘÇÇÇÉÉÉĹĹĹÇÇÇÎÎÎŃŃŃŐŐŐÇÇÇ°°°···ŔŔŔ¸¸¸ŔŔŔĹĹĹżżż´´´¬¬¬łłłłłł´´´´´´»»»ŔŔŔÝÝÝŰŰŰŕŕŕŘŘŘ×××ÔÔÔŰŰŰăăăÜÜÜĐĐĐĚĚĚÇÇÇŔŔŔżżżÉÉÉ×××ŰŰŰŮŮŮŐŐŐ×××ŐŐŐŃŃŃÎÎÎÍÍÍÎÎÎÎÎÎĐĐĐÎÎÎĐĐĐŃŃŃŃŃŃŇŇŇŐŐŐŰŰŰßßßăăăäääëëëíííęęęîîîćććŃŃŃÔÔÔŮŮŮŃŃŃŐŐŐÜÜÜŐŐŐÔÔÔŇŇŇÎÎÎÍÍÍĹĹĹÂÂÂĂĂĂĽĽĽşşşŔŔŔĐĐĐĐĐĐŮŮŮßßßŰŰŰŮŮŮŰŰŰÔÔÔŃŃŃŮŮŮŰŰŰŘŘŘŐŐŐĘĘĘżżżżżżĂĂĂĹĹĹĹĹĹĂĂĂŔŔŔŔŔŔÂÂÂĹĹĹĆĆĆĆĆĆÂÂÂÂÂÂÉÉÉĆĆĆŔŔŔĆĆĆŻŻŻ´´´żżżĚĚĚĐĐĐÎÎÎÎÎÎŃŃŃĐĐĐĚĚĚŕŕŕŇŇŇÜÜÜŕŕŕŰŰŰŰŰŰÝÝÝŕŕŕŕŕŕçççńńńîîîčččîîîčččşşşżżżĚĚĚÎÎÎŐŐŐĐĐĐŰŰŰßßßăăăßßßďďďÉÉÉÇÇÇĘĘĘÎÎÎćććßßßŐŐŐÎÎÎĚĚĚĚĚĚĘĘĘĘĘĘßßß×××ĚĚĚÉÉÉÎÎÎ×××ŇŇŇÉÉÉĹĹĹĆĆĆÉÉÉĘĘĘÉÉÉÉÉÉĚĚĚÎÎÎĐĐĐÎÎÎŰŰŰŮŮŮŐŐŐÔÔÔĐĐĐŰŰŰÇÇÇÝÝÝÔÔÔÍÍÍŇŇŇÎÎÎÎÎÎĚĚĚĹĹĹŮŮŮëëëńńńńńńęęęçççęęęâââóóóŘŘŘ×××ßßßĆĆĆĹĹĹŇŇŇÝÝÝĐĐĐĹĹĹĂĂĂĹĹĹŔŔŔżżżżżżŔŔŔ»»»···şşşĽĽĽĽĽĽŔŔŔĹĹĹĹĹĹÇÇÇľľľ¸¸¸ŻŻŻĄĄĄŞŞŞ¨¨¨¨¨¨¬¬¬±±±µµµ¸¸¸¸¸¸···µµµµµµ¸¸¸şşş»»»···ĘĘĘĂĂĂÇÇÇĆĆĆĘĘĘŇŇŇŘŘŘÔÔÔĚĚĚÇÇÇĘĘĘŔŔŔĆĆĆŰŰŰŕŕŕ×××ÂÂÂŻŻŻµµµÂ¸¸¸żżżÂÂÂĂĂĂżżż°°°łłł´´´´´´µµµżżżĂĂĂŰŰŰŘŘŘâââÝÝÝŘŘŘĐĐĐ×××äääŕŕŕŃŃŃĚĚĚĘĘĘĂĂĂŔŔŔĂĂĂÉÉÉÍÍÍŇŇŇŮŮŮŐŐŐŐŐŐÔÔÔŇŇŇŇŇŇŃŃŃŃŃŃĐĐĐÍÍÍĐĐĐŇŇŇŃŃŃĐĐĐŃŃŃŮŮŮßßßúúúőőőńńńęęęćććîîîëëëŘŘŘÍÍÍŮŮŮÔÔÔŐŐŐŰŰŰ×××ŐŐŐÎÎÎÍÍÍĚĚĚĹĹĹÂÂÂĂĂĂĽĽĽ¸¸¸żżżÔÔÔÔÔÔÜÜÜâââßßßßßßŕŕŕŮŮŮŮŮŮÝÝÝŮŮŮŐŐŐ×××ÍÍÍŔŔŔŔŔŔĹĹĹĆĆĆĆĆĆĂĂĂÂÂÂĂĂĂÇÇÇĚĚĚĚĚĚÉÉÉÂÂÂĹĹĹĘĘĘĽĽĽ¬¬¬¬¬¬łłłµµµżżżĚĚĚĐĐĐÍÍÍÎÎÎÔÔÔĚĚĚÇÇÇÝÝÝŃŃŃÜÜÜŕŕŕŘŘŘŘŘŘŰŰŰÝÝÝÝÝÝäääńńńîîîčččďďďççç»»»ĹĹĹÎÎÎĐĐĐŘŘŘŇŇŇÜÜÜÝÝÝçççâââëëëŔŔŔÇÇÇĐĐĐŃŃŃçççßßßŮŮŮŰŰŰââââââŰŰŰŃŃŃĹĹĹĐĐĐŐŐŐŇŇŇÍÍÍĘĘĘÇÇÇÂÂÂßßßÜÜÜŰŰŰÝÝÝâââăăăŕŕŕÜÜÜŰŰŰĘĘĘĘĘĘĘĘĘŇŇŇ×××ÉÉÉĘĘĘĆĆĆëëëŮŮŮÉÉÉŇŇŇÔÔÔ×××ŮŮŮÂÂÂÍÍÍëëë˙˙˙őőőćććâââÝÝÝäääüüü×××ĐĐĐŕŕŕĘĘĘĘĘĘÝÝÝŘŘŘ×××ŇŇŇĚĚĚÇÇÇĆĆĆĹĹĹĂĂĂĹĹĹľľľ»»»ĽĽĽżżżĽĽĽĽĽĽżżżĹĹĹĘĘĘĆĆĆĂĂõµµŞŞŞŻŻŻ¬¬¬ĄĄĄ©©©°°°µµµ¸¸¸···´´´łłłşşşĽĽĽĽĽĽĽĽĽ´´´Â»»»ĂĂĂÇÇÇĘĘĘŃŃŃŘŘŘŐŐŐĚĚĚÉÉÉĚĚĚĚĚĚÉÉÉÜÜÜÜÜÜĹĹĹ´´´°°°¸¸¸ŔŔŔşşşżżżżżżÇÇÇÍÍÍ···°°°łłł±±±´´´ľľľĽĽĽÉÉÉżżżÇÇÇăăăßßßŐŐŐ×××ßßßŮŮŮÍÍÍÍÍÍÍÍÍÉÉÉĆĆĆÂÂÂĽĽĽĽĽĽÉÉÉŘŘŘŇŇŇÔÔÔŐŐŐ×××ŐŐŐÔÔÔŃŃŃĐĐĐĐĐĐŐŐŐŮŮŮ×××ÔÔÔŐŐŐÝÝÝćććčččíííäääŰŰŰńńńřřřćććčččĘĘĘÔÔÔßßßŕŕŕŮŮŮŃŃŃĚĚĚĘĘĘĐĐĐÍÍÍżżżĚĚĚŔŔŔ»»»ĽĽĽĹĹĹŇŇŇŮŮŮßßßÝÝÝÜÜÜÝÝÝÜÜÜŘŘŘŮŮŮÔÔÔŇŇŇÔÔÔĚĚĚľľľşşşŔŔŔĂĂĂĆĆĆĹĹĹÂÂÂŔŔŔŔŔŔ»»»±±±°°°±±±ĽĽĽÇÇÇżżż­­­©©©°°°···şşşŔŔŔÉÉÉÎÎÎŃŃŃÎÎÎĚĚĚÇÇÇĚĚĚŐŐŐÝÝÝÝÝÝŘŘŘŮŮŮâââßßßÝÝÝßßßöööńńńččč˙˙˙îîîßßßĆĆĆşşşĘĘĘÇÇÇŐŐŐÔÔÔ×××ŰŰŰŕŕŕŕŕŕäääŇŇŇżżżĚĚĚÔÔÔÜÜÜĐĐĐĐĐĐĆĆĆĂĂĂÉÉÉÉÉÉŘŘŘÉÉÉÍÍÍĚĚĚÂÂÂľľľĆĆĆŇŇŇŰŰŰŇŇŇŇŇŇÔÔÔŐŐŐ×××ŘŘŘŮŮŮŮŮŮŮŮŮ×××ŘŘŘŮŮŮŇŇŇÉÉÉÍÍÍŮŮŮÎÎÎÉÉÉŰŰŰŮŮŮŘŘŘŃŃŃŰŰŰŃŃŃÎÎλ»»őőőřřřňňňőőőęęęăăăëëëîîîÝÝÝŘŘŘâââĐĐĐĆĆĆßßßßßß×××ÎÎÎĘĘĘĘĘĘĚĚĚĘĘĘÇÇÇĂĂĂÂÂÂżżżĽĽĽ»»»»»»ĽĽĽĽĽĽÂÂÂÉÉÉ»»»»»»łłłŞŞŞ­­­¦¦¦˘˘˘¦¦¦´´´ĽĽĽşşşµµµ´´´µµµşşşĽĽĽ»»»»»»żżżŔŔŔżżżÉÉÉĐĐĐÎÎÎÔÔÔÇÇÇĚĚĚÉÉÉĐĐĐĘĘĘĆĆĆŐŐŐÝÝÝĐĐЬ¬¬···»»»ĽĽĽĽĽĽşşşľľľÎÎÎŮŮŮÉÉÉ­­­łłł±±±···żżżĂĂĂÂÂÂĂĂĂÉÉÉÉÉÉŃŃŃÔÔÔŇŇŇŘŘŘÝÝÝ×××ÉÉÉÉÉÉŇŇŇĐĐĐÇÇÇÇÇÇÇÇÇĆĆĆĘĘĘŐŐŐŇŇŇŮŮŮ×××ŐŐŐŘŘŘŃŃŃŐŐŐŮŮŮŰŰŰŰŰŰŮŮŮŮŮŮßßßęęęóóóâââčččëëëăăăçççęęęŕŕŕëëëçççâââŮŮŮÔÔÔŃŃŃÎÎÎĚĚĚÉÉÉÎÎÎĘĘĘşşşÇÇÇľľľżżżĹĹĹÎÎÎĐĐĐŘŘŘÝÝÝÜÜÜŮŮŮŮŮŮŘŘŘŐŐŐŇŇŇÍÍÍÎÎÎŇŇŇĚĚĚżżż»»»żżżżżżĂĂĂĹĹĹÂÂÂŔŔŔÂÂÂľľľ···´´´±±±±±±łłł­­­¨¨¨­­­¸¸¸şşşĽĽĽÂÂÂÉÉÉÎÎÎĐĐĐÍÍÍĘĘĘÉÉÉÉÉÉÍÍÍŐŐŐÜÜÜÜÜÜÝÝÝÝÝÝÜÜÜŕŕŕâââőőőďďďííí˙˙˙îîîęęę××׾ľľĆĆĆĂĂĂĐĐĐÔÔÔŘŘŘÜÜÜŕŕŕßßßŕŕŕ×××ĹĹĹÇÇÇŃŃŃŃŃŃĐĐĐ×××ŮŮŮ×××ÔÔÔĐĐĐÔÔÔĂĂĂĐĐĐŰŰŰŰŰŰ×××ÔÔÔŃŃŃÍÍÍĚĚĚĚĚĚĚĚĚÍÍÍÎÎÎĐĐĐĐĐĐŃŃŃÍÍÍÉÉÉĘĘĘŃŃŃĐĐĐÇÇÇĆĆĆÍÍÍŃŃŃßßßŃŃŃĹĹĹçççÜÜÜÍÍÍŮŮŮÔÔÔľľľÝÝÝîîîőőőňňňďďďćććîîîčččŰŰŰŘŘŘŕŕŕŐŐŐĘĘĘŇŇŇŰŰŰŐŐŐŇŇŇÔÔÔ×××ÔÔÔĚĚĚĂĂĂĆĆĆĹĹĹÂÂÂżżżĽĽĽĽĽĽĽĽĽĽĽĽÂÂÂĹĹĹĆĆĆĆĆĆĂĂĂľľľľľľĆĆƸ¸¸°°°°°°µµµşşş»»»ĽĽĽ»»»µµµłłł¸¸¸żżżŔŔŔÂÂÂĂĂĂŮŮŮŮŮŮŃŃŃ×××ÍÍÍŇŇŇĘĘĘĘĘĘĚĚĚÍÍÍÝÝÝäääŇŇҬ¬¬¸¸¸ľľľ¸¸¸ľľľżżżżżżĆĆĆĐĐĐŇŇŇÎÎÎĂĂĂŔŔŔşşş±±±łłłĽĽĽŔŔŔľľľĐĐĐŐŐŐ×××ŐŐŐŮŮŮŕŕŕÜÜÜŃŃŃŃŃŃÝÝÝßßßŐŐŐĐĐĐĘĘĘÉÉÉÍÍÍîîîßßßŘŘŘĐĐĐÔÔÔßßßÝÝÝâââăăăęęęîîîëëëäääŕŕŕăăăçççăăăăăăëëëćććŕŕŕßßßÜÜÜçççŕŕŕŰŰŰÔÔÔŃŃŃŇŇŇŇŇŇÎÎÎĘĘĘÇÇÇĆĆƸ¸¸ÉÉÉĹĹĹÇÇÇÍÍÍÔÔÔÍÍÍ×××ÜÜÜŰŰŰ×××ŐŐŐŇŇŇĐĐĐŃŃŃÍÍÍÎÎÎŃŃŃÍÍÍŔŔŔĽĽĽżżżĽĽĽŔŔŔĂĂĂĂĂĂÂÂÂÂÂÂŔŔŔľľľŞŞŞ­­­°°°±±±°°°°°°łłł´´´»»»ľľľÂÂÂÇÇÇÍÍÍÍÍÍĘĘĘÇÇÇĘĘĘÇÇÇĆĆĆĚĚĚŘŘŘâââŕŕŕŰŰŰŰŰŰŕŕŕăăăňňňďďďďďď˙˙˙îîîîîîćććŔŔŔĹĹĹĹĹĹÍÍÍŐŐŐŘŘŘÜÜÜÝÝÝÜÜÜŰŰŰÜÜÜÎÎÎÂÂÂÎÎÎŃŃŃŃŃŃÎÎÎŃŃŃĐĐĐĚĚĚŇŇŇŐŐŐĐĐĐŇŇŇŃŃŃÍÍÍĘĘĘĚĚĚÎÎÎĐĐĐĆĆĆÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÉÉÉÉÉÉĆĆĆżżżżżżÇÇÇĘĘĘÇÇÇĹĹĹÇÇÇŃŃŃĐĐĐĐĐĐĘĘĘŇŇŇÍÍÍÍÍÍÍÍÍŇŇŇÂÂÂÇÇÇäääůůůńńńóóóćććîîîăăăŘŘŘŘŘŘÝÝÝÜÜÜŃŃŃÇÇÇÜÜÜŮŮŮ×××××××××ŐŐŐŃŃŃÎÎÎĘĘĘÉÉÉĹĹĹÂÂÂżżżľľľľľľľľľŔŔŔżżżĹĹĹÇÇÇŔŔŔĽĽĽŔŔŔĆĆĆżżż¸¸¸°°°­­­±±±¸¸¸şşş···µµµ¸¸¸»»»ĽĽĽżżżŔŔŔŔŔŔżżżÇÇÇĐĐĐĐĐĐ×××ĚĚĚÎÎÎĘĘĘĐĐĐÍÍÍŃŃŃäääččč××ׯŻŻ»»»ĹĹĹ»»»ŔŔŔĂĂĂĂĂĂĂĂĂĘĘĘŘŘŘăăăŐŐŐŇŇŇÉÉÉ»»»···ĽĽĽÂÂÂÂÂÂĐĐĐ×××ŮŮŮŰŰŰŕŕŕäääŕŕŕ×××ăăăçççăăăŕŕŕăăăÜÜÜÎÎÎÇÇÇćććÜÜÜßßßÜÜÜŕŕŕäääÜÜÜÜÜÜŕŕŕćććęęęćććŰŰŰĐĐĐĚĚĚĚĚĚďďďÝÝÝââââââÜÜÜÝÝÝŰŰŰÜÜÜŃŃŃŇŇŇÔÔÔŇŇŇÎÎÎĚĚĚÉÉÉÇÇÇŔŔŔĹĹĹľľľÔÔÔŇŇŇŇŇŇĐĐĐĐĐĐĘĘĘÔÔÔŰŰŰŘŘŘÔÔÔŃŃŃĐĐĐÍÍÍÔÔÔĐĐĐÎÎÎĐĐĐĘĘĘÂÂÂĽĽĽżżżĽĽĽŔŔŔĹĹĹĂĂĂÂÂÂŔŔŔŔŔŔŔŔŔĄĄĄŻŻŻ¸¸¸»»»żżżŔŔŔĽĽĽ´´´şşş»»»żżżĆĆĆĘĘĘĚĚĚÉÉÉĆĆĆÉÉÉÇÇÇĂĂĂĆĆĆŇŇŇŕŕŕŕŕŕŮŮŮŰŰŰÝÝÝâââňňňňňňîîîřřřďďďćććęęęŔŔŔĆĆĆÉÉÉÎÎÎŐŐŐÔÔÔŘŘŘŘŘŘŘŘŘ×××ßßßŐŐŐżżżÎÎÎŐŐŐŐŐŐÇÇÇÇÇÇĆĆĆĹĹĹŐŐŐŘŘŘÎÎÎĚĚĚÇÇÇĂĂĂÂÂÂĹĹĹÉÉÉĘĘĘĘĘĘĘĘĘÉÉÉÉÉÉÇÇÇÇÇÇÇÇÇĆĆĆĘĘĘÂÂÂľľľŔŔŔĹĹĹĆĆĆÉÉÉÎÎÎĹĹĹÎÎÎÎÎÎÍÍÍŮŮŮ×××ÔÔÔÜÜÜÎÎÎÇÇÇÂÂÂŮŮŮňňňňňňńńńćććčččäääŰŰŰ×××ÝÝÝâââŘŘŘĚĚĚ×××ŮŮŮŰŰŰŘŘŘŐŐŐÔÔÔ×××ŰŰŰĐĐĐÍÍÍÉÉÉĹĹĹÂÂÂŔŔŔżżżżżżľľľ»»»ÂÂÂĂĂĂĽĽĽĽĽĽżżż···¬¬¬­­­¬¬¬¬¬¬łłłĽĽĽ»»»´´´ľľľĐĐĐŇŇŇżżż±±±¸¸¸ĽĽĽşşş···ĹĹĹĚĚĚŐŐŐĘĘĘÍÍÍÉÉÉĐĐĐÎÎÎŃŃŃßßßäääŮŮٵµµżżżÉÉÉĆĆĆÂÂÂÂÂÂĆĆĆÉÉÉĘĘĘŃŃŃŮŮŮĚĚĚĚĚĚĚĚĚĘĘʸ¸¸¸¸¸żżżĆĆĆĐĐĐŮŮŮßßßääääääÜÜÜŃŃŃççççççâââćććńńńęęęÔÔÔÇÇÇŃŃŃŮŮŮîîîóóóóóóńńńăăăâââçççäääâââÝÝÝ×××ŃŃŃĚĚĚÇÇÇőőőÜÜÜŰŰŰŰŰŰŘŘŘÜÜÜŘŘŘÔÔÔŮŮŮŐŐŐÎÎÎĆĆĆŔŔŔżżżŔŔŔĂĂĂĹĹĹĚĚĚĆĆĆŰŰŰŮŮŮŮŮŮŃŃŃĘĘĘÇÇÇĐĐĐ×××ŐŐŐŃŃŃĐĐĐÎÎÎĚĚĚÎÎÎĘĘĘĆĆĆĆĆĆĂĂĂżżżżżżŔŔŔŔŔŔÂÂÂĹĹĹĹĹĹÂÂÂżżżżżżÂ­­­µµµ»»»»»»ŔŔŔÇÇÇĆĆĆŔŔŔ···¸¸¸ĽĽĽÂÂÂÇÇÇĘĘĘÉÉÉÇÇÇÉÉÉÉÉÉÇÇÇĆĆĆÎÎÎŰŰŰßßßŰŰŰÝÝÝŰŰŰâââóóóóóóíííńńńďďďäääçççżżżĂĂĂÇÇÇÍÍÍŇŇŇŃŃŃŇŇŇŇŇŇÔÔÔŇŇŇÝÝÝŐŐŐŔŔŔŃŃŃÎÎÎŘŘŘÔÔÔŮŮŮŮŮŮÔÔÔŰŰŰŐŐŐĘĘĘÉÉÉÇÇÇÉÉÉĘĘĘĘĘĘĘĘĘĘĘĘÍÍÍÍÍÍĚĚĚĘĘĘÉÉÉÇÇÇĆĆĆĹĹĹĆĆĆĂĂĂÂÂÂÂÂÂÂÂÂÂÂÂÉÉÉĐĐĐŘŘŘÂÂÂĚĚĚŘŘŘĚĚĚŘŘŘăăăÎÎÎĐĐĐÎÎÎĘĘĘÍÍÍßßßńńńîîîëëëâââęęęŕŕŕ×××ßßßâââŰŰŰŰŰŰĐĐĐŇŇŇ×××ŰŰŰÜÜÜŰŰŰ×××ÔÔÔŇŇŇĐĐĐĚĚĚÇÇÇĹĹĹÂÂÂÂÂÂŔŔŔżżżŔŔŔĆĆĆĹĹĹĂĂĂĚĚĚÇÇDZ±±°°°łłłłłłłłłşşşÂÂÂÂÂÂĽĽĽ¸¸¸ÉÉÉĘĘʸ¸¸łłłŔŔŔĐĐĐŇŇŇÉÉÉĚĚĚĆĆĆŃŃŃĚĚĚŇŇŇÉÉÉÇÇÇÍÍÍĚĚĚÔÔÔÜÜÜÜÜÜ»»»ĂĂĂĚĚĚĚĚĚĂĂĂżżżĹĹĹÉÉÉĆĆĆÇÇÇĚĚĚÇÇÇĆĆĆĚĚĚŇŇŇŃŃŃĹĹĹ»»»¸¸¸ľľľĆĆĆŃŃŃŘŘŘÜÜÜŰŰŰÔÔÔĚĚĚ×××ÝÝÝŕŕŕčččńńńččč×××ĐĐĐŔŔŔÉÉÉÜÜÜâââćććęęęćććëëëäääÝÝÝ××××××ÜÜÜÜÜÜÔÔÔĚĚĚîîîÜÜÜÜÜÜ×××ĐĐĐÔÔÔŇŇŇŇŇŇŇŇŇĚĚĚĂĂĂŔŔŔĆĆĆĚĚĚÎÎÎÎÎÎŇŇŇŐŐŐÉÉÉŮŮŮ×××ŘŘŘĐĐĐÇÇÇĂĂĂĘĘĘÎÎÎÎÎÎÍÍÍĐĐĐÎÎÎĘĘĘŔŔŔĽĽĽşşşşşşĽĽĽżżżÂÂÂĹĹĹĹĹĹĂĂĂĹĹĹĆĆĆĂĂĂżżżżżżŔŔŔŻŻŻµµµşşş»»»ŔŔŔÇÇÇÇÇÇĂĂĂ···¸¸¸ĽĽĽÂÂÂÇÇÇĘĘĘÉÉÉÇÇÇÉÉÉÉÉÉĘĘĘĚĚĚŃŃŃŮŮŮÝÝÝÝÝÝßßßßßßćććóóóőőőďďďîîîďďďëëëââ⼼ĽŔŔŔĂĂĂĚĚĚĐĐĐÎÎÎÎÎÎĐĐĐŃŃŃŇŇŇ×××ÍÍÍĹĹĹÔÔÔĹĹĹŃŃŃŮŮŮŕŕŕâââÜÜÜŮŮŮŃŃŃÍÍÍÉÉÉĹĹĹĆĆĆÇÇÇÉÉÉĚĚĚŃŃŃÍÍÍÍÍÍĘĘĘÇÇÇĆĆĆĂĂĂŔŔŔŔŔŔĽĽĽżżżÂÂÂĂĂĂÂÂÂŔŔŔÂÂÂĆĆĆÇÇÇÝÝÝĹĹĹľľľŐŐŐÔÔÔÂÂÂßßß×××ŐŐŐŇŇŇĂĂĂÉÉÉííííííőőőßßßëëëćććÜÜÜŕŕŕŕŕŕÝÝÝäääŮŮŮŇŇŇÎÎÎŃŃŃŮŮŮÜÜÜ×××ĐĐĐÔÔÔŃŃŃÎÎÎĘĘĘĆĆĆĹĹĹĂĂĂĂĂĂÇÇÇÉÉÉÉÉÉĆĆĆÇÇÇĚĚĚÂÂÂŻŻŻ¸¸¸ľľľÂÂÂĂĂĂĂĂĂÂÂÂľľľ¸¸¸ĂĂĂĹĹĹĹĹĹĹĹĹĹĹĹĆĆĆĆĆĆĆĆĆÍÍÍÍÍÍĹĹĹĚĚĚÇÇÇĐĐĐĘĘĘĚĚĚĚĚĚÉÉÉÍÍÍ×××ÜÜÜĽĽĽŔŔŔÇÇÇĆĆĆŔŔŔľľľŔŔŔŔŔŔżżżĂĂĂĘĘĘÎÎÎÍÍÍĘĘĘÍÍÍŐŐŐŘŘŘÉÉÉ···ĽĽĽŔŔŔĹĹĹÉÉÉÍÍÍÎÎÎÍÍÍĚĚĚĚĚĚĐĐĐŐŐŐâââďďďęęęŮŮŮŇŇŇŐŐŐÎÎÎĐĐĐĚĚĚÍÍÍŃŃŃĚĚĚÎÎÎŐŐŐÎÎÎĘĘĘŃŃŃÜÜÜÝÝÝŃŃŃĹĹĹâââŰŰŰÝÝÝŇŇŇĚĚĚĐĐĐĚĚĚĚĚĚÉÉÉÇÇÇÉÉÉÍÍÍÔÔÔŰŰŰÜÜÜÜÜÜŮŮŮŰŰŰĘĘĘŐŐŐŇŇŇÔÔÔĚĚĚÂÂÂżżżÂÂÂĹĹĹĆĆĆÉÉÉÎÎÎÍÍÍÉÉɸ¸¸µµµ´´´···ĽĽĽÂÂÂĆĆĆÇÇÇĆĆĆÂÂÂÂÂÂĹĹĹĆĆĆÂÂÂŔŔŔ¬¬¬łłł»»»ŔŔŔĂĂĂĹĹĹĂĂĂ»»»ĽĽĽżżżĹĹĹÉÉÉĚĚĚĘĘĘÉÉÉĘĘĘĆĆĆÇÇÇĐĐĐŮŮŮÝÝÝßßßßßßßßßçççďďďńńńóóóöööňňňëëëëëëŐŐŐşşşĹĹĹĹĹĹŃŃŃĐĐĐÎÎÎÍÍÍŃŃŃŃŃŃÔÔÔÍÍÍŔŔŔÇÇÇÔÔÔĘĘĘÎÎÎÔÔÔŃŃŃĐĐĐŇŇŇĐĐĐÎÎÎÇÇÇĹĹĹĹĹĹÉÉÉÉÉÉĆĆĆÇÇÇĚĚĚÍÍÍÍÍÍĘĘĘÇÇÇĂĂĂŔŔŔľľľĽĽĽşşşşşşĽĽĽżżżÂÂÂÂÂÂŔŔŔżżżľľľÎÎÎÍÍÍŇŇŇĐĐĐŐŐŐŐŐŐçççŰŰŰŐŐŐÔÔÔÇÇÇĹĹĹçççëëëřřřâââçççęęęäääßßßÝÝÝßßßâââăăăŰŰŰĐĐĐĚĚĚÎÎÎŇŇŇŐŐŐŐŐŐÔÔÔŇŇŇÎÎÎĘĘĘÇÇÇĆĆĆĆĆĆĹĹĹĘĘĘĚĚĚÉÉÉÇÇÇÇÇÇŔŔŔ¸¸¸µµµżżżĂĂĂÉÉÉĚĚĚÇÇÇżżż»»»»»»ŔŔŔľľľŔŔŔÉÉÉÎÎÎĘĘĘĂĂĂŔŔŔÂÂÂÇÇÇÇÇÇÔÔÔÎÎÎ×××ĐĐĐŃŃŃĚĚĚÍÍÍŃŃŃŘŘŘŰŰŰ······żżżżżżĽĽĽĽĽĽĽĽĽĽĽĽĽĽĽŔŔŔĂĂĂĹĹĹĂĂĂÂÂÂĂĂĂÍÍÍŇŇŇĚĚĚżżż»»»ĽĽĽżżżÂÂÂĹĹĹĆĆĆÇÇÇÉÉÉÉÉÉÉÉÉĚĚĚÜÜÜîîîęęęŮŮŮŃŃŃÝÝÝŘŘŘŰŰŰ×××ŘŘŘßßßŰŰŰßßßŘŘŘÔÔÔŇŇŇŘŘŘßßßÝÝÝŇŇŇÉÉÉŰŰŰŮŮŮŮŮŮÍÍÍĚĚĚĐĐĐĆĆĆĂĂĂŘŘŘÜÜÜßßßŰŰŰŐŐŐÔÔÔŘŘŘÜÜÜŰŰŰŰŰŰĘĘĘŐŐŐŃŃŃŇŇŇÇÇÇ»»»»»»ľľľľľľżżżĆĆĆÍÍÍÍÍÍÇÇÇşşş¸¸¸¸¸¸»»»ŔŔŔĆĆĆÉÉÉÉÉÉÇÇÇŔŔŔŔŔŔĹĹĹĆĆĆĂĂĂÂÂÂĂĂñ±±µµµ»»»żżżÂÂÂÂÂÂĹĹĹĆĆĆŔŔŔŔŔŔĂĂĂÇÇÇĘĘĘĚĚĚĘĘĘÉÉÉĚĚĚĂĂĂĹĹĹŇŇŇßßßâââŕŕŕŕŕŕßßßńńńůůůďďďňňň˙˙˙öööčččăăăÇÇÇşşşĚĚĚÍÍÍŮŮŮŃŃŃÎÎÎÎÎÎŇŇŇŃŃŃŐŐŐĆĆƸ¸¸ÉÉÉÔÔÔŐŐŐŇŇŇŐŐŐĆĆĆÂÂÂĘĘĘĆĆĆĘĘĘĚĚĚÉÉÉÉÉÉĘĘĘĘĘĘĆĆĆÉÉÉĐĐĐĐĐĐÎÎÎĚĚĚÇÇÇĹĹĹŔŔŔľľľĽĽĽľľľşşşµµµ¸¸¸ŔŔŔĆĆĆĹĹĹŔŔŔĹĹĹĘĘĘÎÎÎŮŮŮÍÍÍĐĐĐĆĆĆĹĹĹŘŘŘŃŃŃŃŃŃŇŇŇĘĘĘćććëëëóóóćććăăăęęęëëëÝÝÝŰŰŰßßßŰŰŰŰŰŰßßßßßß×××ĚĚĚÇÇÇÍÍÍŐŐŐÔÔÔŇŇŇÎÎÎĚĚĚÉÉÉÇÇÇĆĆĆĆĆĆÇÇÇÇÇÇĆĆĆĚĚĚÍÍÍżżż»»»ĚĚĚÍÍÍÉÉÉÉÉÉÇÇÇĂĂĂżżżÇÇÇÔÔÔĆĆĆÇÇÇĂĂĂľľľľľľÂÂÂĆĆĆĆĆĆĆĆĆĘĘĘĚĚĚâââçççíííŘŘŘĚĚĚĘĘĘŃŃŃŘŘŘÝÝÝŰŰ۱±±°°°¸¸¸»»»»»»»»»ĽĽĽŔŔŔÂÂÂĽĽĽ¸¸¸żżżżżżĆĆĆÎÎÎÎÎÎÍÍÍĐĐĐŘŘŘ···şşşżżżĂĂĂĹĹĹĹĹĹĂĂĂĹĹĹÂÂÂĘĘĘŇŇŇßßßčččŕŕŕ×××ŘŘŘňňňďďďóóóçççÝÝÝÜÜÜŮŮŮâââÝÝÝÜÜÜŰŰŰŰŰŰŰŰŰŘŘŘŃŃŃĚĚĚÔÔÔŮŮŮĐĐĐĐĐĐĹĹĹĹĹĹÂÂÂÜÜÜăăăćććăăăŮŮŮŐŐŐ×××ŘŘŘŘŘŘĐĐĐŇŇŇ××××××ŇŇŇĚĚĚĆĆĆĂĂĂżżżĽĽĽ»»»ľľľżżżżżżĆĆĆÍÍÍÇÇÇĽĽĽµµµ»»»ĂĂĂÇÇÇĘĘĘĚĚĚÇÇÇĚĚĚĚĚĚĘĘĘĘĘĘÇÇÇ»»»¬¬¬­­­łłł»»»ÂÂÂĆĆĆÇÇÇĹĹĹÂÂÂÂÂÂŔŔŔĹĹĹĚĚĚĚĚĚÇÇÇÉÉÉĐĐĐĘĘĘĚĚĚÍÍÍâââÜÜÜÜÜÜŮŮŮçççüüüőőőóóóřřřřřřńńńíííďďďÝÝÝÇÇÇĂĂĂÎÎÎĐĐĐÎÎÎŃŃŃŃŃŃĆĆĆŇŇŇĘĘĘĚĚĚŰŰŰĽĽĽŮŮŮŔŔŔĂĂĂÎÎÎĚĚĚĂĂĂĆĆĆÇÇÇĆĆĆĘĘĘÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÉÉÉĘĘĘĚĚĚÍÍÍĘĘĘÇÇÇĂĂĂŔŔŔżżżľľľľľľşşş¸¸¸¸¸¸¸¸¸şşşĽĽĽżżżŔŔŔĂĂĂĂĂĂĐĐĐÎÎÎĹĹĹŇŇŇŰŰŰĆĆĆŰŰŰŃŃŃĐĐĐŃŃŃľľľÂÂÂçççňňňîîîäääÜÜÜßßßčččńńńëëëßßßŘŘŘŇŇŇŇŇŇŮŮŮÜÜÜŇŇŇÇÇÇ»»»ŃŃŃĘĘĘĐĐĐĆĆĆĆĆĆĹĹĹÉÉÉÉÉÉĚĚĚÎÎÎÇÇÇĽĽĽÂÂÂĐĐĐŃŃŃĹĹĹŔŔŔżżżżżż»»»¸¸¸ŔŔŔÍÍÍĘĘĘÂÂÂŔŔŔĆĆĆĚĚĚĘĘĘĘĘĘÍÍÍčččâââßßßŕŕŕăăăčččëëëęęęäääŕŕŕŐŐŐÜÜÜäääĚĚĚŻŻŻŻŻŻ±±±µµµŔŔŔµµµłłł···µµµÂÂÂÂÂÂĹĹĹĘĘĘÎÎÎÎÎÎÍÍÍĘĘĘŕŕŕĚĚĚ······ÂÂÂżżż»»»ĂĂĂÇÇÇĆĆĆĚĚĚŐŐŐ×××ŐŐŐÔÔÔŐŐŐńńńíííęęęëëëçççŕŕŕßßßŕŕŕŕŕŕŮŮŮÜÜÜŇŇŇ×××ÜÜÜĚĚĚĹĹĹŰŰŰŮŮŮĚĚĚĘĘĘĹĹĹÍÍÍŃŃŃâââäääçççćććßßßŘŘŘŐŐŐŇŇŇĐĐĐĚĚĚÎÎÎŃŃŃŃŃŃÎÎÎÉÉÉĂĂĂŔŔŔÂÂÂżżżżżżŔŔŔżżż»»»ĽĽĽÂÂÂŃŃŃÇÇÇŔŔŔĹĹĹÉÉÉĘĘĘÉÉÉÇÇÇĘĘĘÍÍÍÎÎÎÍÍÍĘĘĘĂĂõµµ©©©­­­łłł»»»ĂĂĂÇÇÇÉÉÉÇÇÇĆĆĆĹĹĹÇÇÇÇÇÇÇÇÇÇÇÇÉÉÉÉÉÉÉÉÉŇŇŇ××××××ăăăßßßćććçççďďďďďďëëë˙˙˙ňňňÇÇÇÉÉÉăăăŕŕŕÂÂÂŔŔŔĘĘĘŇŇŇŃŃŃĐĐĐŇŇŇĐĐĐĚĚĚĚĚĚÉÉÉÎÎÎĘĘĘ»»»ŐŐŐÍÍÍÇÇÇÎÎÎĘĘĘÂÂÂĆĆĆÇÇÇĆĆĆĘĘĘÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇÉÉÉĘĘĘĚĚĚĚĚĚÉÉÉĆĆĆÂÂÂżżżľľľĽĽĽĽĽĽşşş¸¸¸¸¸¸¸¸¸şşşĽĽĽżżżŔŔŔĆĆĆÂÂÂĘĘĘÎÎÎÍÍÍÔÔÔŐŐŐĆĆĆŰŰŰÝÝÝ××××××ÎÎÎĂĂĂÔÔÔćććíííëëëçççŕŕŕŕŕŕćććçççäääďďďăăăŘŘŘŘŘŘŰŰŰŘŘŘÎÎÎÇÇÇĽĽĽŇŇŇÍÍÍŇŇŇÉÉÉÉÉÉÇÇÇĚĚĚÎÎÎĘĘĘÇÇÇĂĂĂżżżĆĆĆĘĘĘÂÂÂşşşĆĆĆÍÍÍÍÍÍĐĐĐŐŐŐŃŃŃĆĆĆĚĚĚĆĆĆĹĹĹÍÍÍŮŮŮÝÝÝÜÜÜŮŮŮÝÝÝçççíííęęęććććććčččęęęŕŕŕäääŰŰŰŮŮŮßßßĚĚ̱±±¬¬¬±±±¬¬¬­­­ŻŻŻ¬¬¬°°°···´´´şşşĽĽĽÂÂÂĂĂĂĹĹĹÇÇÇĚĚĚĐĐĐŃŃŃŇŇŇŃŃŃŃŃŃÎÎÎÂÂÂĽĽĽĆĆĆÂÂÂÇÇÇĐĐĐÔÔÔĐĐĐÍÍÍŐŐŐŕŕŕďďďçççćććďďďřřřöööîîîčččÝÝÝÝÝÝăăăŰŰŰ×××ŘŘŘĘĘĘĆĆĆßßß×××ĘĘĘĆĆĆÂÂÂÔÔÔâââćććŰŰŰŕŕŕăăăßßßÜÜÜŮŮŮŐŐŐŃŃŃĐĐĐŃŃŃŃŃŃŃŃŃĐĐĐĚĚĚÇÇÇĂĂĂÂÂÂŔŔŔÂÂÂĂĂĂżżż¸¸¸···şşşÂÂÂĽĽĽĽĽĽĹĹĹÍÍÍÎÎÎÎÎÎÎÎÎŇŇŇŃŃŃŃŃŃĐĐĐĘĘĘżżż···łłł±±±···ľľľĂĂĂÉÉÉĘĘĘĘĘĘÉÉÉĆĆĆĘĘĘĘĘĘĹĹĹĆĆĆÍÍÍÎÎÎĘĘĘÜÜÜŕŕŕÝÝÝâââŕŕŕîîîňňňöööńńńňňň˙˙˙ëëëŔŔŔŔŔŔŃŃŃÂÂÂżżżĹĹĹÎÎÎĐĐĐÍÍÍŇŇŇ×××ŇŇŇĐĐĐÇÇÇĚĚĚŇŇŇşşşĽĽĽĹĹĹĚĚĚĚĚĚÍÍÍÇÇÇÂÂÂĹĹĹÇÇÇÇÇÇÉÉÉÇÇÇĆĆĆĆĆĆĆĆĆÇÇÇÉÉÉĘĘĘĘĘĘÉÉÉÇÇÇĹĹĹÂÂÂżżżĽĽĽĽĽĽ»»»¸¸¸¸¸¸¸¸¸¸¸¸şşşĽĽĽżżżŔŔŔĆĆĆŔŔŔĂĂĂÎÎÎŐŐŐŇŇŇÍÍÍĘĘĘżżżŘŘŘĐĐĐĐĐĐ×××ÇÇÇĆĆĆÔÔÔçççíííęęęßßßŰŰŰŕŕŕćććęęęďďďäää×××ŃŃŃ×××ÜÜÜ×××ÍÍÍżżżŐŐŐÎÎÎŐŐŐĚĚĚĚĚĚĘĘĘÍÍÍŃŃŃÉÉÉĆĆĆĹĹĹĂĂĂÉÉÉÇÇÇľľľĘĘĘÍÍÍÇÇÇŔŔŔĹĹĹĐĐĐÎÎÎĂĂĂŔŔŔĆĆĆÍÍÍ×××ŕŕŕççççççâââćććííííííçççćććččččččçççÝÝÝçççâââÜÜÜäääßßßŃŃŃÍÍÍĘĘʵµµŞŞŞŻŻŻ»»»ĆĆĆĹĹĹ···±±±¸¸¸ŔŔŔĹĹĹĹĹĹĹĹĹĹĹĹĂĂĂĚĚĚŇŇŇŐŐŐŮŮŮßßß×××ÇÇÇÂÂÂÂÂÂÇÇÇĐĐĐÔÔÔÔÔÔÔÔÔÝÝÝęęęçççÝÝÝŮŮŮâââńńńúúúüüüúúúüüüóóóîîîŕŕŕŘŘŘŐŐŐÉÉÉĹĹĹ×××ŇŇŇĚĚĚÇÇÇľľľŃŃŃęęęăăăŮŮŮÝÝÝßßßŰŰŰŮŮŮŮŮŮŘŘŘŇŇŇŃŃŃĐĐĐĐĐĐÎÎÎÎÎÎĚĚĚÉÉÉĆĆĆżżżżżżŔŔŔĂĂĂÂÂÂĽĽĽ»»»żżżľľľĽĽĽżżżÉÉÉÎÎÎÎÎÎĚĚĚÍÍÍŇŇŇÍÍÍĘĘĘÉÉÉĂĂĂşşş¸¸¸ľľľşşşĽĽĽŔŔŔĆĆĆÉÉÉĘĘĘĘĘĘĘĘĘĹĹĹÇÇÇÇÇÇÇÇÇÍÍÍŐŐŐŘŘŘ×××ŕŕŕßßßÝÝÝâââćććďďďőőőůůůüüüüüüçççÎÎÎĚĚĚŃŃŃÍÍÍÉÉÉŃŃŃĐĐĐĐĐĐĐĐĐŇŇŇ×××ŐŐŐĐĐĐŇŇŇĚĚĚŇŇŇ×××»»»ĐĐĐľľľÍÍÍŃŃŃÍÍÍĹĹĹÂÂÂĹĹĹÇÇÇÇÇÇĆĆĆĆĆĆĹĹĹĹĹĹĹĹĹĆĆĆÇÇÇÉÉÉÉÉÉĆĆĆĹĹĹĂĂĂŔŔŔżżżĽĽĽ»»»şşş¸¸¸¸¸¸¸¸¸¸¸¸şşşĽĽĽżżżŔŔŔĆĆĆÂÂÂŔŔŔÍÍÍ×××ÍÍÍÇÇÇŇŇŇĂĂĂÜÜÜŰŰŰŘŘŘŮŮŮĐĐĐÇÇÇŔŔŔäääíííčččÜÜÜŰŰŰßßßŕŕŕăăăăăăŕŕŕŮŮŮÔÔÔ×××ÜÜÜŘŘŘÎÎÎŔŔŔ×××ĐĐĐŐŐŐĚĚĚĚĚĚĘĘĘÎÎÎĐĐĐĘĘĘĚĚĚĘĘĘĂĂĂĆĆĆĘĘĘĆĆĆĘĘĘŔŔŔľľľĂĂĂĹĹĹżżżĽĽĽľľľĘĘĘŮŮŮäääăăăÝÝÝÝÝÝßßßÝÝÝâââäääăăăćććëëëčččăăăäääíííňňňęęęâââćććäääŕŕŕăăăŰŰŰŃŃŃĐĐĐÎÎÎĚĚĚÎÎÎŇŇŇÍÍÍ°°°µµµşşşľľľĹĹĹĘĘĘĚĚĚÉÉÉĘĘĘÍÍÍÇÇÇÍÍÍßßßäääŐŐŐÉÉÉÉÉÉÉÉÉĘĘĘ×××ćććčččćććčččÜÜÜ×××ŇŇŇÔÔÔÜÜÜćććîîîňňňëëëäääâââăăăčččćććŐŐŐÇÇÇÉÉÉÍÍÍĐĐĐĘĘĘĽĽĽÇÇÇçççÜÜÜŕŕŕŕŕŕÜÜÜÔÔÔŃŃŃŇŇŇŃŃŃÎÎÎÉÉÉÉÉÉÉÉÉÇÇÇĆĆĆĹĹĹĂĂĂÂÂÂÂÂÂŔŔŔŔŔŔĂĂĂÂÂÂżżżÂÂÂĆĆĆĂĂĂĂĂĂÇÇÇŃŃŃÔÔÔŃŃŃÎÎÎĐĐĐĹĹĹÂÂÂÂÂÂĂĂĂżżżşşş»»»ÂÂÂÂÂÂĂĂĂĹĹĹÇÇÇÉÉÉÉÉÉÉÉÉÉÉÉĆĆĆĹĹĹÉÉÉŃŃŃ×××ŮŮŮÝÝÝăăăăăăŰŰŰÜÜÜçççďďďďďďóóóúúúîîîäääÎÎÎĹĹĹĐĐĐ×××ŐŐŐŮŮŮŐŐŐŇŇŇÔÔÔŘŘŘŰŰŰŐŐŐÍÍÍĚĚĚĘĘĘĘĘĘÇÇÇĂĂĂĽĽĽŘŘظ¸¸ÇÇÇÔÔÔĚĚĚĹĹĹĂĂĂĹĹĹĆĆĆĆĆĆĹĹĹĂĂĂĂĂĂĂĂĂĂĂĂĹĹĹĹĹĹĆĆĆÇÇÇĹĹĹĂĂĂÂÂÂŔŔŔżżżĽĽĽ»»»şşş¸¸¸¸¸¸···¸¸¸şşş»»»ľľľżżżĂĂĂĹĹĹÂÂÂÉÉÉŃŃŃÇÇÇĆĆĆŰŰŰĚĚĚĐĐĐ×××ßßß×××ĐĐĐĐĐĐĽĽĽŰŰŰíííëëëßßßÜÜÜÜÜÜŘŘŘŰŰŰâââçççćććÝÝÝ××××××ŐŐŐŃŃŃŔŔŔ×××ŃŃŃ×××ÍÍÍÍÍÍĚĚĚÎÎÎŃŃŃĘĘĘĘĘĘÉÉÉÂÂÂÂÂÂÇÇÇÇÇÇÉÉÉÂÂÂÉÉÉŰŰŰßßßŇŇŇŃŃŃÜÜÜŇŇŇŰŰŰŮŮŮĘĘĘ»»»···¸¸¸şşşĹĹĹÎÎÎÜÜÜîîîőőőćććÜÜÜćććííííííćććâââŕŕŕŰŰŰŮŮŮŕŕŕâââÝÝÝŕŕŕÜÜÜŇŇŇŇŇŇŮŮŮŮŮŮ××××××ÍÍÍżżż···şşşżżżÂÂÂĂĂĂÍÍÍĚĚĚĘĘĘŐŐŐÝÝÝÝÝÝÜÜÜÍÍÍÍÍÍĚĚĚŰŰŰďďďîîîßßßŰŰŰŐŐŐŐŐŐŐŐŐ×××ŰŰŰÝÝÝÝÝÝÜÜÜ×××ŇŇŇÎÎÎ×××ŕŕŕßßßŘŘŘÎÎÎŔŔŔÍÍÍŇŇŇÍÍÍľľľżżżăăăŮŮŮÝÝÝÜÜÜŐŐŐÎÎÎÍÍÍĐĐĐĐĐĐÍÍÍĹĹĹÇÇÇÉÉÉÇÇÇĹĹĹĂĂĂĂĂĂĂĂĂĆĆĆĂĂĂĂĂĂĹĹĹĂĂĂŔŔŔĂĂĂĘĘĘĂĂĂĂĂĂÉÉÉĐĐĐĐĐĐĚĚĚĘĘĘÍÍÍŔŔŔĂĂĂÇÇÇÍÍÍĚĚĚÇÇÇÇÇÇĘĘĘÉÉÉÉÉÉÇÇÇÇÇÇÇÇÇÇÇÇÉÉÉÉÉÉĘĘĘÉÉÉĐĐĐŰŰŰÝÝÝŰŰŰÝÝÝäääćććŮŮŮßßßíííúúúóóóöööúúúęęęÍÍÍÉÉÉÔÔÔŇŇŇŘŘŘÝÝÝŇŇŇŃŃŃŇŇŇŇŇŇÔÔÔÔÔÔÎÎÎÍÍÍŐŐŐŐŐŐÎÎÎŔŔŔ···ŔŔŔĐĐеµµŔŔŔŐŐŐĘĘĘĆĆĆĆĆĆĹĹĹĹĹĹĆĆĆĂĂĂÂÂÂŔŔŔŔŔŔŔŔŔÂÂÂĂĂĂĹĹĹĹĹĹĂĂĂĂĂĂÂÂÂŔŔŔżżżĽĽĽ»»»şşş¸¸¸·········¸¸¸»»»ľľľżżżÂÂÂĆĆĆĂĂĂĹĹĹĘĘĘÇÇÇĘĘĘŮŮŮÎÎÎľľľĹĹĹŰŰŰŇŇŇĘĘĘÔÔÔĆĆĆÂÂÂâââíííăăăŕŕŕŕŕŕßßßćććßßßääääääÝÝÝÔÔÔŃŃŃŐŐŐŘŘŘÂÂÂŘŘŘŃŃŃŘŘŘÍÍÍÎÎÎĚĚĚĐĐĐŇŇŇÇÇÇĹĹĹĆĆĆÂÂÂÂÂÂĆĆĆĂĂĂŘŘŘÔÔÔĐĐĐÍÍÍÉÉÉĂĂĂĂĂĂÉÉÉâââŰŰŰĚĚĚľľľ···»»»żżżÂÂÂĽĽĽÂÂÂÉÉÉßßßőőőîîîäääíííääääääăăăäääŕŕŕ×××ŇŇŇ×××ćććŰŰŰŘŘŘŮŮŮŮŮŮßßßăăăÝÝÝŕŕŕçççăăăĐĐĐľľľ»»»ľľľżżżŔŔŔÎÎÎŃŃŃÎÎÎÔÔÔŮŮŮÝÝÝäääÇÇÇĐĐĐŇŇŇÝÝÝëëëâââŃŃŃŃŃŃ×××ŐŐŐŐŐŐŰŰŰäääíííęęęâââçççăăăŐŐŐŇŇŇÎÎÎÉÉÉĐĐĐŃŃŃÂÂÂÎÎÎŃŃŃĚĚĚÂÂÂĽĽĽăăăÝÝÝŐŐŐŐŐŐŃŃŃÍÍÍÍÍÍĐĐĐÍÍÍÇÇÇÂÂÂÇÇÇĚĚĚĘĘĘĆĆĆÂÂÂĂĂĂĆĆĆĹĹĹÂÂÂÂÂÂĹĹĹĂĂĂÂÂÂĆĆĆĚĚĚÍÍÍĚĚĚÍÍÍÍÍÍÇÇÇľľľ»»»ľľľÇÇÇĚĚĚĐĐĐĐĐĐĐĐĐŇŇŇŇŇŇŃŃŃĚĚĚĘĘĘÉÉÉÇÇÇÇÇÇÇÇÇĘĘĘĚĚĚĆĆĆÍÍÍŘŘŘßßßßßßÜÜÜÝÝÝâââăăăŰŰŰăăăęęęüüüřřřúúúřřřëëëĐĐĐĘĘĘŇŇŇŇŇŇ×××ŰŰŰŇŇŇĐĐĐŐŐŐŃŃŃĚĚĚŃŃŃÔÔÔŐŐŐŰŰŰâââŃŃŃĆĆĆÂÂÂŐŐŐĘĘĘĹĹĹÉÉÉŐŐŐÉÉÉÇÇÇĘĘĘĹĹĹĂĂĂĹĹĹÂÂÂżżżżżżżżżżżżżżżŔŔŔÂÂÂĂĂĂÂÂÂÂÂÂÂÂÂÂÂÂżżżľľľ»»»şşş············¸¸¸»»»ľľľżżżŔŔŔĹĹĹĂĂĂŔŔŔÇÇÇĐĐĐŃŃŃĐĐĐŰŰŰÔÔÔĘĘĘŃŃŃŇŇŇÎÎÎŃŃŃÇÇǵµµŮŮŮçççăăăčččëëëčččîîîŕŕŕââââââßßßŘŘŘŇŇŇÔÔÔŰŰŰĹĹĹŰŰŰÔÔÔŮŮŮĐĐĐĐĐĐÎÎÎŇŇŇĚĚĚĹĹĹÉÉÉĚĚĚĆĆĆĆĆĆĚĚĚÎÎÎÔÔÔ×××ÔÔÔĐĐĐĐĐĐŇŇŇÍÍÍĹĹĹĆĆĆĽĽĽłłłłłł···ľľľĹĹĹĘĘĘÍÍÍĘĘĘżżżÉÉÉęęęöööîîîëëëčččęęęčččâââŮŮŮŐŐŐŃŃŃÍÍÍŘŘŘŮŮŮâââăăăŰŰŰÝÝÝćććçççŕŕŕčččëëëâââŘŘŘÎÎÎżżż°°°żżżÉÉÉĚĚĚÍÍÍ×××ŰŰŰÝÝÝäääÂÂÂĐĐĐŐŐŐÜÜÜäääŮŮŮÍÍÍ×××ŘŘŘŰŰŰÝÝÝâââęęęóóóňňňíííäääçççŕŕŕăăăŰŰŰÍÍÍĐĐĐÎÎÎÉÉÉŃŃŃÎÎÎÇÇÇĆĆĆżżżćććăăăŐŐŐ×××ÔÔÔĐĐĐÍÍÍĚĚĚĹĹĹ»»»şşşŔŔŔÇÇÇĆĆĆŔŔŔĽĽĽľľľÂÂÂżżżľľľŔŔŔĹĹĹĹĹĹĹĹĹÇÇÇÎÎÎĚĚĚĘĘĘÍÍÍÎÎÎĘĘĘĂĂĂĹĹĹÉÉÉĚĚĚÍÍÍĘĘĘĹĹĹĹĹĹÍÍÍŃŃŃĐĐĐĚĚĚĘĘĘÇÇÇĆĆĆÇÇÇÉÉÉĚĚĚÍÍÍľľľÎÎÎÜÜÜßßßÝÝÝŕŕŕŕŕŕßßßÝÝÝŰŰŰăăăăăăřřřřřřüüüńńńĆĆĆĐĐĐÍÍÍĐĐĐÝÝÝŐŐŐĚĚĚ×××ÎÎÎŘŘŘŇŇŇÎÎÎÜÜÜćććŰŰŰĐĐĐÍÍ͵µµ···ĂĂĂŰŰŰĽĽĽĘĘĘĘĘĘŐŐŐÉÉÉÉÉÉĚĚĚĹĹĹÂÂÂĂĂĂŔŔŔľľľľľľľľľľľľľľľżżżŔŔŔÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂŔŔŔľľľ»»»şşş············¸¸¸»»»ľľľżżżÂÂÂĂĂĂŔŔŔľľľÇÇÇ×××ŐŐŐÇÇÇÉÉÉŰŰŰĹĹŸ¸¸ĚĚĚŐŐŐŃŃŃĆĆĆŔŔŔÝÝÝćććâââďďďóóóčččćććďďďíííííííííćććŘŘŘŇŇŇÔÔÔĆĆĆÜÜÜ×××ÜÜÜŇŇŇŇŇŇŃŃŃŐŐŐżżżĂĂĂŇŇŇŘŘŘĚĚĚÉÉÉ×××ăăăÎÎÎÎÎÎÉÉÉĹĹĹĆĆĆĆĆĆşşş¨¨¨¬¬¬©©©­­­µµµşşş»»»ŔŔŔÉÉÉĐĐĐŘŘŘĚĚĚÇÇÇăăăőőőíííćććÝÝÝâââßßßŇŇŇÎÎÎŮŮŮÝÝÝ×××ÎÎÎÔÔÔâââčččâââßßßŕŕŕÝÝÝ×××ŮŮŮŰŰŰßßßęęęëëëÔÔÔ¸¸¸···ŔŔŔĆĆĆĘĘĘŇŇŇ×××ÝÝÝęęęŔŔŔÎÎÎŇŇŇŘŘŘäääÜÜÜŐŐŐŕŕŕŐŐŐäääńńńńńńîîîęęęäääßßßćććäääŰŰŰâââßßßĐĐĐŃŃŃĘĘĘŕŕŕĚĚĚÍÍÍĘĘĘÇÇÇÔÔÔŰŰŰćććÔÔÔÜÜÜŇŇŇÔÔÔŮŮŮÎÎÎĹĹĹĽĽĽÇÇÇĆĆĆĹĹĹĹĹĹĂĂĂĂĂĂĂĂĂĹĹĹĂĂĂŔŔŔ»»»żżżÉÉÉÉÉÉÇÇÇÎÎÎÍÍÍĚĚĚÎÎÎĚĚĚżżżµµµ»»»ĆĆĆÍÍÍŃŃŃĐĐĐÉÉÉÇÇÇĚĚĚĐĐĐĐĐĐŃŃŃĚĚĚÍÍÍĂĂĂĘĘĘĹĹĹÍÍÍĚĚĚëëëăăăÜÜÜÜÜÜŕŕŕăăăŕŕŕŰŰŰßßßćććâââńńńňňňóóó˙˙˙äääÍÍÍŃŃŃ×××ŮŮŮ×××ŇŇŇÎÎÎĚĚĚĐĐĐĚĚĚÉÉÉÔÔÔĘĘĘŘŘŘ°°°ĽĽĽ···µµµĆĆĆÝÝÝĆĆĆşşşĐĐĐĆĆĆÝÝÝĐĐĐĹĹĹĂĂĂĹĹĹĆĆĆĹĹĹżżżľľľľľľĽĽĽĽĽĽĽĽĽżżżŔŔŔÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂŔŔŔżżżľľľşşş¸¸¸¸¸¸şşş»»»ĽĽĽľľľľľľŔŔŔĹĹĹÂÂÂĆĆĆÉÉÉŇŇŇÜÜÜĚĚĚŐŐŐÉÉÉÉÉÉľľľŇŇŇÎÎÎÇÇÇĘĘĘŔŔŔ···°°°±±±ĽĽĽÍÍÍăăăőőőňňňőőőďďďďďďâââßßßŃŃŃŐŐŐĘĘĘŰŰŰßßßŰŰŰÜÜÜŘŘŘŇŇŇÔÔÔĹĹĹĂĂĂÉÉÉĂĂĂĂĂĂŕŕŕęęęÎÎÎłłłĹĹĹ···°°°©©©µµµŻŻŻ¬¬¬±±±°°°­­­°°°´´´şşşżżżĆĆĆŇŇŇŃŃŃĂĂĂÍÍÍćććööööööÜÜÜäääÜÜÜŘŘŘŰŰŰÜÜÜŮŮŮŘŘŘŰŰŰŇŇŇŮŮŮçççÜÜÜÜÜÜćććŮŮŮŇŇŇçççęęęčččääääääçççäääÝÝݸ¸¸···żżżÍÍÍŃŃŃŇŇŇÜÜÜęęężżżĘĘĘŃŃŃÜÜÜíííëëëßßßŰŰŰßßßëëëďďďçççäääčččćććÝÝÝçççÝÝÝâââŐŐŐŘŘŘŇŇŇ×××ĆĆĆÔÔÔÉÉÉŔŔŔ¸¸¸ÂÂÂŮŮŮÜÜÜŇŇŇÍÍÍŮŮŮŃŃŃŃŃŃÎÎÎÂÂÂŔŔŔŔŔŔÇÇÇÇÇÇĆĆĆĆĆĆĹĹĹĂĂĂÂÂÂÂÂÂĆĆĆĹĹĹżżżĹĹĹÎÎÎĚĚĚÇÇÇÍÍÍĚĚĚÎÎÎÎÎÎÉÉÉżżżşşşżżżÉÉÉÎÎÎŃŃŃĐĐĐÉÉÉÇÇÇĘĘĘÎÎÎÎÎÎĘĘĘĆĆĆÉÉÉÂÂÂÍÍÍÍÍÍÜÜÜŕŕŕăăăßßßÜÜÜÝÝÝăăăäääâââÝÝÝăăăăăăßßßďďďďďďňňňóóóÇÇÇÍÍÍŃŃŃ×××ŘŘŘŐŐŐŇŇŇĐĐĐÎÎÎĐĐĐÍÍÍĚĚĚŇŇŇÍÍÍŰŰ۵µµľľľżżż¸¸¸ĆĆĆŇŇŇĆĆĆĆĆĆŃŃŃŔŔŔ×××ÔÔÔĘĘĘĂĂĂÂÂÂŔŔŔ»»»¸¸¸ľľľĽĽĽĽĽĽ»»»ĽĽĽľľľŔŔŔÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂŔŔŔżżżżżżşşşşşşşşşşşş»»»ĽĽĽľľľżżżĹĹĹÉÉÉĹĹĹÇÇÇÉÉÉĐĐĐ×××ĆĆĆŇŇŇĚĚĚĐĐĐĹĹĹŇŇŇÍÍÍĆĆĆĆĆĆÂÂÂĽĽĽ¸¸¸»»»ľľľŔŔŔÇÇÇĐĐĐčččóóóöööňňňäääčččăăăÝÝÝŇŇŇŘŘŘßßßâââŕŕŕßßß×××ĚĚĚĘĘĘĚĚĚÔÔÔÔÔÔÔÔÔßßßŐŐŐ´´´¦¦¦­­­©©©ŻŻŻźźźĄĄĄĄĄĄŞŞŞ°°°ŻŻŻŻŻŻŻŻŻłłł···ĽĽĽŔŔŔĂĂĂÂÂÂĘĘĘäääőőőďďďčččâââÜÜÜÝÝÝŰŰŰŐŐŐŐŐŐŘŘŘŐŐŐÎÎÎŃŃŃŐŐŐßßßŘŘŘŘŘŘßßß×××ŐŐŐÔÔÔŐŐŐÔÔÔŐŐŐÝÝÝćććçççăăăĐĐĐľľľµµµÂÂÂÎÎÎÔÔÔßßßîîîĘĘĘĘĘĘŃŃŃßßßčččęęęäääÝÝÝßßßčččîîîîîîîîîńńńíííćććâââŘŘŘŘŘŘÎÎÎĐĐĐĐĐĐŘŘŘĚĚĚĚĚĚĘĘĘĽĽĽľľľĐĐĐßßßßßßÎÎÎĐĐĐŘŘŘĐĐĐĐĐĐÍÍÍĂĂĂÇÇÇĘĘĘĹĹĹĹĹĹĆĆĆĆĆĆĆĆĆĹĹĹĹĹĹĹĹĹÉÉÉÉÉÉĹĹĹÉÉÉŃŃŃÎÎÎÉÉÉĚĚĚÍÍÍŃŃŃĐĐĐĆĆĆŔŔŔżżżĹĹĹĚĚĚĐĐĐŃŃŃĐĐĐÉÉÉÇÇÇĘĘĘÍÍÍÍÍÍĚĚĚĘĘĘŃŃŃĘĘĘŇŇŇŃŃŃßßßâââÝÝÝÝÝÝÝÝÝŕŕŕăăăăăăŕŕŕßßßââââââćććőőőóóóřřřóóóżżżÎÎÎŃŃŃŐŐŐŐŐŐÔÔÔŇŇŇŃŃŃĐĐĐŃŃŃĐĐĐÎÎÎŃŃŃĐĐĐŰŰŰĽĽĽżżżÂÂÂľľľÎÎÎÉÉÉĂĂĂÎÎÎŃŃŃżżżżżżÍÍÍĘĘĘżżżÂÂÂÂÂÂĽĽĽżżżĽĽĽ»»»»»»»»»»»»ĽĽĽżżżŔŔŔÂÂÂÂÂÂĂĂĂĂĂĂĂĂĂÂÂÂŔŔŔŔŔŔĽĽĽĽĽĽĽĽĽĽĽĽĽĽĽľľľżżżŔŔŔĹĹĹÇÇÇĆĆĆĘĘĘĘĘĘÎÎÎŐŐŐĹĹĹŃŃŃĘĘĘĐĐĐĂĂĂŇŇŇŇŇŇÎÎÎÍÍÍŔŔŔľľľżżżÂÂÂÂÂÂľľľĽĽĽľľľŔŔŔ×××îîîîîîŕŕŕăăăăăăÎÎÎŰŰŰÔÔÔŮŮŮßßßÜÜÜÝÝÝ×××ĂĂĂĐĐĐĚĚĚĹĹĹĂĂĂÎÎÎÝÝÝÝÝÝŇŇŇŻŻŻ©©©ŻŻŻĽĽĽ©©©¨¨¨©©©···±±±±±±±±±°°°±±±¸¸¸ľľľľľľżżżÉÉÉŕŕŕňňňóóóęęęÝÝÝßßßßßßâââŕŕŕŰŰŰŘŘŘŘŘŘŇŇŇĘĘĘÍÍÍÎÎÎ×××ÔÔÔÔÔÔ×××ÔÔÔŘŘŘŘŘŘ×××ŇŇŇÔÔÔÜÜÜćććęęęçççíííŃŃŃ»»»ľľľĚĚĚŇŇŇŘŘŘâââ×××ĘĘĘĐĐĐÝÝÝŕŕŕäääęęęäää×××ÜÜÜćććîîîňňňńńńíííčččÝÝÝÝÝÝŕŕŕŇŇŇÍÍÍĚĚĚŰŰŰŰŰŰĹĹĹĂĂĂľľľÔÔÔäääŰŰŰŮŮŮ×××ÔÔÔŇŇŇÉÉÉÍÍÍÎÎÎÉÉÉĚĚĚĘĘĘĂĂĂĂĂĂĂĂĂĂĂĂĹĹĹĆĆĆÉÉÉĘĘĘĘĘĘĚĚĚĆĆĆÇÇÇĐĐĐÎÎÎÉÉÉĚĚĚÎÎÎ×××ŃŃŃĹĹĹÂÂÂĹĹĹÇÇÇÍÍÍÎÎÎĐĐĐÎÎÎÉÉÉÉÉÉÍÍÍÎÎÎÍÍÍĘĘĘÎÎÎÜÜÜŘŘŘÝÝÝÔÔÔŘŘŘ×××ßßßßßßŕŕŕââââââŕŕŕßßßÝÝÝÜÜÜŕŕŕîîîůůůńńńőőőóóóĂĂĂÍÍÍĐĐĐŇŇŇŇŇŇŇŇŇŃŃŃŃŃŃŇŇŇŇŇŇŃŃŃŃŃŃÍÍÍŃŃŃŐŐŐľľľ»»»ĽĽĽÂÂÂÜÜÜĹĹĹżżżĐĐĐÎÎÎŔŔŔ¸¸¸ŇŇŇŃŃŃŔŔŔŔŔŔĽĽĽµµµ»»»»»»»»»şşşşşşşşşĽĽĽľľľżżżÂÂÂÂÂÂĂĂĂĂĂĂĂĂĂĂĂĂÂÂÂŔŔŔľľľľľľľľľľľľľľľżżżŔŔŔŔŔŔżżżĹĹĹĹĹĹĚĚĚĚĚĚĐĐĐ×××ÉÉÉŇŇŇÇÇÇÇÇÇ´´´ÂÂÂÉÉÉÉÉÉĹĹĹĘĘĘĆĆĆĆĆĆÉÉÉÉÉÉĹĹĹĹĹĹÇÇÇ···ĘĘĘçççńńńăăăŕŕŕčččŐŐŐÝÝÝÔÔÔŃŃŃŃŃŃŃŃŃŇŇŇÎÎÎĂĂĂÔÔÔŃŃŃĂĂĂÂÂÂĐĐĐ×××ŘŘŘÝÝÝŃŃŃÉÉÉÇÇÇĐĐĐľľľ´´´¦¦¦´´´łłł±±±ŻŻŻ¨¨¨ĄĄĄ°°°¸¸¸´´´ßßßçççúúúöööîîîëëëâââäääćććâââßßßŕŕŕŰŰŰŃŃŃĚĚĚÍÍÍĘĘĘÉÉÉĐĐĐÔÔÔÔÔÔŃŃŃŇŇŇŮŮŮŰŰŰŮŮŮŐŐŐŇŇŇŇŇŇŘŘŘßßßăăăńńńăăăÍÍÍĹĹĹĚĚĚŇŇŇŇŇŇŐŐŐÝÝÝÎÎÎĚĚĚÔÔÔŘŘŘßßßčččîîîćććßßßÜÜÜŕŕŕâââßßßÝÝÝßßßÜÜÜŐŐŐÎÎÎĆĆĆÉÉÉÍÍÍÍÍÍĹĹĹżżżµµµ´´´×××äääÔÔÔŇŇŇŐŐŐŇŇŇÎÎÎĹĹĹÉÉÉĆĆĆľľľĂĂĂŔŔŔÉÉÉÇÇÇĹĹĹÂÂÂÂÂÂĹĹĹÇÇÇÉÉÉĘĘĘĘĘĘĂĂĂŔŔŔÉÉÉĚĚĚÉÉÉĚĚĚŃŃŃŮŮŮŃŃŃĹĹĹĆĆĆÉÉÉÉÉÉÎÎÎÍÍÍĐĐĐÎÎÎĘĘĘĘĘĘĐĐĐĐĐĐÍÍÍĆĆĆÍÍÍÝÝÝÜÜÜâââ×××ŮŮŮ×××ßßßßßßŕŕŕŕŕŕŕŕŕßßßŕŕŕâââßßßŕŕŕíííňňňčččíííçççľľľĘĘĘÍÍÍÎÎÎĐĐĐĐĐĐĐĐĐĐĐĐŃŃŃÔÔÔŃŃŃŃŃŃĘĘĘŃŃŃĘĘĘşşş···»»»ÂÂÂŕŕŕŔŔŔĂĂĂŃŃŃĘĘĘżżż¸¸¸ŇŇŇŇŇŇÂÂÂÂÂÂľľľ···ľľľ»»»»»»şşşşşşşşş»»»ľľľżżżŔŔŔÂÂÂĂĂĂĂĂĂĂĂĂĂĂĂÂÂÂÂÂÂŔŔŔżżżżżżżżżżżżŔŔŔŔŔŔÂÂÂżżżĂĂĂĹĹĹĚĚĚĚĚĚÎÎÎ×××ĚĚĚÇÇÇĆĆĆÎÎθ¸¸ľľľÇÇÇŃŃŃŃŃŃŮŮŮÔÔÔĐĐĐĐĐĐÎÎÎĘĘĘĚĚĚÎÎÎĘĘĘÍÍÍŮŮŮîîîŕŕŕÝÝÝďďďëëëŮŮŮŮŮŮŇŇŇÎÎÎĐĐĐĘĘĘĹĹĹÇÇÇÔÔÔŐŐŐÎÎÎÍÍÍÔÔÔĐĐĐĚĚĚ×××××××××ÎÎÎĐĐĐÍÍÍĆĆƦ¦¦±±±±±±±±±´´´±±±µµµÎÎÎâââßßßîîîęęęńńńčččââââââÜÜÜäääâââÜÜÜŘŘŘ×××ŃŃŃÉÉÉĆĆĆĘĘĘÉÉÉÇÇÇĚĚĚŐŐŐ×××ĐĐĐŇŇŇŘŘŘŐŐŐ×××ŘŘŘÔÔÔÎÎÎŃŃŃÝÝÝčččŕŕŕęęęÝÝÝÉÉÉĘĘĘÔÔÔ×××ŮŮŮŰŰŰÔÔÔÉÉÉÇÇÇĐĐĐ×××ăăăóóóőőőęęęăăăäääçççčččîîîřřřÜÜÜÜÜÜÔÔÔŃŃŃŃŃŃÔÔÔĚĚĚĹĹĹŔŔŔ±±±´´´ÎÎÎŰŰŰŮŮŮŮŮŮŃŃŃŐŐŐŇŇŇÍÍÍÎÎÎżżżłłłľľľÂÂÂĐĐĐÍÍÍÉÉÉĹĹĹÂÂÂÂÂÂÂÂÂĂĂĂĆĆĆÇÇÇľľľşşşĂĂĂĘĘĘĘĘĘÍÍÍŇŇŇŘŘŘÎÎÎĆĆĆĚĚĚĚĚĚÉÉÉŃŃŃĐĐĐŃŃŃÎÎÎĚĚĚÍÍÍŃŃŃŃŃŃÍÍÍĐĐĐŃŃŃÜÜÜ×××ÝÝÝŐŐŐŰŰŰŮŮŮŰŰŰÜÜÜÝÝÝŕŕŕâââăăăćććçççäääŕŕŕçççîîîîîîďďďŕŕŕľľľĹĹĹÇÇÇĚĚĚÍÍÍÍÍÍÍÍÍÎÎÎĐĐĐŇŇŇÎÎÎŃŃŃÇÇÇŃŃŃľľľ···µµµĽĽĽżżżŘŘŘ»»»ĘĘĘŃŃŃÇÇÇĽĽĽ»»»ÍÍÍĚĚĚÂÂÂÂÂÂŔŔŔľľľĹĹĹ»»»»»»şşşşşşşşşĽĽĽľľľżżżŔŔŔŔŔŔÂÂÂĂĂĂĂĂĂĂĂĂÂÂÂÂÂÂÂÂÂŔŔŔŔŔŔżżżżżżŔŔŔŔŔŔÂÂÂÂÂÂĹĹĹĹĹĹÍÍÍĚĚĚĚĚĚÔÔÔĚĚĚĽĽĽÉÉÉÝÝÝĂĂĂ»»»ŔŔŔĐĐĐŇŇŇŘŘŘÔÔÔŇŇŇÔÔÔŇŇŇÎÎÎÎÎÎŃŃŃĐĐĐĘĘĘĆĆĆíííâââÜÜÜćććęęęŘŘŘÝÝÝŰŰŰŘŘŘŘŘŘÍÍÍĂĂĂĘĘĘŇŇŇÔÔÔÍÍÍĚĚĚŃŃŃÎÎÎÎÎÎŰŰŰĐĐĐŐŐŐĐĐĐÎÎÎŐŐŐŇŇҨ¨¨°°°±±±±±±łłł¬¬¬­­­ĘĘĘŕŕŕŮŮŮăăăâââŕŕŕŮŮŮŰŰŰăăăßßßŰŰŰŰŰŰÝÝÝŮŮŮĐĐĐĘĘĘĚĚĚÍÍÍĘĘĘÉÉÉĘĘĘÉÉÉÔÔÔ×××ŇŇŇ××××××ŐŐŐŘŘŘŰŰŰŘŘŘŃŃŃĐĐĐÜÜÜęęęßßßîîîŕŕŕĆĆĆĹĹĹĐĐĐÔÔÔŮŮŮ×××ŘŘŘĚĚĚÂÂÂÉÉÉŃŃŃŰŰŰíííúúúöööóóóőőőďďďćććÝÝÝÝÝÝĹĹĹÔÔÔŐŐŐŃŃŃĂĂĂŔŔŔľľľĂĂĂľľľ±±±ĂĂĂÔÔÔŐŐŐŕŕŕŕŕŕŃŃŃ×××ŃŃŃĚĚĚÍÍÍżżż´´´ĹĹĹĚĚĚÍÍÍĚĚĚĘĘĘÇÇÇĹĹĹĂĂĂÂÂÂŔŔŔÂÂÂĂĂĂ»»»···ŔŔŔĘĘĘĚĚĚÎÎÎĐĐĐÔÔÔĘĘĘÇÇÇŃŃŃÎÎÎĘĘĘŐŐŐÔÔÔÔÔÔŃŃŃÎÎÎÎÎÎŃŃŃÎÎÎĘĘĘÜÜÜŮŮŮÝÝÝŐŐŐŰŰŰÔÔÔŮŮŮŘŘŘŮŮŮŰŰŰßßßâââćććççççççćććäääăăăęęęňňňóóóëëëÔÔÔľľľŔŔŔĂĂĂÇÇÇĘĘĘĘĘĘĘĘĘĚĚĚÍÍÍŃŃŃĘĘĘŃŃŃÉÉÉÔÔÔ´´´µµµ¸¸¸ĽĽĽľľľŇŇŇşşşÍÍÍÇÇÇĂĂĂÂÂÂÎÎÎÎÎÎÉÉÉÂÂÂľľľĽĽĽ»»»ĽĽĽĽĽĽ»»»şşşşşş»»»ĽĽĽľľľżżżżżżżżżŔŔŔÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂŔŔŔżżżżżżŔŔŔŔŔŔŔŔŔÂÂÂĂĂĂĂĂĂĚĚĚĘĘĘĘĘĘŐŐŐÎÎÎŔŔŔĚĚĚßßßżżż°°°´´´żżż»»»ŇŇŇĐĐĐŃŃŃÔÔÔŐŐŐŇŇŇŇŇŇŐŐŐŇŇŇŃŃŃÂÂÂřřřńńńëëëăăăćććßßßÝÝÝÝÝÝÝÝÝŰŰŰŃŃŃĘĘĘĚĚĚ×××ÔÔÔÎÎÎĐĐĐÔÔÔŃŃŃĚĚĚĚĚĚ×××ŮŮŮŮŮŮŮŮŮŘŘŘĐĐСˇˇ©©©°°°±±±´´´ŻŻŻ°°°ŃŃŃęęęŕŕŕăăăçççâââßßßäääęęęçççŘŘŘŘŘŘŰŰŰŘŘŘĐĐĐĚĚĚÎÎÎŃŃŃĐĐĐĚĚĚÍÍÍĆĆĆĐĐĐŐŐŐŇŇŇŮŮŮŐŐŐŐŐŐŐŐŐ×××ŐŐŐŃŃŃÎÎÎ×××ŕŕŕćććęęęÔÔÔŔŔŔĆĆĆĚĚĚĘĘĘŃŃŃŇŇŇŮŮŮ×××ÉÉÉĹĹĹĚĚĚ×××ßßß×××ŰŰŰŕŕŕäääŕŕŕŘŘŘŃŃŃÎÎÎŇŇŇÜÜÜŃŃŃÎÎÎĆĆĆÉÉÉľľľŔŔŔłłłŞŞŞĐĐĐŕŕŕÔÔÔŰŰŰÜÜÜŃŃŃŃŃŃĹĹĹ»»»Â»»»¸¸¸ÉÉÉÍÍÍĆĆĆÇÇÇÉÉÉÉÉÉÉÉÉĆĆĆĹĹĹĂĂĂżżżÂÂÂşşşµµµÂÂÂĚĚĚÎÎÎĐĐĐÍÍÍĐĐĐÇÇÇÉÉÉŐŐŐŃŃŃĚĚĚŮŮŮŘŘŘŘŘŘÔÔÔĐĐĐÎÎÎĐĐĐÍÍÍÇÇÇÝÝÝŮŮŮÝÝÝŐŐŐÝÝÝ×××ÜÜÜŮŮŮÜÜÜÝÝÝâââćććčččçççäääŕŕŕßßßçççńńńóóóîîî×××»»»°°°ľľľÂÂÂĆĆĆÉÉÉÉÉÉÉÉÉÉÉÉĘĘĘŃŃŃÉÉÉĐĐĐÉÉÉŐŐŐ°°°µµµľľľ¸¸¸żżżŇŇŇ»»»ĘĘĘ»»»ÂÂÂĚĚĚŃŃŃÇÇÇŔŔŔżżżĽĽĽľľľŔŔŔżżżĽĽĽ»»»»»»şşş»»»ĽĽĽżżżŔŔŔľľľżżżŔŔŔÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂŔŔŔżżżżżżżżżŔŔŔŔŔŔľľľżżżŔŔŔĘĘĘĘĘĘÍÍÍŮŮŮŐŐŐÇÇÇĘĘĘŘŘŘĽĽĽĽĽĽĚĚĚŘŘŘÎÎÎŘŘŘÔÔÔŃŃŃŇŇŇŇŇŇĐĐĐŇŇŇ×××ŘŘŘŮŮŮĽĽĽöööňňňóóóäääçççčččŰŰŰŮŮŮÜÜÜŐŐŐŇŇŇŃŃŃĚĚĚŮŮŮĐĐĐÉÉÉĘĘĘŇŇŇ×××ŇŇŇĚĚĚÉÉÉÇÇÇŐŐŐßßßŘŘŘĐĐШ¨¨łłł­­­°°°µµµŻŻŻ°°°ÔÔÔëëëŕŕŕçççßßßÔÔÔăăăćććŐŐŐŇŇŇÍÍÍŇŇŇÎÎÎÎÎÎÎÎÎĚĚĚĆĆĆÉÉÉĐĐĐÎÎÎÎÎÎĂĂĂĘĘĘŃŃŃŇŇŇÜÜÜÔÔÔŰŰŰŘŘŘŘŘŘÜÜÜßßßßßßăăăčččäääÜÜÜĂĂĂĽĽĽÍÍÍĐĐĐÇÇÇÎÎÎŃŃŃŮŮŮßßßŇŇŇÂÂÂÉÉÉŐŐŐŇŇŇ××××××ŐŐŐÔÔÔŐŐŐÜÜÜćććíííŘŘŘßßßÎÎÎÇÇÇľľľŔŔŔµµµ»»»°°°­­­ŃŃŃŘŘŘÔÔÔŕŕŕÔÔÔĘĘĘŔŔŔÉÉÉÉÉÉ»»»ĹĹĹĐĐĐÇÇÇÇÇÇÉÉÉĘĘĘĘĘĘÉÉÉĆĆĆĹĹĹĂĂĂĹĹĹĆĆĆ»»»´´´¸¸¸ÇÇÇĐĐĐÇÇÇ»»»ŔŔŔÂÂÂÉÉÉŇŇŇ×××ÔÔÔŇŇŇŐŐŐŐŐŐŐŐŐÎÎÎÔÔÔŇŇŇÉÉÉĘĘĘĆĆĆŮŮŮÝÝÝââââââŕŕŕÝÝÝÜÜÜÜÜÜŕŕŕâââăăăććććććääääääćććßßßřřřňňňńńńęęęÝÝÝĽĽĽşşşĽĽĽÂÂÂÇÇÇÇÇÇĆĆĆĹĹĹÉÉÉĚĚĚĐĐĐÎÎÎŃŃŃ××׺şş´´´¸¸¸ĹĹĹŮŮŮŃŃŃÂÂÂĐĐĐĹĹŵµµĐĐĐŘŘŘŐŐŐĆĆĆÂÂÂŔŔŔĽĽĽżżżĂĂĂĽĽĽşşşşşş»»»ĽĽĽĽĽĽľľľżżżżżżżżżżżżżżżżżżżżżÂÂÂĂĂĂĹĹĹÂÂÂŔŔŔľľľĽĽĽĽĽĽżżżÂÂÂĂĂĂÂÂÂÂÂÂżżżĚĚĚĘĘĘĘĘĘŰŰŰŇŇŇşşşĚĚĚÔÔÔÂÂÂżżżÝÝÝĘĘĘŃŃŃÍÍÍŐŐŐŐŐŐŃŃŃŇŇŇÎÎÎĚĚĚÔÔÔŮŮŮÔÔÔÍÍÍîîîëëëřřřäääćććććć×××ÝÝÝÜÜÜÝÝÝÍÍÍĐĐĐĘĘĘÎÎÎŐŐŐŇŇŇĆĆĆÂÂÂĚĚĚŃŃŃÎÎÎŇŇŇÂÂÂĹĹĹĐĐĐŇŇŇŘŘŘĘĘʨ¨¨±±±¸¸¸­­­°°°łłłÔÔÔßßßäääŮŮŮÔÔÔŰŰŰäääććććććßßßĐĐĐĐĐĐŇŇŇÔÔÔŃŃŃÎÎÎÍÍÍÎÎÎĐĐĐÔÔÔÉÉÉĂĂĂĐĐĐŐŐŐŃŃŃ×××ÝÝÝęęęćććíííęęęííííííßßßăăă×××ÂÂÂżżżĘĘĘĘĘĘÉÉÉĚĚĚĚĚĚŮŮŮŇŇŇîîîŮŮŮĽĽĽÉÉÉÇÇÇÉÉÉĹĹĹŇŇŇÝÝÝćććńńńůůůňňňäääâââŰŰŰĹĹĹĐĐĐŔŔŔµµµ±±±¸¸¸ÎÎÎĆĆĆŮŮŮŐŐŐÉÉÉÎÎÎĹĹĹşşşĹĹĹĹĹĹŔŔŔ´´´»»»ÉÉÉĆĆĆÍÍÍĐĐĐĐĐĐÍÍÍĘĘĘĆĆĆĂĂĂĹĹĹĆĆĆĆĆĆżżż»»»żżżĆĆĆÇÇÇĂĂĂľľľľľľľľľĂĂĂÍÍÍŇŇŇŇŇŇÔÔÔŘŘŘŰŰŰŘŘŘÍÍÍŇŇŇŃŃŃĘĘĘÎÎÎÍÍÍŮŮŮŰŰŰÜÜÜÜÜÜŰŰŰÜÜÜßßßâââŕŕŕâââäääćććććććććääääääčččőőőńńńřřříííŘŘŘşşş»»»żżżĂĂĂÇÇÇÇÇÇĹĹĹĹĹĹÉÉÉÍÍÍÍÍÍĘĘĘÉÉÉĆĆƵµµ¸¸¸ĆĆĆŇŇŇÔÔÔĚĚĚĽĽĽĚĚĚĆĆĆşşşĘĘĘÇÇÇÎÎÎÉÉÉÉÉÉÇÇÇĹĹĹĂĂĂĂĂĂżżżşşşşşş»»»ĽĽĽĽĽĽľľľżżżżżżżżżżżżżżżŔŔŔÂÂÂĂĂĂĹĹĹĹĹĹĂĂĂŔŔŔżżżĽĽĽľľľżżżÂÂÂĂĂĂĂĂĂĹĹĹĂĂĂĘĘĘÇÇÇÇÇÇŇŇŇÉÉÉľľľĐĐĐÔÔÔ»»»¸¸¸ŮŮŮÉÉÉÉÉÉŇŇŇŐŐŐĐĐĐĚĚĚĐĐĐÎÎÎÍÍÍŇŇŇÔÔÔ×××ÎÎÎććććććůůůčččâââăăăÔÔÔÝÝÝââââââĐĐĐÍÍÍĆĆĆÎÎÎŮŮŮßßßÔÔÔÇÇÇĂĂĂĂĂĂÂÂÂ×××ĐĐĐÍÍÍÉÉÉĘĘĘ×××ÎÎÎŻŻŻŻŻŻłłł±±±ŔŔŔÉÉÉŕŕŕćććëëëŮŮŮŐŐŐÜÜÜćććććććććŕŕŕŇŇŇŇŇŇÔÔÔŐŐŐŇŇŇĐĐĐÎÎÎÎÎÎĐĐĐĘĘĘĘĘĘÎÎÎŮŮŮÝÝÝŮŮŮ×××ŐŐŐîîîććććććăăăćććíííčččäääÉÉÉżżżÂÂÂĘĘĘÉÉÉÉÉÉĐĐĐÔÔÔĚĚĚŇŇŇîîîâââÍÍÍŃŃŃĚĚĚÉÉÉŐŐŐâââęęęččččččëëëćććŰŰŰŮŮŮÎÎÎĆĆĆÇÇÇ°°°­­­ĄĄĄ¦¦¦ÝÝÝŐŐŐ×××ĐĐĐĂĂĂÇÇÇÇÇÇľľľĆĆĆŔŔŔĽĽĽµµµĽĽĽĆĆĆĹĹĹÎÎÎÎÎÎÍÍÍĘĘĘĆĆĆĂĂĂÂÂÂĹĹĹÇÇÇÇÇÇĂĂĂĹĹĹÇÇÇĹĹĹľľľľľľĂĂĂŔŔŔŔŔŔĂĂĂÍÍÍŇŇŇÔÔÔŘŘŘÝÝÝŮŮŮ×××ÍÍÍŇŇŇÔÔÔŃŃŃŮŮŮŮŮŮÝÝÝßßßŕŕŕßßßÝÝÝÜÜÜŰŰŰÜÜÜääääääććććććçççççççççäääóóóřřřöööőőőÜÜÜĘĘĘĽĽĽżżżĂĂĂĆĆĆÇÇÇÇÇÇĆĆĆÇÇÇĚĚĚĐĐĐŮŮŮŐŐŐĐĐĐŔŔŔ»»»ĂĂĂŐŐŐŮŮŮĐĐĐÇÇÇşşşĆĆĆÇÇÇŔŔŔÇÇÇşşşĚĚĚĐĐĐÎÎÎÍÍÍÍÍÍÇÇÇżżżĽĽĽşşşşşş»»»ĽĽĽĽĽĽľľľżżżżżżżżżŔŔŔÂÂÂĂĂĂĹĹĹĹĹĹĹĹĹĹĹĹĂĂĂÂÂÂŔŔŔľľľľľľŔŔŔÂÂÂĂĂĂĹĹĹÉÉÉÇÇÇÇÇÇĹĹĹĹĹĹĘĘĘżżżżżżÇÇÇĘĘʸ¸¸´´´ĘĘĘĽĽĽżżżÉÉÉĘĘĘÇÇÇÇÇÇÎÎÎĐĐĐÎÎÎŃŃŃŇŇŇ×××ĐĐĐćććëëëüüüčččâââęęę×××ŰŰŰăăăŕŕŕÍÍÍÉÉÉĹĹĹÂÂÂĚĚĚÔÔÔÔÔÔÎÎÎÉÉÉÇÇÇÇÇÇĆĆĆÇÇÇĹĹĹŔŔŔĚĚĚßßßâââÔÔÔ©©©ŻŻŻ¸¸¸ŃŃŃßßßęęęçççęęęŘŘŘŘŘŘßßßćććććććććâââŮŮŮÔÔÔŐŐŐÔÔÔŇŇŇĐĐĐÎÎÎÎÎÎÎÎÎâââÝÝÝŮŮŮŐŐŐŐŐŐŘŘŘŮŮŮŰŰŰíííäääßßßŕŕŕâââęęęëëëŐŐŐľľľŔŔŔÉÉÉĚĚĚÇÇÇĘĘĘÔÔÔ×××ŃŃŃßßßčččŕŕŕŘŘŘŮŮŮÜÜÜßßßŰŰŰćććíííçççăăăăăăâââÝÝÝŘŘŘÇÇÇĚĚĚĆĆĆ···ŃŃŃŮŮŮŰŰŰŕŕŕŰŰŰÔÔÔÍÍÍĂĂĂĆĆĆĚĚĚ»»»ÂÂÂĂĂĂÉÉÉĘĘĘĂĂĂĘĘĘĂĂĂĂĂĂĂĂĂÂÂÂŔŔŔÂÂÂĹĹĹÇÇÇĘĘĘĆĆĆÇÇÇÍÍÍĆĆĆ»»»ľľľÇÇÇĘĘĘÉÉÉĚĚĚŇŇŇŐŐŐ×××ŰŰŰßßßŐŐŐÔÔÔÍÍÍ×××ŰŰŰŮŮŮââââââăăăââââââŕŕŕŕŕŕŕŕŕăăăäääóóóőőőóóóňňňóóóööööööóóóőőőřřřöööŕŕŕľľľşşşÂÂÂĹĹĹĆĆĆÇÇÇÉÉÉÉÉÉÉÉÉÍÍÍŇŇŇŘŘŘâââßßßŮŮŮŔŔŔĹĹĹÍÍÍÜÜÜŐŐŐÍÍÍÉÉÉżżżĆĆĆÇÇÇĆĆĆĚĚĚĽĽĽĂĂĂĚĚĚÉÉÉÇÇÇŃŃŃÎÎÎŔŔŔĽĽĽşşşşşş»»»ĽĽĽĽĽĽľľľżżżżżżżżżŔŔŔÂÂÂĹĹĹĆĆĆĆĆĆĆĆĆĹĹĹĹĹĹĂĂĂÂÂÂŔŔŔżżżŔŔŔÂÂÂĂĂĂĆĆĆĘĘĘĘĘĘĹĹĹĂĂĂĆĆĆĆĆĆľľľĹĹĹ···¸¸¸ľľľÇÇÇĚĚĚşşşşşşŔŔŔĹĹĹÇÇÇĚĚĚÎÎÎÎÎÎÍÍÍÎÎÎÔÔÔŃŃŃÍÍÍęęęőőőúúúćććçççřřřßßßŘŘŘÝÝÝŘŘŘÉÉÉÇÇÇĘĘĘĆĆĆĂĂĂÂÂÂĆĆĆĘĘĘÍÍÍĚĚĚĘĘĘĹĹĹĹĹĹÂÂÂĹĹĹÎÎÎ×××ÝÝÝăăăâââŕŕŕßßßäääćććäääŰŰŰŐŐŐ×××ŮŮŮßßßäääćććććććććăăăřřřöööóóóîîîčččăăăŕŕŕÝÝÝçççŕŕŕßßß×××ŐŐŐŘŘŘŘŘŘÝÝÝęęęăăăßßßäääâââćććää似ĽŔŔŔÉÉÉĐĐĐÍÍÍĘĘĘÎÎÎŇŇŇŇŇŇŰŰŰëëëäääŕŕŕŕŕŕŕŕŕëëëńńńŰŰŰăăăçççäääăăăäääăăăŕŕŕŮŮŮĚĚĚĹĹĹ···łłłŃŃŃÜÜÜŐŐŐÉÉÉÇÇÇĆĆĆÇÇÇÇÇÇÎÎÎŇŇŇĚĚĚżżż¸¸¸ĂĂĂĘĘĘÍÍÍĘĘĘŔŔŔĹĹĹżżżŔŔŔĂĂĂĂĂĂĂĂĂĂĂĂĆĆĆÇÇÇÍÍÍÇÇÇÇÇÇÍÍÍÉÉÉŔŔŔĂĂĂÍÍÍŇŇŇĐĐĐŃŃŃŐŐŐ×××ŐŐŐŐŐŐŘŘŘÔÔÔŐŐŐŇŇŇßßßăăăÝÝÝâââßßßÝÝÝŰŰŰŮŮŮŰŰŰŕŕŕčččńńńőőőîîîîîîíííčččęęęîîîîîîčččëëëäääßßßÉÉÉłłłµµµĆĆĆÇÇÇÇÇÇÇÇÇÉÉÉĘĘĘÎÎÎÔÔÔŰŰŰßßßßßßÝÝÝÔÔÔ¸¸¸ĹĹĹŃŃŃÜÜÜŃŃŃÎÎÎÍÍÍĘĘĘĘĘĘĆĆĆÉÉÉŇŇŇĚĚĚľľľÂ»»»ľľľĐĐĐÔÔÔÇÇÇľľľşşşşşş»»»ĽĽĽĽĽĽľľľżżżżżżżżżŔŔŔÂÂÂĹĹĹĹĹĹĆĆĆĹĹĹĹĹĹĆĆĆĹĹĹĂĂĂÂÂÂÂÂÂÂÂÂĂĂĂĂĂĂĆĆĆÉÉÉÉÉÉĂĂĂĂĂĂÇÇÇĹĹĹĂĂĂĹĹĹ»»»ĹĹĹÍÍÍÎÎεµµ···ĽĽĽŔŔŔÇÇÇÉÉÉĹĹĹĂĂĂĆĆĆÇÇÇŃŃŃĚĚĚĹĹĹÝÝÝńńńöööćććęęęůůůâââ×××ŰŰŰŇŇŇĚĚĚÍÍÍŇŇŇŮŮŮĐĐĐĆĆĆÂÂÂÂÂÂżżżĽĽĽ»»»ĹĹĹĆĆĆĆĆĆÉÉÉÎÎÎĐĐĐŐŐŐÜÜÜćććçççäääÝÝÝâââččččččßßßŐŐŐŮŮŮßßßăăăççççççčččęęęâââŕŕŕâââăăăääääääććććććŰŰŰ×××ŕŕŕÝÝÝÝÝÝŕŕŕÜÜÜçççęęęäääŕŕŕčččäääćććßßßµµµĹĹĹÍÍÍÎÎÎÍÍÍĐĐĐŐŐŐŐŐŐĐĐĐÔÔÔęęęăăăçççîîîäääčččçççŕŕŕăăăăăăăăăääääääÝÝÝ×××ĐĐĐÍÍÍżżżĽĽĽÎÎÎßßßćććŇŇŇÇÇÇĆĆĆÇÇÇĹĹĹĹĹĹÉÉÉ»»»ĂĂø¸¸ŔŔŔĹĹĹĹĹĹĆĆĆŔŔŔĂĂĂĹĹĹĆĆĆÉÉÉÉÉÉÇÇÇÇÇÇÇÇÇÉÉÉÎÎÎĘĘĘĘĘĘÍÍÍĘĘĘĆĆĆĘĘĘÔÔÔÔÔÔŃŃŃŃŃŃÔÔÔÔÔÔĐĐĐĐĐĐŇŇŇŮŮŮÜÜÜŮŮŮäääćććÝÝÝÝÝÝŮŮŮŐŐŐŘŘŘÝÝÝäääęęęîîîîîîîîîőőőůůůöööňňňňňňőőőîîîäääŮŮŮĹĹĹÂÂÂľľľľľľĽĽĽÇÇÇĹĹĹÉÉÉÉÉÉÉÉÉĚĚĚĐĐĐ×××ÝÝÝâââćććäääŇŇŇşşşÂÂÂŇŇŇ×××ÍÍÍÍÍÍÎÎÎŇŇŇĐĐĐĹĹĹĆĆĆŃŃŃŇŇŇÇÇÇĆĆĆĽĽĽşşşÇÇÇĐĐĐĹĹĹ···şşşşşş»»»ĽĽĽĽĽĽľľľżżżżżżľľľżżżŔŔŔÂÂÂĂĂĂĂĂĂĂĂĂĹĹĹÇÇÇĆĆĆĹĹĹĂĂĂĂĂĂĂĂĂĂĂĂĂĂĂĆĆĆĆĆĆÉÉÉĹĹĹÇÇÇÇÇÇżżżĹĹŵµµµµµĹĹĹĂĂĂŔŔŔ······łłł···¸¸¸ľľľżżż»»»ľľľĆĆĆÉÉÉĆĆĆÇÇÇľľľÉÉÉäääňňňčččçççíííßßßŘŘŘÝÝÝŇŇŇÔÔÔŐŐŐŮŮŮŐŐŐŐŐŐŇŇŇĘĘĘÂÂÂľľľĽĽĽĽĽĽ»»»ŔŔŔĆĆĆĆĆĆÉÉÉŐŐŐÜÜÜŘŘŘÎÎÎŮŮŮäääÝÝÝääääääŕŕŕĐĐĐ×××ÜÜÜÝÝÝŕŕŕçççččččččíííčččçççäääăăăâââŕŕŕßßßÜÜÜŕŕŕâââńńńęęęçççîîîäääííííííćććâââäääăăăćććÜÜÜżżżĂĂĂĘĘĘÉÉÉĘĘĘÔÔÔŰŰŰŘŘŘÔÔÔĐĐĐŕŕŕÝÝÝäääëëëâââŕŕŕÜÜÜâââŕŕŕŕŕŕâââäääăăăŰŰŰŃŃŃĘĘĘÇÇǸ¸¸ľľľŮŮŮÝÝÝßßßĚĚĚĂĂĂŔŔŔÉÉÉĂĂĂÇÇÇĐĐĐÂÂÂŔŔŔÉÉÉĽĽĽÂÂÂŔŔŔľľľĹĹĹĹĹĹĆĆĆĆĆĆÇÇÇÉÉÉÉÉÉÉÉÉÉÉÉĚĚĚÍÍÍÍÍÍĐĐĐŃŃŃÍÍÍĆĆĆĆĆĆĐĐĐÜÜÜ×××ŃŃŃĐĐĐŃŃŃŇŇŇĐĐĐŇŇŇ×××ÝÝÝßßßŮŮŮâââăăăÜÜÜßßßŰŰŰßßßâââčččďďďóóóňňňíííçççíííóóóóóóďďďíííęęęŰŰŰĘĘĘÇÇÇşşş»»»»»»ĹĹĹżżżĆĆĆĂĂĂÉÉÉÉÉÉÉÉÉĚĚĚĐĐĐŐŐŐŰŰŰÝÝÝäääçççŇŇŇÂÂÂĆĆĆ×××ŃŃŃÉÉÉÉÉÉĘĘĘÔÔÔÔÔÔĆĆĆÂÂÂÇÇÇĚĚĚŃŃŃÍÍÍÇÇÇŔŔŔŔŔŔÉÉÉĹĹĹ´´´şşşşşş»»»ĽĽĽĽĽĽľľľżżżżżżľľľľľľľľľżżżŔŔŔÂÂÂĂĂĂĂĂĂÇÇÇÇÇÇĆĆĆĹĹĹĹĹĹĂĂĂĂĂĂĂĂĂĆĆĆĂĂĂÉÉÉÇÇÇĘĘĘĂĂĂ´´´żżżÎÎÎľľľşşş±±±´´´¬¬¬ŻŻŻźźź¨¨¨¤¤¤©©©ŻŻŻŻŻŻ±±±łłł¬¬¬ĽĽĽŔŔŔ»»»ÉÉÉčččóóóçççäääçççăăăÜÜÜßßßŃŃŃŘŘŘŘŘŘŰŰŰĚĚĚÔÔÔŘŘŘŃŃŃĚĚĚÍÍÍÎÎÎĘĘĘĆĆĆĂĂĂÇÇÇÇÇÇĹĹĹĐĐĐŮŮŮŃŃŃÎÎÎŘŘŘčččćććëëëâââÜÜÜÎÎÎÜÜÜâââßßßßßßćććçççäääęęęęęęçççääääääääääääâââßßßâââííí˙˙˙ćććßßßďďďäääâââëëëâââßßßÝÝÝÝÝÝÜÜÜÍÍÍżżżżżżĆĆĆĹĹĹÇÇÇŇŇŇ×××ŐŐŐŘŘŘ×××ŰŰŰŘŘŘÜÜÜŕŕŕÝÝÝßßßÝÝÝÝÝÝßßßŕŕŕâââŕŕŕÝÝÝŘŘŘŐŐŐÎÎÎżżżĂĂĂÎÎÎăăăââââââÔÔÔĘĘĘĂĂĂÎÎÎĆĆĆĘĘĘ×××ĹĹĹÇÇÇÎÎÎÂÂÂÇÇÇÂÂÂżżżÇÇÇÉÉÉÇÇÇÂÂÂÂÂÂĂĂĂĂĂĂĹĹĹÉÉÉÍÍÍŃŃŃĚĚĚŐŐŐŘŘŘÎÎÎĂĂĂĹĹĹŇŇŇŕŕŕŘŘŘŇŇŇĐĐĐŃŃŃŇŇŇÔÔÔŮŮŮßßßßßßÝÝÝ×××ÝÝÝŕŕŕÜÜÜăăăâââńńńîîîęęęëëëďďďöööůůůüüüćććîîîńńńíííčččŕŕŕĚĚ̵µµ»»»żżżĆĆƸ¸¸żżż»»»ĹĹĹĂĂĂÉÉÉÉÉÉÉÉÉĘĘĘÎÎÎŇŇŇ×××ŘŘŘÍÍÍŘŘŘÉÉÉĹĹĹÉÉÉŮŮŮĚĚĚĹĹĹĹĹĹĹĹĹŇŇŇŐŐŐÇÇÇľľľĽĽĽŔŔŔÍÍÍĚĚĚĚĚĚĆĆĆżżżĘĘĘÎÎÎŔŔŔşşşşşş»»»ĽĽĽĽĽĽľľľżżżżżżľľľĽĽĽĽĽĽĽĽĽľľľżżżÂÂÂĂĂĂÉÉÉÇÇÇÇÇÇĆĆĆĹĹĹĂĂĂĂĂĂĂĂĂÇÇÇÂÂÂÉÉÉĚĚĚÍÍÍŔŔŔŞŞŞ¸¸¸ľľľ°°°···łłł°°°©©©ÇÇÇŐŐŐÝÝÝ×××ŰŰŰăăăâââßßßŇŇŇľľľ¸¸¸şşşĽĽĽ×××úúúřřřääääääíííęęęŕŕŕßßßĚĚĚŐŐŐŘŘŘŰŰŰŘŘŘÝÝÝÜÜÜŇŇŇŇŇŇŘŘŘÔÔÔĘĘĘŇŇŇżżżÂÂÂĘĘĘĹĹĹĚĚĚŘŘŘŐŐŐŮŮŮŐŐŐÜÜÜŐŐŐÜÜÜŇŇŇÜÜÜÝÝÝâââäääßßßÝÝÝćććäääâââćććčččćććăăăăăăääääääâââßßßâââëëëëë뼼Ľ´´´ÝÝÝäääçççćććÜÜÜÝÝÝŘŘŘŘŘŘŇŇŇşşşµµµľľľĹĹĹĹĹĹÇÇÇĐĐĐĐĐĐĐĐĐŘŘŘŰŰŰŘŘŘŮŮŮÝÝÝßßßŕŕŕŕŕŕÝÝÝŕŕŕăăăäääâââŰŰŰÔÔÔŇŇŇÔÔÔĘĘĘ´´´ŇŇŇäääíííăăăŮŮŮĚĚĚĐĐĐĘĘĘÉÉÉÍÍÍŇŇŇŃŃŃÉÉÉżżżĹĹĹĹĹĹĹĹĹĹĹĹĹĹĹĹĹĹĂĂĂÂÂÂżżżĹĹĹÍÍÍŃŃŃŇŇŇŇŇŇŃŃŃŃŃŃ×××ŘŘŘÔÔÔÍÍÍĚĚĚŇŇŇŮŮŮÜÜÜŕŕŕĐĐĐÔÔÔŇŇŇÔÔÔÔÔÔÍÍÍŮŮŮ×××ÝÝÝâââóóóííííííćććďďďîîîďďďňňňőőőöööřřřůůůůůůńńńóóóőőőíííŘŘŘĂĂĂľľľĂĂĂżżżŔŔŔŔŔŔżżżľľľżżżÂÂÂĹĹĹÉÉÉĆĆĆĹĹĹÇÇÇĚĚĚŃŃŃŇŇŇÔÔÔŰŰŰÔÔÔŔŔŔĂĂĂĆĆĆ×××ÎÎÎĆĆĆÉÉÉŃŃŃŃŃŃŇŇŇÎÎÎÎÎÎÍÍÍ···¸¸¸ŔŔŔĐĐĐŔŔŔľľľÔÔÔÎÎÎľľľ»»»ĽĽĽĽĽĽĽĽĽ»»»»»»ľľľżżżĽĽĽĽĽĽĽĽĽĽĽĽľľľŔŔŔĂĂĂĹĹĹÉÉÉÇÇÇĆĆĆĹĹĹĂĂĂĂĂĂĹĹĹĆĆĆĆĆĆĘĘĘĆĆĆĚĚĚÔÔÔĂĂĂłłł»»»»»»łłł°°°­­­žžž©©©ÍÍÍŃŃŃ×××ŐŐŐŃŃŃ×××ăăăÝÝÝŐŐŐŮŮŮŘŘŘćććččččččóóóőőőęęęäääëëëöööÜÜÜŕŕŕŇŇŇÔÔÔÝÝÝŐŐŐŮŮŮßßßÝÝÝÔÔÔĐĐĐŐŐŐŇŇŇĘĘĘŃŃŃÂÂÂĆĆĆĘĘĘÍÍÍÉÉÉâââÜÜÜŘŘŘŃŃŃŘŘŘÝÝÝŘŘŘ×××ÝÝÝßßßâââßßßâââçççčččććććććęęęäääŕŕŕßßßâââăăăßßßßßßäääŕŕŕäääÝÝÝ»»»»»»±±±ŮŮŮÝÝÝŰŰŰ···łłłµµµ······°°°şşşÂÂÂĂĂĂĹĹĹÉÉÉÍÍÍŃŃŃÔÔÔ××××××ŮŮŮŰŰŰÝÝÝßßßŕŕŕŕŕŕŕŕŕŰŰŰÝÝÝÜÜÜŐŐŐŇŇŇÔÔÔŃŃŃĚĚĚ···şşşÝÝÝâââÝÝÝćććŐŐŐÎÎÎÍÍÍÎÎÎÎÎÎĐĐĐÎÎÎÍÍÍĘĘĘÇÇÇżżżżżżżżżŔŔŔÂÂÂĹĹĹÇÇÇÉÉÉĂĂĂĹĹĹÇÇÇĚĚĚĐĐĐŃŃŃÍÍÍĘĘĘŘŘŘŮŮŮŐŐŐÍÍÍĚĚĚŃŃŃŘŘŘŰŰŰÔÔÔÇÇÇÍÍÍĐĐĐÔÔÔŐŐŐÔÔÔŕŕŕŕŕŕääääääóóóďďďőőőîîîňňňîîîîîîîîîďďďńńńńńńďďďîîîöööîîîäääŘŘŘÉÉÉ»»»¸¸¸ľľľżżżżżżżżżľľľľľľľľľÂÂÂĹĹĹÇÇÇĆĆĆĆĆĆÇÇÇĚĚĚĐĐĐŇŇŇÔÔÔÍÍÍĆĆĆşşşĹĹĹĚĚĚÜÜÜŐŐŐŃŃŃĘĘĘĐĐĐÍÍÍĘĘĘÂÂÂŔŔŔÇÇǸ¸¸ŔŔŔÂÂÂÉÉÉÂÂÂĽĽĽĆĆĆÇÇÇľľľ»»»ĽĽĽĽĽĽĽĽĽ»»»»»»ĽĽĽżżżĽĽĽĽĽĽĽĽĽĽĽĽľľľŔŔŔĂĂĂĹĹĹÉÉÉÇÇÇĆĆĆĹĹĹĂĂĂĂĂĂĹĹĹĆĆĆĆĆĆÉÉÉĆĆĆÍÍÍŐŐŐĆĆĆ´´´»»»ÂÂÂľľľ´´´¬¬¬¦¦¦ľľľŰŰŰŇŇŇ×××ŃŃŃÍÍÍŐŐŐăăăćććăăăäääăăăëëëęęęęęęńńńíííâââÜÜÜęęęďďďŰŰŰęęęÜÜÜŐŐŐŰŰŰŰŰŰŰŰŰßßßÜÜÜŇŇŇĐĐĐŐŐŐŐŐŐĐĐĐĘĘĘŔŔŔÇÇÇĚĚĚÎÎÎĚĚĚăăăŰŰŰŘŘŘ×××ÜÜÜÜÜÜ×××ŰŰŰâââßßßâââßßßŕŕŕăăăŕŕŕŰŰŰŮŮŮÜÜÜâââăăăäääćććăăăŰŰŰŐŐŐÔÔÔăăăäääŰŰ۸¸¸¸¸¸±±±ŐŐŐŘŘŘÎÎεµµ´´´µµµ···ľľľĽĽĽÂÂÂżżżÂÂÂĹĹĹÉÉÉÍÍÍŃŃŃŇŇŇÔÔÔ×××ŘŘŘŮŮŮŰŰŰÜÜÜÜÜÜŰŰŰŰŰŰŕŕŕŐŐŐŃŃŃ×××ÔÔÔÉÉÉÂÂÂĹĹĹÉÉÉĘĘĘäääâââßßßćććŐŐŐÔÔÔÔÔÔŇŇŇŃŃŃÎÎÎÍÍÍĚĚĚÍÍÍÍÍÍĐĐĐĐĐĐĐĐĐÎÎÎÍÍÍĚĚĚĘĘĘĘĘĘÎÎÎĚĚĚÉÉÉÍÍÍÔÔÔŐŐŐĐĐĐĘĘĘŮŮŮŮŮŮŐŐŐÎÎÎÍÍÍŇŇŇŘŘŘŮŮŮŰŰŰĐĐĐŇŇŇŃŃŃŃŃŃŃŃŃŃŃŃÜÜÜćććëëëëëëóóóëëëóóóčččăăăçççćććçççíííňňňöööőőőóóóäääŘŘŘĚĚĚĂĂĂżżżĽĽĽľľľżżżľľľżżżżżżľľľĽĽĽĽĽĽŔŔŔĂĂĂĆĆĆĆĆĆÉÉÉÉÉÉĘĘĘÍÍÍĐĐĐŇŇŇĂĂĂĂĂĂľľľĘĘĘĆĆĆÎÎÎĆĆĆÇÇÇĐĐĐŇŇŇÎÎÎĚĚĚľľľ···ľľľµµµĘĘĘĆĆĆĂĂĂĹĹĹ»»»¸¸¸ŔŔŔżżż»»»ĽĽĽĽĽĽ»»»»»»»»»ĽĽĽżżżľľľĽĽĽĽĽĽĽĽĽľľľŔŔŔĂĂĂĹĹĹÉÉÉÇÇÇĆĆĆĹĹĹĂĂĂĂĂĂĹĹĹĆĆĆĹĹĹÇÇÇĆĆĆÎÎÎŮŮŮÉÉÉ···»»»»»»ŔŔŔµµµŞŞŞ­­­ĘĘĘŕŕŕÎÎÎŃŃŃĐĐĐŘŘŘâââäääăăăâââÝÝÝęęęčččçççęęęîîîçççÜÜÜÜÜÜÜÜÜăăăŐŐŐçççÜÜÜŇŇŇŐŐŐ×××ÔÔÔŰŰŰßßßŰŰŰŮŮŮŰŰŰŐŐŐĚĚĚĂĂĂĂĂĂÍÍÍÎÎÎŃŃŃÎÎÎäääŘŘŘŰŰŰÝÝÝŕŕŕÜÜÜŘŘŘÝÝÝâââŰŰŰăăăâââââââââßßßÝÝÝŕŕŕćććŰŰŰÝÝÝŕŕŕßßßŘŘŘÔÔÔŇŇŇĐĐĐäääâââŘŘصµµ´´´ŻŻŻĘĘĘĘĘĘ°°°¨¨¨°°°´´´···ŔŔŔżżż»»»ľľľŔŔŔĹĹĹÉÉÉÍÍÍĐĐĐĐĐĐŃŃŃŐŐŐŐŐŐ××××××××××××ŐŐŐŐŐŐ×××ŇŇŇŇŇŇŇŇŇÇÇÇĽĽĽĂĂĂÔÔÔŐŐŐŘŘŘćććŕŕŕăăăęęęÝÝÝäääăăăŮŮŮÎÎÎÉÉÉĚĚĚĐĐĐÎÎÎĚĚĚÉÉÉĚĚĚĐĐĐŇŇŇŇŇŇĐĐĐĚĚĚÉÉÉŃŃŃÎÎÎĚĚĚÎÎÎŇŇŇÔÔÔŃŃŃÍÍÍ×××ŘŘŘŐŐŐĐĐĐÎÎÎŐŐŐŮŮŮŮŮŮŮŮŮŇŇŇŃŃŃŃŃŃŇŇŇÔÔÔŮŮŮäääăăăîîîńńńńńńÝÝÝŕŕŕÔÔÔÉÉÉÂÂÂĂĂĂÇÇÇŇŇŇßßßčččëëëëëëĘĘĘĹĹĹŔŔŔżżżŔŔŔÂÂÂŔŔŔŔŔŔżżżżżżżżżľľľĽĽĽĽĽĽżżżÂÂÂĂĂĂĆĆĆĘĘĘĘĘĘĘĘĘĚĚĚÍÍÍĐĐи¸¸ĽĽĽşşşĆĆĆÇÇÇÔÔÔÍÍÍĘĘĘ××××××ÔÔÔ×××ÉÉÉ»»»»»»ŻŻŻĘĘĘĘĘĘĂĂĂĆĆĆşşşłłłŔŔŔľľľşşş»»»ĽĽĽ»»»şşşşşşĽĽĽżżżľľľľľľľľľľľľżżżÂÂÂĹĹĹĆĆĆÉÉÉÇÇÇĆĆĆĂĂĂĂĂĂĂĂĂĹĹĹĹĹĹÂÂÂĆĆĆĹĹĹĐĐĐŰŰŰĚĚĚşşşľľľ¨¨¨¸¸¸łłł©©©¬¬¬ÂÂÂ×××ĚĚĚŘŘŘŐŐŐÜÜÜÝÝÝÔÔÔŐŐŐßßßŕŕŕăăăÝÝÝÝÝÝçççíííćććâââćććÝÝÝęęęâââíííăăăăăăâââÝÝÝŃŃŃŘŘŘÜÜÜŮŮŮŘŘŘ×××ĐĐĐÇÇÇĆĆĆĘĘĘÔÔÔŃŃŃŇŇŇĐĐĐäääŘŘŘÝÝÝßßßŕŕŕßßßÜÜÜŰŰŰŮŮŮ×××ŐŐŐŮŮŮßßßâââßßßÜÜÜŰŰŰÜÜÜŕŕŕßßßßßß×××ÍÍÍĐĐĐŐŐŐŐŐŐÜÜÜŘŘŘÍÍͬ¬¬¨¨¨¤¤¤łłł°°°­­­ĄĄĄ¦¦¦©©©ŞŞŞµµµŔŔŔĂĂĂľľľżżżÂÂÂĆĆĆÉÉÉĚĚĚÎÎÎĐĐĐÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÍÍÍŐŐŐŇŇŇĂĂĂ»»»ĆĆĆŰŰŰçççÝÝÝŕŕŕćććßßßćććëëëŕŕŕëëëëëëßßßŃŃŃĘĘĘĘĘĘÍÍÍÎÎÎÍÍÍÉÉÉĚĚĚÍÍÍÎÎÎÎÎÎĚĚĚÉÉÉĆĆĆÉÉÉĘĘĘĘĘĘĘĘĘĘĘĘĘĘĘĚĚĚĚĚĚŃŃŃÔÔÔŇŇŇŃŃŃŇŇŇŮŮŮÜÜÜŰŰŰŘŘŘŇŇŇĚĚĚÍÍÍĐĐĐÔÔÔßßßćććŕŕŕîîîňňňęęęÉÉÉĚĚĚÇÇÇŔŔŔĚĚĚÇÇÇĹĹĹĆĆĆÉÉÉÉÉÉĹĹĹŔŔŔĹĹĹÇÇÇÉÉÉÇÇÇĂĂĂŔŔŔľľľĽĽĽŔŔŔŔŔŔŔŔŔľľľĽĽĽĽĽĽżżżÂÂÂĂĂĂĆĆĆĘĘĘĚĚĚĘĘĘĘĘĘĚĚĚÍÍÍĂĂĂĹĹŸ¸¸ľľľĂĂĂŰŰŰ×××ÎÎÎŐŐŐŃŃŃÍÍÍÔÔÔÎÎÎĹĹű±±ĂĂĂĚĚĚÇÇÇĆĆĆ»»»şşşĆĆĆ»»»şşş»»»ĽĽĽ»»»şşşşşşĽĽĽľľľżżżľľľľľľľľľŔŔŔÂÂÂĹĹĹĆĆĆÇÇÇĆĆĆĹĹĹÂÂÂÂÂÂÂÂÂĂĂĂĂĂĂŔŔŔĹĹĹĹĹĹÎÎÎŰŰŰÍÍÍĽĽĽÂ¢˘˘···µµµ­­­©©©±±±ĘĘĘŐŐŐŰŰŰŐŐŐŘŘŘ×××ĐĐĐ×××âââŕŕŕŘŘŘŃŃŃŐŐŐäääęęęćććçççďďďŰŰŰâââŮŮŮäääÝÝÝŕŕŕÝÝÝÜÜÜŇŇŇŃŃŃĚĚĚĹĹĹÂÂÂĂĂĂĆĆĆĹĹĹÎÎÎÔÔÔŮŮŮŇŇŇÔÔÔĐĐĐâââŘŘŘŮŮŮŐŐŐ×××ŕŕŕâââŮŮŮ×××ÜÜÜŕŕŕęęęőőőůůůóóóçççŰŰŰŃŃŃĐĐĐÎÎÎÔÔÔŐŐŐÍÍÍŃŃŃŰŰŰŰŰŰŕŕŕŰŰŰŃŃŃ´´´¬¬¬©©©­­­¨¨¨±±±¨¨¨¨¨¨°°°ŻŻŻ°°°ľľľĆĆĆżżżżżżżżżŔŔŔĂĂĂÉÉÉÍÍÍĐĐĐŃŃŃŃŃŃŃŃŃŇŇŇŇŇŇÔÔÔÔÔÔŐŐŐŃŃŃŐŐŐĘĘʸ¸¸ĽĽĽÔÔÔäääâââččččččçççâââçççćććŰŰŰäääćććăăăŰŰŰŃŃŃÉÉÉÇÇÇĚĚĚĐĐĐÔÔÔŃŃŃÎÎÎĚĚĚĘĘĘÉÉÉÉÉÉÉÉÉĘĘĘÍÍÍÎÎÎÎÎÎĚĚĚĘĘĘÍÍÍÎÎÎÍÍÍŃŃŃŇŇŇÔÔÔŘŘŘÜÜÜÝÝÝŮŮŮŘŘŘÔÔÔÉÉÉĘĘĘÎÎÎŃŃŃÜÜÜÝÝÝâââîîîďďďăăăľľľĹĹĹĚĚĚÍÍÍŃŃŃÎÎÎÍÍÍÎÎÎŃŃŃŃŃŃÎÎÎĚĚĚÉÉÉÎÎÎĐĐĐĘĘĘĂĂĂŔŔŔŔŔŔŔŔŔÂÂÂĂĂĂÂÂÂŔŔŔľľľľľľŔŔŔĂĂĂĂĂĂĆĆĆĘĘĘĚĚĚĚĚĚĘĘĘÉÉÉÉÉÉÎÎÎŇŇŇĆĆĆżżż±±±ľľľżżżĂĂĂÇÇÇ»»»ĂĂĂĆĆĆÇÇÇĚĚĚĽĽĽ»»»ÇÇÇĘĘĘĂĂĂĽĽĽĂĂĂÇÇǸ¸¸şşş»»»»»»»»»şşşşşş»»»ľľľżżżżżżżżżżżżŔŔŔĂĂĂĆĆĆÇÇÇĆĆĆĹĹĹĂĂĂŔŔŔŔŔŔŔŔŔÂÂÂÂÂÂżżżĹĹĹĂĂĂĚĚĚ×××ĚĚĚżżżÉÉÉ°°°Â»»»łłł¬¬¬©©©ÂÂÂŮŮŮŘŘŘŐŐŐŐŐŐŘŘŘŮŮŮÝÝÝŮŮŮĐĐĐŇŇŇÍÍÍŐŐŐâââăăăŕŕŕçççîîîíííăăăŰŰŰîîîęęęçççŕŕŕčččęęęçççâââÜÜÜŮŮŮŮŮŮŰŰŰŰŰŰ×××ŮŮŮŮŮŮŇŇŇŐŐŐÍÍÍÜÜÜŐŐŐŃŃŃĘĘĘĚĚĚŰŰŰäääÜÜÜŰŰŰčččäääęęęëëëęęęçççâââŮŮŮŃŃŃŇŇŇÎÎÎŰŰŰćććÝÝÝÜÜÜâââÝÝÝâââÝÝÝ×××»»»±±±±±±ŻŻŻŞŞŞ¨¨¨ĄĄĄ©©©¸¸¸´´´­­­µµµµµµżżżľľľĽĽĽľľľŔŔŔĹĹĹĘĘĘÎÎÎĐĐĐĐĐĐĐĐĐĐĐĐŃŃŃŇŇŇÔÔÔÔÔÔŇŇŇŇŇŇĘĘĘŔŔŔżżżÉÉÉŐŐŐŰŰŰčččçççććććććčččäääßßßăăăßßßŕŕŕÝÝÝŘŘŘĐĐĐĘĘĘĘĘĘÍÍÍĹĹĹĆĆĆÉÉÉĚĚĚÎÎÎŃŃŃŇŇŇŇŇŇŐŐŐÔÔÔÔÔÔÔÔÔÔÔÔŇŇŇĐĐĐÎÎÎĚĚĚĐĐĐÔÔÔ×××ŰŰŰßßßŰŰŰŐŐŐÔÔÔŇŇŇÉÉÉĐĐĐ×××ŮŮŮâââÜÜÜäääęęęíííćććŔŔŔÉÉÉŇŇŇÔÔÔŇŇŇŇŇŇŇŇŇŇŇŇÔÔÔŇŇŇŃŃŃĐĐĐĘĘĘÍÍÍÍÍÍÉÉÉĆĆĆÇÇÇÉÉÉĆĆĆĹĹĹĹĹĹĹĹĹÂÂÂŔŔŔŔŔŔÂÂÂĹĹĹĹĹĹĆĆĆÉÉÉĚĚĚÍÍÍĚĚĚÇÇÇĹĹĹĹĹĹĚĚĚĚĚĚÎÎθ¸¸±±±ŻŻŻĽĽĽ¸¸¸¸¸¸łłł···»»»ĹĹĹĐĐи¸¸żżżÉÉÉÂÂÂĽĽĽÇÇÇĹĹŸ¸¸şşş»»»»»»şşşşşşşşş»»»ľľľŔŔŔżżżżżżżżżŔŔŔĂĂĂĆĆĆÇÇÇĹĹĹĂĂĂŔŔŔżżżżżżżżżŔŔŔŔŔŔľľľĹĹĹĂĂĂÉÉÉŇŇŇÇÇÇŔŔŔĐĐĐşşşÉÉÉĽĽĽ´´´´´´¬¬¬łłłŔŔŔĚĚĚŇŇŇŇŇŇŃŃŃÔÔÔÔÔÔĐĐĐÍÍÍÎÎÎÍÍÍŘŘŘâââÜÜÜŰŰŰăăăčččëëëÜÜÜŇŇŇćććääääääŮŮŮâââßßßŕŕŕââââââŕŕŕŰŰŰ×××ŇŇŇŮŮŮŘŘŘŐŐŐŃŃŃŘŘŘĘĘĘŐŐŐŇŇŇĐĐĐĚĚĚÉÉÉŇŇŇŕŕŕßßßâââďďďëëëčččäääŕŕŕăăăęęęíííęęęíííŰŰŰßßßćććŮŮŮŇŇŇŮŮŮŮŮŮÔÔÔĐĐĐĘĘĘ°°°¦¦¦ŞŞŞ¨¨¨¨¨¨©©©¨¨¨¤¤¤ŞŞŞ¦¦¦¨¨¨¸¸¸µµµĽĽĽĽĽĽ»»»ĽĽĽżżżĂĂĂÇÇÇĘĘĘŃŃŃĐĐĐÎÎÎÎÎÎÎÎÎÎÎÎĐĐĐŃŃŃÍÍÍÎÎÎĐĐĐĘĘĘżżż»»»ÍÍÍăăăęęęääääääëëëëëëččččččćććÜÜÜŰŰŰŮŮŮŮŮŮŘŘŘÔÔÔĚĚĚĆĆĆĚĚĚŃŃŃŘŘŘßßßâââßßßŰŰŰŘŘŘŘŘŘÔÔÔĐĐĐŃŃŃÔÔÔŇŇŇĚĚĚĹĹĹĚĚĚŃŃŃŐŐŐŘŘŘÜÜÜßßßŮŮŮŃŃŃăăăăăăŐŐŐŰŰŰÝÝÝŮŮŮÜÜÜĐĐĐăăăćććëëëëëëĘĘĘÎÎÎŇŇŇĐĐĐŐŐŐŐŐŐŐŐŐÔÔÔŇŇŇŃŃŃĐĐĐÎÎÎĚĚĚÎÎÎÍÍÍÉÉÉÉÉÉĚĚĚÉÉÉÂÂÂĆĆĆĆĆĆĆĆĆĂĂĂÂÂÂŔŔŔĂĂĂĆĆĆĹĹĹĆĆĆÇÇÇĘĘĘÍÍÍĚĚĚÇÇÇĂĂĂĚĚĚĆĆĆĘĘĘăăăŮŮŮĆĆĆŻŻŻ±±±°°°···µµµ······ÂÂÂÎÎÎÂÂÂşşş¸¸¸ĆĆĆżżżĽĽĽÇÇÇŔŔŔ¸¸¸şşşşşş»»»şşş¸¸¸şşş»»»ľľľŔŔŔŔŔŔżżżŔŔŔÂÂÂĂĂĂĆĆĆÇÇÇĂĂĂÂÂÂŔŔŔżżżľľľľľľżżżżżżľľľĹĹĹÂÂÂÇÇÇĐĐĐĆĆĆÂÂÂÔÔÔ···ÇÇǸ¸¸´´´»»»ŻŻŻ˘˘˘źźź¤¤¤ÂÂÂÔÔÔŐŐŐŐŐŐÍÍÍĆĆĆĚĚĚĚĚĚÍÍÍŮŮŮŕŕŕŘŘŘŘŘŘâââäääëëëâââŘŘŘăăăăăăëëëÝÝÝÜÜÜŕŕŕŕŕŕŕŕŕâââŕŕŕÜÜÜŮŮŮŘŘŘŘŘŘÔÔÔŃŃŃŃŃŃŮŮŮÉÉÉŃŃŃĐĐĐÔÔÔŇŇŇĚĚĚÍÍÍŰŰŰŕŕŕäääďďďÝÝÝÝÝÝÜÜÜÜÜÜăăăëëëëëëäääŐŐŐ···°°°···ŻŻŻłłłÉÉÉÔÔÔŐŐŐĐĐĐĘĘʱ±±¨¨¨±±±ŻŻŻ´´´©©©ŻŻŻ©©©ŞŞŞ¨¨¨°°°Â···şşş»»»»»»ľľľŔŔŔĂĂĂĆĆĆÇÇÇŃŃŃĐĐĐÎÎÎĚĚĚĚĚĚĚĚĚĚĚĚÍÍÍĚĚĚĘĘĘĘĘĘÇÇÇŔŔŔÂÂÂŐŐŐíííóóóęęęęęęńńńëëëçççęęęăăăćććÜÜÜŕŕŕăăăŮŮŮ×××ŰŰŰŰŰŰŮŮŮ×××ŐŐŐ×××ŮŮŮÜÜÜÜÜÜŰŰŰâââÝÝÝÔÔÔÔÔÔŰŰŰÔÔÔÎÎÎŐŐŐŮŮŮŮŮŮÝÝÝÜÜÜŮŮŮßßßăăăÝÝÝĚĚĚÎÎÎŃŃŃŇŇŇŮŮŮßßßÝÝÝ×××ŕŕŕćććńńńçççÉÉÉŇŇŇĘĘĘÎÎÎĐĐĐŃŃŃÔÔÔÔÔÔÔÔÔŃŃŃÎÎÎĚĚĚÍÍÍÔÔÔÍÍÍÍÍÍĚĚĚÉÉÉĐĐĐĂĂĂŔŔŔĆĆĆÉÉÉĆĆĆĂĂĂĆĆĆÉÉÉĆĆĆĹĹĹĹĹĹĆĆĆĆĆĆĆĆĆĆĆĆĹĹĹĹĹĹĹĹĹĐĐĐĚĚĚÉÉÉĆĆĆĚĚĚÍÍÍŞŞŞ±±±¬¬¬±±±°°°´´´»»»şşşÂÂÂżżż°°°»»»ŔŔŔµµµÇÇÇ»»»»»»şşşşşşşşşşşşşşş»»»ĽĽĽľľľŔŔŔŔŔŔżżżŔŔŔŔŔŔĂĂĂĹĹĹĆĆĆĂĂĂÂÂÂŔŔŔľľľľľľľľľżżżżżżÂÂÂÂÂÂŔŔŔĂĂĂĹĹĹÜÜÜÎÎÎĆĆƸ¸¸ÍÍÍĂĂĂľľľ°°°ŻŻŻżżż¤¤¤ĄĄĄżżżŃŃŃŐŐŐŐŐŐÍÍÍÎÎÎÝÝÝÝÝÝâââÝÝÝŐŐŐ×××âââäääŕŕŕäääëëëŰŰŰŮŮŮßßßÝÝÝâââÝÝÝßßß×××ßßßćććÜÜÜ×××ŘŘŘ×××ŮŮŮÎÎÎŐŐŐŮŮŮÎÎÎĐĐĐŰŰŰŘŘŘŃŃŃĚĚĚĐĐĐćććŰŰŰßßßăăăíííÜÜܸ¸¸±±±ĽĽĽŔŔŔŃŃŃŇŇŇ´´´ĽĽĽżżżÂÂÂÂÂÂľľľµµµ¬¬¬¦¦¦ĐĐĐŔŔŔ°°°ŞŞŞ±±±···µµµ°°°°°°°°°°°°´´´¸¸¸şşşşşş···¸¸¸¸¸¸şşşĽĽĽżżżĂĂĂÇÇÇÉÉÉĚĚĚĚĚĚĘĘĘĘĘĘÉÉÉÇÇÇÉÉÉÉÉÉÇÇÇĘĘĘĘĘĘŔŔŔşşşĂĂĂÜÜÜňňňńńńíííęęęęęęíííëëëçççăăăâââÜÜÜăăăçççßßßŮŮŮŮŮŮ×××ŰŰŰŮŮŮŘŘŘŮŮŮÜÜÜÝÝÝÜÜÜŰŰŰßßßŰŰŰŇŇŇŇŇŇŘŘŘŐŐŐÔÔÔŰŰŰŮŮŮŮŮŮÝÝÝÜÜÜŘŘŘÝÝÝâââÜÜÜŐŐŐŘŘŘŘŘŘŐŐŐŘŘŘÜÜÜŰŰŰ×××ÝÝÝćććňňňăăăĚĚĚĐĐĐĘĘĘÇÇÇÎÎÎĐĐĐŇŇŇŇŇŇŃŃŃÎÎÎĚĚĚÉÉÉÉÉÉÎÎÎÇÇÇÉÉÉĘĘĘÇÇÇÍÍÍĂĂĂÂÂÂżżżżżżŔŔŔĹĹĹÉÉÉĘĘĘÉÉÉĆĆĆÇÇÇÉÉÉĘĘĘĘĘĘÉÉÉÇÇÇĆĆĆĆĆĆĚĚĚĚĚĚÎÎÎĘĘĘÎÎÎÜÜÜÔÔÔŔŔŔ°°°°°°°°°±±±´´´şşşĐĐĐ»»»°°°ľľľÂµµµÍÍÍżżż»»»şşşşşşşşşşşş»»»»»»ĽĽĽľľľŔŔŔŔŔŔŔŔŔÂÂÂĂĂĂĂĂĂĹĹĹĹĹĹÂÂÂŔŔŔżżżĽĽĽĽĽĽĽĽĽľľľľľľżżżÂÂÂÂÂÂĹĹĹĆĆĆŮŮŮÇÇÇŔŔŔľľľľľľ»»»żżż¸¸¸´´´şşşŻŻŻŞŞŞµµµÂÂÂÎÎÎ××××××ŃŃŃŃŃŃŕŕŕßßß×××ÍÍÍĐĐĐÜÜÜçççęęęčččîîîßßßŰŰŰŕŕŕßßßăăăßßßńńńäääÝÝÝÝÝÝÜÜÜÝÝÝŕŕŕßßßÜÜÜŘŘŘćććëëëŮŮŮŃŃŃ×××ŇŇŇÔÔÔ×××ÜÜÜÜÜÜŰŰŰóóóęęęäääľľľ´´´ĽĽĽżżż±±±···ŔŔŔ¸¸¸ŔŔŔÂÂÂĂĂĂÂÂÂľľľ¸¸¸łłłŻŻŻ°°°­­­¬¬¬ŻŻŻ´´´¸¸¸¸¸¸···¸¸¸······şşşĽĽĽľľľĽĽĽşşşşşşşşşşşşĽĽĽľľľÂÂÂĹĹĹĆĆĆĘĘĘÉÉÉÉÉÉÇÇÇĆĆĆĹĹĹĹĹĹĆĆĆĂĂĂĆĆĆĂĂĂĽĽĽĹĹĹŘŘŘčččîîîíííëëëčččęęęëëëëëëçççäääâââßßßäääçççŕŕŕŰŰŰŰŰŰŘŘŘÜÜÜÜÜÜŰŰŰÜÜÜÝÝÝÝÝÝÜÜÜŰŰŰŰŰŰŘŘŘŇŇŇŃŃŃ××××××ŮŮŮŕŕŕŰŰŰŮŮŮÝÝÝÝÝÝŮŮŮÝÝÝßßßŘŘŘĘĘĘĐĐĐŃŃŃĐĐĐŇŇŇŘŘŘÜÜÜÜÜÜŕŕŕčččňňňŘŘŘÇÇÇÉÉÉĚĚĚĆĆĆÍÍÍÎÎÎŃŃŃŃŃŃĐĐĐÍÍÍÉÉÉĆĆĆĆĆĆĘĘĘĂĂĂĹĹĹĆĆĆĂĂĂĹĹĹżżżĘĘĘĂĂĂ»»»ĽĽĽĹĹĹĘĘĘÉÉÉÉÉÉÇÇÇÉÉÉĚĚĚÍÍÍÍÍÍĚĚĚÉÉÉÇÇÇÉÉÉĆĆĆĹĹĹÍÍÍÉÉÉĹĹĹÔÔÔŰŰŰŇŇŇ´´´­­­±±±µµµ´´´¸¸¸ĐĐĐ»»»łłłżżżÂ···ÎÎλ»»»»»»»»şşş»»»»»»ĽĽĽľľľżżżŔŔŔŔŔŔĂĂĂĹĹĹĆĆĆĹĹĹĹĹĹĂĂĂŔŔŔżżżľľľ»»»»»»»»»ĽĽĽĽĽĽľľľŔŔŔŔŔŔĆĆĆĆĆĆŐŐŐŔŔŔ»»»ĐĐĐ»»»şşşŔŔŔŔŔŔ»»»łłł´´´¬¬¬ĄĄĄ¨¨¨łłłÂÂÂŇŇŇÝÝÝÜÜÜŮŮŮŰŰŰŮŮŮŘŘŘÜÜÜäääęęęíííćććęęęŮŮŮÔÔÔŰŰŰŰŰŰÜÜÜŮŮŮíííäää×××ÔÔÔŕŕŕëëëííííííŕŕŕÜÜÜäääăăăĐĐĐÉÉÉŇŇŇ×××ŃŃŃŐŐŐŕŕŕŮŮŮŮŮŮäääżżżµµµÂÂÂÂÂÂĘĘĘĚĚĚÂÂÂÂÂÂĆĆĆĹĹĹÇÇÇĆĆĆĹĹĹĂĂĂżżżĽĽĽ¸¸¸···ĄĄĄŞŞŞ±±±´´´łłłłłłµµµşşşĽĽĽĽĽĽĽĽĽĽĽĽľľľľľľ»»»şşşşşşşşş»»»»»»ĽĽĽżżżŔŔŔÂÂÂÇÇÇĆĆĆĆĆĆĹĹĹĹĹĹĂĂĂĂĂĂÂÂÂÂÂÂżżżĽĽĽĹĹĹ×××ęęęďďďíííćććçççčččęęęëëëęęęçççćććäääâââŕŕŕßßßŮŮŮŘŘŘŰŰŰÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜŰŰŰŮŮŮŘŘŘ×××ÔÔÔŇŇŇÔÔÔ×××ŰŰŰŕŕŕŮŮŮŮŮŮßßßŕŕŕÜÜÜßßßÝÝÝŇŇŇÎÎÎÔÔÔ×××ÔÔÔŃŃŃŇŇŇ××××××čččîîîíííĘĘĘÂÂÂĂĂĂĐĐĐĚĚĚÍÍÍÎÎÎŃŃŃŇŇŇŃŃŃÍÍÍÉÉÉĹĹĹÇÇÇÇÇÇŔŔŔŔŔŔĂĂĂľľľ»»»ĽĽĽŘŘŘŐŐŐĆĆĆ»»»ŔŔŔÇÇÇĆĆĆÂÂÂÇÇÇÉÉÉĚĚĚÍÍÍÍÍÍĚĚĚÉÉÉÇÇÇĘĘĘÂÂÂŔŔŔĘĘĘĘĘĘÂÂÂĂĂĂĆĆĆ××׸¸¸°°°´´´»»»¸¸¸łłłżżżÇÇÇ···żżżŔŔŔ´´´ĘĘĘżżżżżż»»»»»»»»»»»»ĽĽĽĽĽĽľľľżżżŔŔŔÂÂÂĹĹĹÇÇÇÇÇÇĆĆĆĹĹĹĂĂĂÂÂÂŔŔŔľľľĽĽĽ»»»ĽĽĽĽĽĽľľľĽĽĽŔŔŔŔŔŔĹĹĹĆĆĆÔÔÔżżżľľľŐŐŐĂĂĂĽĽĽĽĽĽÂÂÂĂĂĂľľľ»»»żżż±±±¬¬¬©©©¦¦¦´´´ÇÇÇĘĘĘŰŰŰŰŰŰŮŮŮ×××ŘŘŘÝÝÝćććęęęăăăäääŮŮŮŃŃŃŘŘŘŰŰŰŰŰŰŮŮŮćććčččÜÜÜ×××äääëëëäääâââëëëăăăăăăßßßŇŇŇŇŇŇŕŕŕčččÜÜÜŘŘŘŕŕŕââââââŐŐŐşşşÇÇÇÉÉÉÇÇÇÇÇÇÉÉÉÍÍÍÍÍÍÇÇÇĹĹĹĚĚĚĘĘĘÇÇÇĹĹĹÂÂÂľľľ»»»şşşłłł···şşş···±±±°°°···ľľľşşşşşşşşş»»»»»»şşş¸¸¸¸¸¸»»»»»»»»»ĽĽĽĽĽĽľľľľľľľľľĂĂĂĂĂĂĂĂĂĂĂĂĹĹĹĹĹĹĂĂĂÂÂÂŔŔŔĽĽĽĹĹĹŮŮŮčččëëëëëëîîîâââäääçççęęęęęęčččçççćććŕŕŕâââßßßŮŮŮ××××××ŘŘŘŰŰŰŮŮŮŮŮŮŮŮŮŮŮŮŮŮŮŘŘŘŘŘŘŘŘŘŘŘŘŘŘŘŘŘŘÔÔÔŃŃŃÔÔÔŮŮŮÜÜÜŘŘŘŮŮŮŕŕŕăăăŕŕŕŕŕŕÜÜÜÎÎÎŇŇŇŰŰŰŕŕŕÝÝÝŮŮŮŰŰŰÜÜÜÜÜÜëëëîîîăăăĂĂĂÂÂÂĂĂĂŃŃŃÍÍÍÍÍÍĐĐĐŇŇŇÔÔÔŇŇŇĐĐĐĘĘĘÇÇÇĹĹĹÂÂÂľľľĽĽĽŔŔŔ»»»···ĂĂĂÝÝÝäääŇŇŇ»»»ĽĽĽĆĆĆĹĹĹŔŔŔĆĆĆÇÇÇÉÉÉĘĘĘĘĘĘÉÉÉÇÇÇĆĆĆÇÇÇĆĆĆĘĘĘÍÍÍÎÎÎĚĚĚĆĆĆĆĆĆÍÍÍżżżĽĽĽµµµ´´´···±±±···ÔÔÔ»»»ľľľżżż°°°Â»»»Â»»»»»»»»»»»»ĽĽĽĽĽĽľľľżżżŔŔŔĂĂĂĆĆĆÉÉÉÉÉÉĆĆĆĂĂĂÂÂÂĂĂĂÂÂÂżżżľľľľľľľľľľľľżżżĽĽĽÂÂÂżżżĂĂĂÇÇÇÔÔÔÂÂÂĆĆĆĹĹĹÉÉÉ»»»łłłşşşÉÉÉÎÎÎĂĂĂĆĆĆľľľľľľ¸¸¸ŞŞŞ©©©ŻŻŻ¬¬¬ŘŘŘÝÝÝßßßÝÝÝÜÜÜŕŕŕăăăăăăćććçççŕŕŕ×××ÜÜÜŕŕŕßßßâââÝÝÝčččäääÝÝÝäääćććßßßßßßäääßßßŕŕŕăăăßßßÝÝÝâââăăăÜÜÜâââćććäääÝÝÝĹĹĹľľľĐĐĐĹĹĹÉÉÉÉÉÉÇÇÇÉÉÉĆĆĆĹĹĹÉÉÉĚĚĚĚĚĚĘĘĘÇÇÇĹĹĹżżż»»»¸¸¸şşş»»»şşş···µµµ···ĽĽĽŔŔŔ···¸¸¸şşş»»»»»»»»»»»»»»»ľľľľľľľľľľľľĽĽĽĽĽĽĽĽĽĽĽĽÂÂÂŔŔŔŔŔŔĂĂĂÇÇÇÇÇÇĆĆĆĹĹĹĽĽĽÇÇÇÜÜÜííííííćććäääëëëâââäääçççęęęęęęčččçççćććŰŰŰŕŕŕßßßŰŰŰŮŮŮŘŘŘÔÔÔŐŐŐ×××ŘŘŘŘŘŘ×××ŐŐŐŐŐŐŘŘŘŮŮŮŮŮŮŮŮŮŮŮŮÔÔÔĚĚĚĐĐĐŘŘŘŮŮŮŮŮŮŮŮŮŕŕŕăăăŕŕŕâââÝÝÝĐĐĐÍÍÍ×××ÝÝÝÝÝÝÝÝÝŕŕŕăăăăăăćććççç×××ĹĹĹĆĆĆĆĆĆÍÍÍÉÉÉÍÍÍĐĐĐÔÔÔŐŐŐŐŐŐŃŃŃÍÍÍÉÉÉŔŔŔľľľĽĽĽ»»»ŔŔŔ»»»şşşŃŃŃŮŮŮăăăĐĐĐ···»»»ĹĹĹĹĹĹĹĹĹĆĆĆĆĆĆÇÇÇÇÇÇÇÇÇÇÇÇĆĆĆĆĆĆĆĆĆÍÍÍÔÔÔÎÎÎĚĚĚĚĚĚĆĆĆĚĚĚĂĂĂÇÇÇĚĚ̸¸¸­­­´´´···żżżÔÔÔĽĽĽĽĽĽĽĽĽ­­­ŔŔŔ»»»ŔŔŔ»»»»»»şşş»»»»»»ĽĽĽľľľżżżŔŔŔĂĂĂĆĆĆÇÇÇÇÇÇĆĆĆĂĂĂŔŔŔĂĂĂÂÂÂŔŔŔżżżľľľľľľżżżżżżĽĽĽÂÂÂĽĽĽŔŔŔÇÇÇÔÔÔĂĂĂÎÎλ»»ĚĚĚ°°°±±±ŔŔŔÉÉÉÂÂÂŔŔŔ»»»ĽĽĽľľľ»»»şşşµµµ­­­şşşÇÇÇŇŇŇŐŐŐŮŮŮâââäääâââŕŕŕäääăăăŘŘŘŮŮŮÝÝÝŮŮŮŕŕŕŰŰŰâââăăăŕŕŕâââăăăăăăçççŕŕŕŮŮŮŮŮŮßßßŕŕŕÝÝÝÝÝÝÝÝÝëëë˙˙˙˙˙˙ććć×××ÉÉÉÉÉÉĂĂĂÉÉÉÍÍÍÍÍÍĚĚĚĘĘĘÉÉÉĘĘĘÎÎÎĚĚĚĚĚĚĚĚĚĘĘĘÇÇÇÂÂÂľľľ»»»ĽĽĽ»»»şşş»»»»»»»»»şşş¸¸¸¸¸¸»»»ľľľżżżżżżżżżżżżŔŔŔżżżżżżżżżżżżżżżľľľĽĽĽĽĽĽŔŔŔżżżŔŔŔĂĂĂÇÇÇÉÉÉÇÇÇĂĂĂ···×××ńńńńńńčččçççčččçççćććçççčččęęęëëëęęęçççćććŮŮŮăăăŕŕŕŮŮŮŰŰŰŮŮŮŐŐŐ××××××××××××ŐŐŐÔÔÔŐŐŐŮŮŮÝÝÝŰŰŰŮŮŮŮŮŮĐĐĐĹĹĹĚĚĚŮŮŮŰŰŰÝÝÝŰŰŰßßßŕŕŕßßßăăăŕŕŕÔÔÔŇŇŇŮŮŮÝÝÝŰŰŰŘŘŘŰŰŰÜÜÜŰŰŰâââŕŕŕĆĆĆÂÂÂĹĹĹĆĆĆÇÇÇĆĆĆĘĘĘÍÍÍŇŇŇŐŐŐŐŐŐŇŇŇÍÍÍĘĘĘĹĹĹŔŔŔŔŔŔ»»»żżżşşş···ŘŘŘ×××ŐŐŐżżż±±±ĽĽĽŔŔŔżżżÇÇÇÇÇÇĆĆĆĆĆĆĹĹĹĹĹĹĆĆĆĆĆĆÇÇÇĘĘĘÍÍÍŐŐŐÎÎÎĐĐĐÍÍÍżżżÇÇÇÂÂÂÉÉÉÎÎÎľľľµµµżżżŔŔŔĆĆĆĹĹŸ¸¸żżżşşş¬¬¬ÉÉÉŔŔŔ»»»şşşşşşşşşşşş»»»»»»ĽĽĽľľľÂÂÂĂĂĂĆĆĆĆĆĆĆĆĆĹĹĹĂĂĂŔŔŔÂÂÂŔŔŔżżżľľľĽĽĽĽĽĽľľľżżż»»»Â»»»ŔŔŔÇÇÇŇŇŇÂÂÂĐĐĐľľľĚĚĚÎÎλ»»łłłµµµ···ĆĆĆÉÉÉĂĂĂşşşµµµ»»»»»»µµµ´´´¨¨¨µµµşşş±±±¸¸¸ĐĐĐŕŕŕŕŕŕÜÜÜŕŕŕäääŐŐŐŇŇŇŐŐŐÎÎÎŮŮŮăăăßßßŕŕŕŕŕŕŰŰŰŘŘŘÜÜÜÝÝÝćććŕŕŕÜÜÜÜÜÜÝÝÝßßßäääíííćććÝÝÝŰŰŰżżżľľľĹĹĹÍÍÍĆĆĆĚĚĚÉÉÉÉÉÉĚĚĚĘĘĘĚĚĚĚĚĚÇÇÇĘĘĘĚĚĚĚĚĚĚĚĚĘĘĘÇÇÇĂĂĂÂÂÂÂÂÂŔŔŔżżżľľľĽĽĽ»»»¸¸¸···»»»ľľľŔŔŔŔŔŔŔŔŔŔŔŔÂÂÂĂĂĂŔŔŔŔŔŔÂÂÂÂÂÂŔŔŔżżżľľľĽĽĽÂÂÂŔŔŔŔŔŔĂĂĂÇÇÇÇÇÇĂĂĂżżżşşşŰŰŰňňňîîîčččîîîńńńęęęíííëëëčččęęęëëëëëëçççäääßßßçççŕŕŕŐŐŐ×××ŘŘŘŘŘŘÜÜÜŘŘŘŘŘŘ×××ÔÔÔÔÔÔŐŐŐŰŰŰŕŕŕÜÜÜŮŮŮŘŘŘÍÍÍżżżÉÉÉŰŰŰÝÝÝâââÜÜÜÝÝÝÜÜÜÜÜÜăăăăăăŘŘŘÔÔÔŮŮŮÜÜÜŰŰŰÜÜÜâââććććććâââÜÜܸ¸¸ĽĽĽżżżĂĂĂĹĹĹÉÉÉÇÇÇĚĚĚŃŃŃŐŐŐŐŐŐŇŇŇÍÍÍĘĘĘÍÍÍÇÇÇĆĆĆľľľľľľµµµłłłŘŘŘ×××ÉÉÉ°°°­­­ľľľĽĽĽ¸¸¸ĹĹĹÉÉÉÇÇÇĹĹĹĹĹĹĹĹĹĹĹĹÇÇÇÉÉÉĚĚĚÉÉÉĐĐĐÔÔÔßßßŰŰŰĂĂĂÇÇÇĆĆĆĹĹĹÉÉÉĂĂĂĆĆĆĐĐĐÉÉÉĆĆĆłłłµµµÂ¸¸¸­­­ŇŇŇĆĆƵµµşşşşşşşşşşşşşşş»»»ĽĽĽľľľÂÂÂĂĂĂĹĹĹĆĆĆĆĆĆĹĹĹÂÂÂŔŔŔŔŔŔżżżľľľĽĽĽ»»»»»»ĽĽĽľľľşşşÂ»»»ŔŔŔÇÇÇŃŃŃľľľÍÍÍŔŔŔĂĂĂ×××ÉÉÉĽĽĽµµµ°°°ŐŐŐĆĆĆĹĹŸ¸¸±±±¸¸¸µµµ±±±···´´´ĹĹĹĹĹŵµµ¸¸¸ÎÎÎÜÜÜŘŘŘßßßäääëëëŰŰŰÔÔÔŐŐŐÍÍÍŘŘŘŮŮŮÎÎÎÔÔÔÜÜÜŘŘŘ×××ÜÜÜŰŰŰŰŰŰŮŮŮŘŘŘ××××××ŘŘŘăăăńńńâââşşşŔŔŔĽĽĽĘĘĘĐĐĐÎÎÎŇŇŇÍÍÍĘĘĘĐĐĐŇŇŇĚĚĚÍÍÍĐĐĐĚĚĚĘĘĘĚĚĚĚĚĚĚĚĚĚĚĚĘĘĘÉÉÉÉÉÉĂĂĂĂĂĂÂÂÂżżżĽĽĽĽĽĽżżżÂ»»»ľľľŔŔŔŔŔŔżżżľľľżżżÂÂÂŔŔŔÂÂÂĂĂĂĂĂĂÂÂÂŔŔŔżżżľľľĂĂĂŔŔŔŔŔŔÂÂÂĆĆĆĹĹĹżżż»»»ŔŔŔ×××čččëëëíííňňňőőőńńńńńńíííęęęęęęíííëëëçççăăăßßßŕŕŕŕŕŕÝÝÝŘŘŘ×××ŮŮŮÝÝÝÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝŮŮŮÎÎÎŘŘŘŐŐŐÉÉÉ×××ßßßßßßÜÜÜÝÝÝăăăćććâââÜÜÜÜÜÜŰŰŰÜÜÜŮŮŮŐŐŐŮŮŮăăăäääßßßŐŐŐľľľ···şşşĂĂĂŔŔŔµµµÇÇÇĂĂĂĘĘĘŇŇŇŐŐŐŇŇŇÎÎÎÎÎÎĐĐĐÉÉÉÇÇÇĆĆĆÂÂÂĽĽĽµµµ°°°¬¬¬ŞŞŞ¬¬¬­­­±±±µµµ»»»żżżĂĂĂĂĂĂĂĂĂÂÂÂÂÂÂŔŔŔÂÂÂĹĹĹĆĆĆÇÇÇÔÔÔĘĘĘĐĐĐÝÝÝŰŰŰŘŘŘÎÎÎÉÉÉÍÍÍŇŇұ±±ĆĆĆĽĽĽşşşşşşŔŔŔŔŔŔ±±±¸¸¸ĆĆĆÂÂÂĽĽĽ´´´łłł´´´···¸¸¸şşş»»»ľľľŔŔŔÂÂÂĂĂĂĹĹĹĆĆĆĹĹĹÂÂÂżżżľľľĽĽĽ»»»şşşşşş»»»»»»şşş¸¸¸şşş»»»¸¸¸żżżÂÂÂÎÎÎŔŔŔĘĘĘĹĹĹÂÂÂŐŐŐĚĚĚ···żżżżżż»»»ĹĹĹĆĆĆ»»»ľľľ±±±¸¸¸µµµľľľşşşľľľÂÂÂżżż¸¸¸´´´´´´µµµ±±±âââęęęëëëÎÎÎŮŮŮÎÎÎŮŮŮŰŰŰÔÔÔŮŮŮćććçççßßßŮŮŮŰŰŰŇŇŇŰŰŰŮŮŮăăăäääŕŕŕćććÝÝÝ···¸¸¸ľľľĂĂĂÉÉÉÎÎÎŃŃŃÔÔÔÎÎÎÎÎÎÎÎÎÍÍÍÍÍÍĚĚĚĚĚĚĚĚĚĘĘĘĘĘĘÉÉÉÉÉÉÇÇÇĆĆĆĆĆĆĹĹĹĹĹĹĂĂĂĂĂĂÂÂÂŔŔŔżżżľľľľľľĽĽĽľľľżżżÂÂÂÂÂÂÂÂÂŔŔŔżżżĂĂĂĂĂĂÂÂÂÂÂÂÂÂÂĂĂĂĂĂĂĂĂĂľľľÂÂÂĹĹĹÇÇÇĂĂø¸¸żżż×××äääćććëëëńńńíííâââÝÝÝŕŕŕŕŕŕëëëëëëęęęîîîęęęăăăčččßßßŕŕŕâââßßßŮŮŮŮŮŮÜÜÜŕŕŕŕŕŕßßßÜÜÜŮŮŮŮŮŮÜÜÜßßßâââÝÝÝÜÜÜŇŇŇŮŮŮ×××ĐĐĐŰŰŰßßßßßßÝÝÝŕŕŕăăăăăăÝÝÝŮŮŮŰŰŰßßßßßßÜÜÜŮŮŮŮŮŮßßßăăăăăă»»»µµµşşşşşşľľľĽĽĽĽĽĽŐŐŐľľľĹĹĹÎÎÎÔÔÔŇŇŇĐĐĐÎÎÎÎÎÎĘĘĘÉÉÉĆĆĆ»»»´´´ŻŻŻ¬¬¬ŞŞŞŞŞŞ¬¬¬°°°µµµ»»»żżżÂÂÂÂÂÂŔŔŔżżżżżżżżżÂÂÂĹĹĹĆĆĆĘĘĘÔÔÔÎÎÎ×××âââăăăćććÜÜÜĚĚĚĂĂĂÇÇǵµµĐĐĐÂÂÂľľľĂĂø¸¸ŔŔŔ¸¸¸ĽĽĽÂ¸¸¸µµµłłłłłł´´´···¸¸¸¸¸¸şşşĽĽĽżżżÂÂÂĂĂĂĹĹĹĹĹĹĂĂĂŔŔŔľľľĽĽĽşşş···µµµµµµ···¸¸¸···µµµ»»»»»»¸¸¸ľľľżżżĘĘʸ¸¸żżżÍÍÍżżżÎÎÎĐĐĐĆĆĆĘĘĘĆĆĆŔŔŔ¸¸¸ĂĂĂżżżĽĽĽ±±±ĽĽĽ···łłł»»»ľľľŔŔŔżżż»»»·········¸¸¸ŐŐŐŮŮŮëëëŕŕŕčččÔÔÔÔÔÔ×××ŇŇŇŘŘŘçççîîîćććŮŮŮÔÔÔßßßćććăăăŕŕŕâââćććäää×××µµµ¸¸¸ĽĽĽÂÂÂĆĆĆĚĚĚÎÎÎŃŃŃÎÎÎÍÍÍÍÍÍÍÍÍĚĚĚĚĚĚĚĚĚĘĘĘĘĘĘĘĘĘÉÉÉÉÉÉÇÇÇĆĆĆĹĹĹĹĹĹĂĂĂĂĂĂĂĂĂÂÂÂÂÂÂŔŔŔŔŔŔżżżżżżżżżŔŔŔÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂĂĂĂĂĂĂĂĂĂĂĂĂĂĂĂĹĹĹĹĹĹĹĹĹżżżĽĽĽÂÂÂŔŔŔ¸¸¸ÂÂÂÜÜÜîîîîîîíííëëëčččăăăÝÝÝÜÜÜßßßÝÝÝăăăćććčččëëëęęęçççęęęŕŕŕâââăăăŕŕŕÝÝÝÝÝÝâââäääâââŕŕŕßßßÝÝÝÝÝÝßßßâââăăăÜÜÜßßßŮŮŮÜÜÜŰŰŰŮŮŮŕŕŕŕŕŕŘŘŘŰŰŰâââćććăăăŰŰŰŘŘŘŮŮŮâââŘŘŘÔÔÔŰŰŰăăăäääÝÝÝŮŮٱ±±···żżż»»»¸¸¸µµµşşşŃŃŃşşşżżżÉÉÉĐĐĐŇŇŇŃŃŃÎÎÎĚĚĚĚĚĚÉÉÉĆĆĆżżżşşşłłł­­­ŞŞŞŞŞŞ©©©ŞŞŞŻŻŻ···ĽĽĽżżżżżżľľľĽĽĽ»»»»»»ĽĽĽŔŔŔĹĹĹÇÇÇĘĘĘÎÎÎÎÎÎÔÔÔ×××ŰŰŰŕŕŕŐŐŐÇÇÇ···»»»şşşŘŘŘĹĹĹľľľĘĘĘ°°°ŔŔŔŔŔŔŔŔŔĽĽĽŻŻŻ°°°°°°±±±´´´···¸¸¸¸¸¸şşş»»»ľľľÂÂÂĂĂĂĹĹĹĹĹĹÂÂÂżżżĽĽĽşşş¸¸¸µµµ´´´´´´µµµ······µµµşşş»»»¸¸¸żżżÂÂÂĚĚĚ···»»»ÉÉÉ»»»ĘĘĘÜÜÜÝÝÝŰŰŰÍÍÍŔŔŔµµµĹĹĹÇÇÇĆĆĆşşşľľľ¸¸¸´´´ĽĽĽľľľľľľľľľľľľĽĽĽ»»»»»»¸¸¸ŔŔŔ»»»ÔÔÔŰŰŰîîîäääčččââââââăăăćććčččçççćććčččâââââââââÜÜÜßßßŕŕŕÎÎÎżżżµµµ···»»»żżżĂĂĂÇÇÇĚĚĚÍÍÍÍÍÍÍÍÍĚĚĚĚĚĚĚĚĚĚĚĚĘĘĘĘĘĘĘĘĘĘĘĘÉÉÉÉÉÉÇÇÇĆĆĆĆĆĆĹĹĹĂĂĂĂĂĂĂĂĂĂĂĂĂĂĂĂĂĂĂĂĂĂĂĂĂĂĂÂÂÂÂÂÂÂÂÂĂĂĂĂĂĂĹĹĹĹĹĹĂĂĂĂĂĂĹĹĹĹĹĹĆĆĆĆĆĆĆĆĆĆĆĆÇÇÇÂÂÂżżżĽĽĽľľľÔÔÔíííóóóîîîîîîęęęăăăÝÝÝÜÜÜÜÜÜŰŰŰÜÜÜŰŰŰâââčččęęęęęęęęęçççâââăăăäääăăăââââââćććčččŕŕŕâââăăăäääăăăâââßßßÜÜÜŰŰŰâââŕŕŕßßßßßßăăăćććâââĘĘĘĐĐĐÜÜÜäääăăăÝÝÝÝÝÝââââââŐŐŐŇŇŇŰŰŰÜÜÜĚĚĚşşş°°°¸¸¸ľľľľľľşşş»»»şşş¸¸¸ŔŔŔĽĽĽżżżĹĹĹĚĚĚĐĐĐŃŃŃÍÍÍĘĘĘĘĘĘÇÇÇĂĂĂĽĽĽµµµ°°°¬¬¬©©©©©©¨¨¨¨¨¨­­­µµµ»»»ĽĽĽ»»»»»»¸¸¸···¸¸¸»»»ŔŔŔĹĹĹĆĆĆÇÇÇĆĆĆĘĘĘÎÎÎĚĚĚŃŃŃ×××ÍÍÍĽĽĽ°°°¸¸¸ľľľ×××···ÇÇÇ°°°ĹĹĹĹĹĹŔŔŔşşş¬¬¬­­­°°°±±±´´´·········¸¸¸»»»ĽĽĽÂÂÂĂĂĂĹĹĹĂĂĂÂÂÂľľľşşş¸¸¸şşş···´´´´´´···¸¸¸¸¸¸¸¸¸···¸¸¸¸¸¸ĂĂĂĘĘĘÔÔÔľľľżżżĆĆĆĽĽĽÇÇÇŘŘŘÝÝÝÝÝÝÔÔÔÇÇDZ±±µµµľľľĆĆĆĂĂĂżżżŔŔŔĆĆĆżżżľľľĽĽĽľľľŔŔŔÂÂÂŔŔŔżżżÇÇÇĆĆĆşşşÂÂÂŔŔŔŇŇŇŇŇŇŰŰŰćććçççßßßŮŮŮÜÜÜßßßŕŕŕäääâââŘŘŘÜÜÜŕŕŕäää×××µµµŻŻŻ···¸¸¸»»»ľľľÂÂÂĆĆĆÉÉÉĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĘĘĘĘĘĘĘĘĘĚĚĚĘĘĘĘĘĘÉÉÉÇÇÇÇÇÇĆĆĆĆĆĆĹĹĹĹĹĹĹĹĹĆĆĆĆĆĆĆĆĆĆĆĆÇÇÇĆĆĆĹĹĹÂÂÂÂÂÂÂÂÂĂĂĂĹĹĹĆĆĆĂĂĂĹĹĹĆĆĆÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇĂĂĂżżżşşşĂĂĂÝÝÝíííîîîîîîćććččččččŕŕŕÝÝÝßßßÜÜÜ×××ŰŰŰŐŐŐßßßęęęčččççççççßßßćććććććććäääăăăäääçççčččăăăäääćććäääăăăŕŕŕÜÜÜŮŮŮÜÜÜâââäääâââăăăëëëęęęćććăăăââââââßßßŘŘŘÎÎÎÎÎÎŇŇŇŇŇŇŃŃŃŘŘŘßßßÔÔÔľľľµµµ»»»şşşżżż»»»şşşÂÂÂÂÂÂŔŔŔżżżĹĹĹĂĂĂĹĹĹÉÉÉÍÍÍĐĐĐÍÍÍĘĘĘÇÇÇĹĹĹżżżşşşłłłŻŻŻ¬¬¬ŞŞŞŞŞŞ©©©©©©ŻŻŻµµµşşşşşş···¸¸¸···´´´···ĽĽĽŔŔŔĹĹĹĆĆĆĹĹĹĂĂĂĚĚĚĐĐĐÍÍÍ×××ŮŮŮĐĐĐłłłµµµĹĹĹĆĆĆÔÔÔżżżłłłÂ···ÉÉÉĂĂĂľľľ¸¸¸°°°±±±°°°łłł´´´·········¸¸¸şşşĽĽĽÂÂÂĂĂĂĂĂĂĂĂĂŔŔŔľľľşşş······´´´łłł±±±´´´·········´´´···¸¸¸ĆĆĆÍÍÍ××׿żżŔŔŔÉÉÉĆĆĆĂĂĂĂĂĂĹĹĹŃŃŃÜÜÜŘŘŘĂĂõµµ°°°···ĂĂĂĂĂĂÂÂÂÂÂÂÂÂÂżżżĽĽĽľľľÂÂÂĆĆĆĆĆĆĹĹĹÉÉÉÎÎÎÇÇÇĹĹĹşşşĂĂĂżżż»»»ÎÎÎŕŕŕćććăăăâââÜÜÜŮŮŮâââçççÝÝÝâââçççęęęŐŐŐłłłłłł¸¸¸şşş»»»ľľľÂÂÂĆĆĆÉÉÉĚĚĚĘĘĘĘĘĘĘĘĘĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚÍÍÍĚĚĚĚĚĚĘĘĘÉÉÉÇÇÇÇÇÇĆĆĆĆĆĆĆĆĆÇÇÇÇÇÇÉÉÉÉÉÉÉÉÉĘĘĘÇÇÇĹĹĹĂĂĂÂÂÂŔŔŔÂÂÂĹĹĹĆĆĆĆĆĆĆĆĆĆĆĆÇÇÇÇÇÇÇÇÇÇÇÇÇÇÇĆĆĆŔŔŔÂÂÂŘŘŘňňňňňňäääâââäääçççäääÜÜÜŮŮŮÜÜÜŰŰŰŐŐŐŰŰŰÔÔÔÝÝÝęęęçççăăăâââŮŮŮččččččçççäääääääääćććççççççćććâââßßßÜÜÜÜÜÜÜÜÜÜÜÜÝÝÝŕŕŕćććăăăçççďďďëëëęęęęęęŕŕŕŘŘŘŇŇŇÎÎÎÍÍÍŇŇŇŰŰŰ×××ŇŇŇŇŇŇŇŇŇÉÉÉşşş¸¸¸ŔŔŔ»»»ĹĹĹżżżŔŔŔĹĹĹŔŔŔĂĂĂĹĹĹÉÉÉÇÇÇĆĆĆÇÇÇĘĘĘÍÍÍĚĚĚĘĘĘĆĆĆĂĂĂľľľ¸¸¸´´´±±±±±±°°°ŻŻŻ­­­ŻŻŻłłł···şşşşşş······µµµ´´´···ľľľĂĂĂĹĹĹĂĂĂĆĆĆĹĹĹÎÎÎÎÎÎÎÎÎÔÔÔÍÍÍĹĹű±±ŔŔŔŇŇŇŃŃŃÔÔÔÂÂÂłłłÂ»»»ĘĘĘĂĂĂĽĽĽşşş´´´···łłł´´´µµµ¸¸¸¸¸¸¸¸¸¸¸¸şşşĽĽĽÂÂÂÂÂÂĂĂĂĂĂĂÂÂÂľľľ»»»¸¸¸µµµłłł°°°ŻŻŻ±±±´´´µµµ···´´´¸¸¸»»»ĆĆĆĘĘĘŃŃŃşşşşşşĂĂĂĚĚĚÇÇÇŔŔŔĽĽĽĹĹĹŘŘŘŮŮŮŰŰŰĂĂñ±±ŻŻŻÇÇÇŇŇŇĐĐĐżżżĹĹĹÂÂÂżżżżżżĂĂĂÇÇÇĘĘĘĘĘĘĂĂĂÇÇÇÇÇÇÉÉÉĹĹĹÎÎÎÉÉÉĽĽĽ»»»ĚĚĚÔÔÔÜÜÜçççćććăăăîîîäääćććăăăÝÝÝÝÝÝÍÍ͵µµ¸¸¸¸¸¸¸¸¸şşşĽĽĽŔŔŔĹĹĹÉÉÉĚĚĚĘĘĘĘĘĘĚĚĚĚĚĚĚĚĚĚĚĚÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍĚĚĚĘĘĘÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉÉĘĘĘĘĘĘĚĚĚĚĚĚĚĚĚÉÉÉÇÇÇĹĹĹĂĂĂĂĂĂĹĹĹĆĆĆÇÇÇÉÉÉÇÇÇÇÇÇĆĆĆĆĆĆĆĆĆÇÇÇÇÇÇÇÇÇÂÂÂŇŇŇëëëńńńëëëčččçççëëëçççßßß×××ÔÔÔŐŐŐ×××ŐŐŐŮŮŮŐŐŐÜÜÜçççćććŕŕŕÝÝÝÜÜÜíííęęęçççäääăăăăăăăăăăăăäääâââÝÝÝŰŰŰŮŮŮŰŰŰÜÜÜÝÝÝŕŕŕÝÝÝćććäääčččňňňëëëíííëëëÝÝÝŇŇŇÎÎÎĐĐĐĐĐĐŇŇŇ×××ŔŔŔ···±±±···»»»»»»ĽĽĽŔŔŔŔŔŔĘĘĘĂĂĂĆĆĆĆĆĆĽĽĽŔŔŔĹĹĹĆĆĆĆĆĆĆĆĆÇÇÇĘĘĘĘĘĘĘĘĘÉÉÉĆĆĆĂĂĂżżżşşş······¸¸¸¸¸¸´´´µµµ···şşş»»»ĽĽĽ»»»»»»···µµµµµµşşşŔŔŔĹĹĹĹĹĹÂÂÂĹĹĹĆĆĆÍÍÍÉÉÉÍÍÍÎÎÎşşş´´´µµµÂÂÂŇŇŇÔÔÔŐŐŐÂÂÂłłłĆĆƸ¸¸ĘĘĘĂĂĂ»»»şşşµµµşşş···µµµ···¸¸¸şşş¸¸¸¸¸¸»»»ĽĽĽŔŔŔÂÂÂĂĂĂĂĂĂÂÂÂżżżĽĽĽşşş¸¸¸µµµłłł±±±´´´¸¸¸şşş»»»¸¸¸ľľľżżżÉÉÉĘĘĘĐĐĐ···¸¸¸ĽĽĽĚĚĚĚĚĚÍÍÍĆĆĆŔŔŔÍÍÍŃŃŃŐŐŐ···°°°ÇÇÇŃŃŃŘŘŘŃŃŃĆĆĆĂĂĂÂÂÂÂÂÂĹĹĹÉÉÉĚĚĚÍÍÍĐĐĐĚĚĚÍÍÍÎÎÎĘĘĘÍÍÍÍÍÍĹĹĹżżż¸¸¸ŞŞŞµµµŃŃŃŘŘŘÔÔÔÝÝÝŮŮŮâââŮŮŮ×××ŃŃŃşşş­­­···µµµµµµ···şşşľľľĂĂĂÇÇÇĘĘĘĘĘĘĚĚĚĚĚĚĚĚĚÍÍÍÍÍÍÍÍÍÎÎÎĐĐĐĐĐĐÎÎÎÍÍÍĚĚĚĚĚĚĘĘĘĘĘĘĘĘĘĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚÍÍÍÍÍÍĚĚĚĘĘĘÉÉÉÇÇÇÇÇÇÇÇÇÉÉÉÉÉÉĚĚĚĘĘĘÇÇÇĹĹĹĂĂĂĹĹĹĆĆĆÇÇÇÇÇÇÉÉÉÜÜÜîîîîîîîîîňňňňňňęęęâââŰŰŰ×××ŐŐŐÔÔÔÔÔÔŐŐŐŐŐŐÔÔÔ×××ßßßäääßßßßßßčččîîîëëëčččäääăăăâââŕŕŕŕŕŕÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜâââŰŰŰääääääęęęňňňëëëďďďŕŕŕŐŐŐÎÎÎŇŇŇŘŘŘŘŘŘÔÔÔŇŇŇşşşµµµµµµ¸¸¸»»»ĽĽĽŔŔŔĹĹĹĂĂĂÇÇÇľľľĹĹĹĘĘĘżżżĂĂĂĆĆĆÂÂÂĂĂĂĆĆĆÇÇÇÉÉÉÉÉÉÉÉÉÇÇÇÇÇÇĹĹĹŔŔŔĽĽĽ»»»»»»ľľľżżż¸¸¸»»»ĽĽĽľľľżżżľľľľľľľľľ···µµµ···»»»ÂÂÂĆĆĆĂĂĂŔŔŔżżżĹĹĹĚĚĚÇÇÇŃŃŃŃŃŃ···´´´···ľľľĘĘĘŇŇŇÔÔÔŔŔŔ±±±ÇÇÇ´´´ÉÉÉĹĹĹĽĽĽ¸¸¸µµµşşş¸¸¸µµµ¸¸¸şşşşşş¸¸¸şşş»»»ĽĽĽŔŔŔÂÂÂĂĂĂĂĂĂĂĂĂŔŔŔľľľ»»»żżż»»»¸¸¸¸¸¸»»»ľľľŔŔŔ»»»ŔŔŔĹĹĹÍÍÍÍÍÍŇŇŇ»»»ľľľÂÂÂÍÍÍĚĚĚŇŇŇĚĚĚĽĽĽÉÉÉĐĐĐŐŐŐĹĹĹŔŔŔ···»»»ŻŻŻĽĽĽĘĘĘÇÇÇĹĹĹĂĂĂÂÂÂĹĹĹÉÉÉÍÍÍĐĐĐŇŇŇĚĚĚÔÔÔŮŮŮĐĐĐĆĆĆÉÉÉĘĘĘĂĂĂĹĹĹşşşłłł´´´¬¬¬łłłŇŇŇÔÔÔÜÜÜÔÔÔÜÜÜÔÔÔŞŞŞĄĄĄ¸¸¸łłłłłł´´´···»»»ŔŔŔĆĆĆÉÉÉĚĚĚĚĚĚĚĚĚÍÍÍÍÍÍÎÎÎÎÎÎÎÎÎŃŃŃĐĐĐĐĐĐÎÎÎÍÍÍĚĚĚĚĚĚĘĘĘÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÎÍÍÍĚĚĚĚĚĚĘĘĘĘĘĘĘĘĘĚĚĚÎÎÎĚĚĚÇÇÇĂĂĂÂÂÂĂĂĂĆĆĆÇÇÇŕŕŕëëëíííëëëîîîčččßßßÝÝÝâââŮŮŮ×××ŰŰŰŰŰŰ×××ÔÔÔŐŐŐŃŃŃŇŇŇŃŃŃŮŮŮăăăßßßâââőőőîîîčččăăăŕŕŕâââŕŕŕÝÝÝŮŮŮŘŘŘŰŰŰ×××ŘŘŘßßßŕŕŕÜÜÜßßßäääćććććććććíííőőőńńńçççŐŐŐÔÔÔÔÔÔŐŐŐŘŘŘŐŐŐĚĚĚĹĹĹľľľĽĽĽ»»»ĽĽĽżżżĂĂĂÇÇÇĘĘĘĂĂĂŔŔŔÂÂÂÉÉÉĚĚĚÇÇÇĂĂĂĂĂĂÉÉÉÉÉÉĘĘĘĚĚĚĚĚĚĘĘĘĘĘĘÉÉÉĆĆĆĹĹĹĽĽĽµµµ···żżżÂÂÂżżżżżżľľľľľľżżżÂÂÂĂĂĂŔŔŔżżżľľľÂÂÂĂĂĂÂÂÂľľľľľľÂÂÂÇÇÇÂÂÂĹĹĹĘĘĘĆĆĆŃŃŃŇŇŇ»»»»»»»»»¸¸¸żżżĽĽĽŇŇҵµµĂĂõµµÂÂÂĆĆĆľľľ»»»żżżĽĽĽ´´´¸¸¸¸¸¸şşş»»»ĽĽĽľľľżżżżżżĆĆĆÂÂÂŔŔŔÂÂÂŔŔŔ»»»¸¸¸ĽĽĽ»»»ľľľľľľŔŔŔĹĹĹľľľĽĽĽĆĆĆĂĂĂľľľĂĂĂĹĹĹÎÎÎÎÎλ»»żżżĆĆĆĐĐĐ×××ÔÔÔĘĘĘÂÂÂŔŔŔĹĹĹĚĚĚ×××ŕŕŕčččŮŮŮÇÇDZ±±ĘĘĘÇÇÇÍÍÍĐĐĐĚĚĚĐĐĐŐŐŐŃŃŃŘŘŘÎÎÎÎÎÎŃŃŃĐĐĐÔÔÔŇŇŇÉÉÉÇÇÇĂĂĂľľľ»»»şşş···±±±­­­ŮŮŮŇŇŇâââÔÔÔŻŻŻ···ŞŞŞłłł´´´»»»¸¸¸µµµżżżĆĆĆĂĂĂĂĂĂĐĐĐĐĐĐÎÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍĐĐĐĐĐĐĐĐĐÎÎÎÎÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÎÎŃŃŃŇŇŇŃŃŃÎÎÎÉÉÉĆĆĆÉÉÉÎÎÎÎÎÎĘĘĘÉÉÉĚĚĚÇÇÇĽĽĽżżżĂĂĂĆĆĆŔŔŔĂĂĂčččőőőúúúďďďîîîäääŘŘŘßßßŰŰŰÔÔÔÜÜÜÜÜÜÜÜÜŕŕŕŰŰŰŘŘŘŕŕŕÔÔÔĐĐĐŇŇŇ×××čččçççŰŰŰóóóëëëçççăăăâââŕŕŕßßßŰŰŰ×××ĐĐĐŮŮŮŮŮŮŘŘŘÜÜÜŃŃŃĆĆĆĆĆĆÝÝÝâââćććčččëëëëëëçççăăăŘŘŘŰŰŰŕŕŕäääăăăŘŘŘÇÇÇ»»»ŔŔŔŔŔŔÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÇÇÇĹĹĹÂÂÂĂĂĂÂÂÂÂÂÂĆĆĆÍÍÍĆĆĆÉÉÉÍÍÍĐĐĐĐĐĐĚĚĚÇÇÇĹĹĹĆĆĆĂĂĂľľľ¸¸¸şşşŔŔŔĂĂĂŔŔŔĹĹĹĂĂĂŔŔŔŔŔŔÂÂÂĹĹĹĆĆĆĆĆĆĆĆĆŔŔŔĽĽĽĽĽĽŔŔŔĹĹĹĂĂĂÂÂÂÇÇÇÇÇÇĚĚĚĆĆĆÍÍÍŃŃŃĽĽĽµµµ»»»ľľľ»»»ÂÂÂŇŇŇĽĽĽĽĽĽľľľ»»»ÂÂÂÂÂÂĽĽĽşşşľľľľľľ¸¸¸şşşşşş»»»ĽĽĽľľľľľľżżżżżżĹĹĹÂÂÂÂÂÂĂĂĂżżżşşş¸¸¸»»»ÂÂÂĂĂĂĹĹĹÉÉÉÍÍÍÍÍÍĘĘĘÉÉÉÇÇÇżżżÂÂÂĹĹĹĐĐĐÎÎÎĽĽĽÂÂÂÇÇÇÎÎÎÔÔÔŃŃŃĆĆĆľľľľľľŔŔŔĂĂĂĘĘĘÉÉÉÍÍÍŃŃŃÜÜÜŕŕŕĘĘĘŔŔŔĽĽĽĘĘĘŘŘŘÔÔÔĘĘĘĚĚĚÍÍÍăăăÍÍÍÍÍÍÜÜÜŘŘŘÍÍÍÍÍÍŇŇŇĆĆĆÂÂÂľľľĽĽĽľľľľľľşşşµµµ¬¬¬­­­ŃŃŃÔÔÔ¬¬¬łłł¬¬¬°°°łłłşşş¸¸¸···ŔŔŔÇÇÇĆĆĆÉÉÉĐĐĐĐĐĐÎÎÎÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎĐĐĐĐĐĐĐĐĐÎÎÎÎÎÎÎÎÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍĐĐĐŃŃŃŃŃŃĐĐĐĐĐĐŇŇŇÍÍÍÉÉÉÉÉÉĘĘĘĘĘĘĘĘĘĚĚĚĆĆĆĐĐĐÝÝÝäääîîîíííęęęöööęęęęęęŕŕŕŕŕŕŕŕŕÝÝÝäääâââßßßŕŕŕŘŘŘŇŇŇŘŘŘŮŮŮŘŘŘÜÜÜŐŐŐŇŇŇŇŇŇŐŐŐćććčččßßßńńńćććäääăăăâââßßßÜÜÜŘŘŘŐŐŐ×××ßßßŘŘŘ×××âââŰŰŰĚĚĚÎÎÎŕŕŕăăăęęęďďďëëëâââÝÝÝÝÝÝŕŕŕŕŕŕŕŕŕÝÝÝŮŮŮŃŃŃÉÉÉĹĹĹĂĂĂĂĂĂĹĹĹĹĹĹĹĹĹĹĹĹĹĹĹĹĹĹĆĆĆĂĂĂĂĂĂÇÇÇÇÇÇĹĹĹĆĆĆÉÉÉÉÉÉĚĚĚÎÎÎŃŃŃĐĐĐĚĚĚÇÇÇĂĂĂĂĂĂĂĂĂżżżĽĽĽľľľÂÂÂĂĂĂÂÂÂĂĂĂĂĂĂÂÂÂżżżĽĽĽ»»»»»»ĽĽĽÂÂÂżżżĽĽĽľľľÂÂÂĹĹĹÂÂÂżżżżżżŔŔŔĘĘĘÉÉÉÍÍÍŐŐŐĹĹű±±µµµľľľ¸¸¸ĂĂĂĘĘĘ´´´ľľľµµµĂĂĂŔŔŔľľľ»»»»»»ĽĽĽľľľľľľ»»»»»»ĽĽĽľľľľľľżżżŔŔŔŔŔŔĹĹĹĂĂĂĹĹĹĹĹĹŔŔŔ»»»şşşĽĽĽżżżĹĹĹÉÉÉĆĆĆÂÂÂĆĆĆĐĐĐ×××ÍÍÍĂĂĂĂĂĂÉÉÉŃŃŃĚĚĚľľľĆĆĆÎÎÎÔÔÔ×××ŃŃŃĆĆĆżżżľľľŔŔŔľľľÉÉÉĹĹĹżżżĹĹĹŮŮŮŕŕŕĹĹĹĂĂĂ»»»ŔŔŔÎÎÎŃŃŃĐĐĐŐŐŐŰŰŰŮŮŮĐĐĐŘŘŘçççäääŘŘŘÔÔÔ×××ĘĘĘĆĆĆÂÂÂÂÂÂĂĂĂĂĂĂŔŔŔľľľłłł±±±×××ÜÜÜ­­­±±±´´´¸¸¸´´´»»»ĽĽĽĽĽĽÂÂÂÇÇÇÉÉÉĚĚĚĐĐĐÎÎÎÎÎÎÍÍÍÍÍÍÎÎÎÎÎÎĐĐĐŃŃŃĐĐĐĐĐĐĐĐĐĐĐĐÎÎÎÎÎÎÎÎÎÍÍÍÎÎÎĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐÍÍÍĚĚĚĘĘĘĘĘĘÍÍÍÎÎÎĚĚĚÉÉÉ»»»âââřřřřřřóóóńńńńńńîîîíííçççŮŮŮŘŘŘŰŰŰŰŰŰßßßŰŰŰăăăăăăŘŘŘÎÎÎŇŇŇŘŘŘŐŐŐŇŇŇŐŐŐŐŐŐŇŇŇŃŃŃâââęęęăăăîîîăăăăăăâââŕŕŕÝÝÝŮŮŮŘŘŘ×××ÔÔÔŃŃŃľľľżżżÜÜÜăăăŮŮŮÝÝÝăăăÝÝÝŕŕŕćććâââÔÔÔÎÎÎŇŇŇăăăŕŕŕŘŘŘÎÎÎÇÇÇĹĹĹĆĆĆÉÉÉÇÇÇĆĆĆĹĹĹĹĹĹÇÇÇĘĘĘÍÍÍĐĐĐÇÇÇĂĂĂĹĹĹĚĚĚĐĐĐĚĚĚĆĆĆĂĂĂĐĐĐÎÎÎÍÍÍĚĚĚĘĘĘÉÉÉÇÇÇÇÇÇÂÂÂÂÂÂŔŔŔŔŔŔŔŔŔÂÂÂÂÂÂÂÂÂżżżĂĂĂÇÇÇÉÉÉÇÇÇĹĹĹĂĂĂĹĹĹĂĂĂĘĘĘĐĐĐÎÎÎĆĆĆĂĂĂĆĆĆĚĚĚŇŇŇÎÎÎÎÎÎÉÉÉÍÍÍâââäääŃŃѵµµ»»»ĆĆĆÇÇÇŔŔŔ···»»»»»»ÇÇÇżżż»»»ĽĽĽżżżĽĽĽľľľŔŔŔľľľľľľľľľżżżŔŔŔŔŔŔÂÂÂÂÂÂĂĂĂĹĹĹÇÇÇÇÇÇĂĂĂŔŔŔŔŔŔÂÂÂĆĆĆÉÉÉĂĂĂşşş´´´°°°···ĆĆĆÍÍÍÉÉÉÉÉÉÎÎÎĐĐĐĂĂĂĽĽĽÉÉÉŇŇŇÔÔÔÔÔÔÎÎÎĆĆĆżżżľľľżżżÇÇÇŮŮŮŮŮŮÎÎÎÇÇÇŇŇŇßßßÍÍÍÇÇÇĂĂĂĂĂĂÇÇÇÎÎÎŐŐŐÔÔÔÍÍÍŮŮŮćććčččÝÝÝ×××ŰŰŰŮŮŮÍÍÍŃŃŃĚĚĚÇÇÇĹĹĹĆĆĆĹĹĹÂÂÂżżż···´´´ÍÍÍŐŐŐŻŻŻ°°°°°°¸¸¸···ĽĽĽŔŔŔĂĂĂĹĹĹĆĆĆÉÉÉĚĚĚÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎĐĐĐĐĐĐŃŃŃŃŃŃŃŃŃŃŃŃŃŃŃŃŃŃŃŃŃŃŃŃŃŃŃÍÍÍĐĐĐŇŇŇŃŃŃĐĐĐÎÎÎÎÎÎĐĐĐĆĆĆĚĚĚĐĐĐĐĐĐÍÍÍĘĘĘĆĆĆŔŔŔĂĂĂëëëüüüüüüóóóńńńúúúńńńďďďęęęâââŕŕŕâââäääččččččŰŰŰâââßßßŐŐŐŐŐŐŮŮŮŐŐŐĚĚĚŐŐŐŘŘŘŇŇŇÎÎÎÝÝÝčččçççëëëäääăăăâââßßßŰŰŰŘŘŘ××××××ÔÔÔĐĐĐżżżŔŔŔÜÜÜäääÝÝÝŕŕŕ×××ÉÉÉĂĂĂĚĚĚÍÍÍĆĆĆÂÂÂÇÇÇĂĂĂĆĆĆĘĘĘĚĚĚĚĚĚÎÎÎÔÔÔŘŘŘÎÎÎÎÎÎÍÍÍĚĚĚĘĘĘĚĚĚÍÍÍÍÍÍĚĚĚĘĘĘĚĚĚÎÎÎÍÍÍÇÇÇÇÇÇĘĘĘĐĐĐÎÎÎÍÍÍĘĘĘÉÉÉÇÇÇĆĆĆĆĆĆÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂŔŔŔŔŔŔŔŔŔĂĂĂĆĆĆĘĘĘĘĘĘÇÇÇĹĹĹĹĹĹĹĹĹĽĽĽĂĂĂĆĆĆĽĽĽ­­­©©©±±±ľľľĚĚĚÍÍÍÍÍÍĘĘĘĚĚĚÜÜÜÝÝÝĆĆƸ¸¸»»»ŘŘŘĚĚĚ»»»ĂĂĂşşşĘĘĘĆĆĆľľľ»»»ŔŔŔÂÂÂľľľľľľÂÂÂŔŔŔŔŔŔŔŔŔŔŔŔÂÂÂÂÂÂĂĂĂĂĂĂÂÂÂĆĆĆÉÉÉĘĘĘÉÉÉÇÇÇÇÇÇÇÇÇÍÍÍĂĂñ±±ŻŻŻşşş±±±¬¬¬şşşĘĘĘĐĐĐĐĐĐŃŃŃĘĘĘ»»»»»»ÉÉÉĐĐĐŃŃŃĐĐĐĘĘĘĹĹĹżżżľľľżżżÇÇÇŐŐŐŘŘŘŇŇŇĆĆĆÍÍÍâââßßßĘĘĘÉÉÉĹĹĹÂÂÂĆĆĆÍÍÍŃŃŃŐŐŐŇŇŇŰŰŰŐŐŐĂĂĂÂÂÂŇŇŇâââćććŇŇŇÍÍÍÇÇÇĆĆĆÇÇÇÇÇÇĹĹĹÂÂÂĽĽĽĽĽĽĚĚĚßßßÍÍÍĂĂĂ°°°´´´µµµşşşŔŔŔĆĆĆÇÇÇÉÉÉĚĚĚÍÍÍÍÍÍÍÍÍÍÍÍÎÎÎÎÎÎĐĐĐŃŃŃŇŇŇŇŇŇŇŇŇÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔÔĐĐĐŇŇŇÔÔÔŇŇŇĐĐĐÎÎÎÎÎÎĐĐĐÍÍÍĐĐĐŃŃŃĚĚĚĹĹĹÂÂÂĹĹĹÇÇÇčččöööőőőřřřöööóóóöööçççÝÝÝÜÜÜŰŰŰÔÔÔĐĐĐÎÎÎĐĐĐŇŇŇŇŇŇßßßäääÜÜÜŐŐŐŘŘŘŘŘŘŃŃŃÔÔÔŮŮŮŇŇŇÎÎÎŮŮŮäääęęęčččćććäääâââÝÝÝŰŰŰŐŐŐŃŃŃÎÎÎşşşżżżżżżŔŔŔĆĆĆÂÂÂşşş¸¸¸ÇÇÇşşş´´´ľľľĆĆĆĆĆĆĆĆĆĚĚĚĚĚĚÎÎÎŃŃŃŃŃŃÎÎÎÍÍÍÎÎÎĐĐĐŐŐŐŐŐŐŇŇŇĐĐĐÍÍÍÉÉÉĆĆĆĂĂĂÉÉÉĐĐĐŮŮŮŰŰŰŃŃŃĆĆĆĆĆĆÍÍÍÉÉÉĘĘĘĚĚĚĚĚĚĘĘĘĆĆĆĂĂĂŔŔŔÂÂÂŔŔŔÂÂÂÂÂÂŔŔŔĽĽĽĽĽĽżżżĂĂĂĂĂĂĂĂĂÂÂÂŔŔŔÂÂÂĂĂĂĹĹĹŃŃŃÍÍ͵µµ¬¬¬¬¬¬µµµľľľĐĐĐÝÝÝăăăčččçççŕŕŕŇŇҵµµłłłşşşŇŇŇĂĂĂ···ĆĆĆ···ÍÍÍĹĹĹżżżľľľÂÂÂĂĂĂżżżżżżĂĂĂÂÂÂÂÂÂĂĂĂĂĂĂĂĂĂĂĂĂĹĹĹĹĹĹĂĂĂÇÇÇĘĘĘĘĘĘĚĚĚÎÎÎĚĚĚÉÉÉÔÔÔĘĘĘ···ŻŻŻ´´´´´´şşşĚĚĚÉÉÉŇŇŇÍÍÍĘĘĘĂĂĂ···ľľľĘĘĘÔÔÔÔÔÔŇŇŇĐĐĐÍÍÍĘĘĘÉÉÉÉÉÉÉÉÉÍÍÍÎÎÎŇŇŇÉÉÉĆĆĆŃŃŃÍÍÍŰŰŰ×××ŇŇŇĐĐĐĚĚĚĹĹĹĐĐĐäääÔÔÔĘĘĘÂÂÂÂÂÂŔŔŔľľľĘĘĘăăăŃŃŃÍÍÍÇÇÇĆĆĆÉÉÉĘĘĘĘĘĘÇÇǸ¸¸µµµ»»»ŘŘŘ×××ĚĚĚ´´´´´´µµµ´´´ĽĽĽĆĆĆÇÇÇĘĘĘĐĐĐŃŃŃÍÍÍÍÍÍÍÍÍÎÎÎĐĐĐŃŃŃŇŇŇÔÔÔŐŐŐŐŐŐŐŐŐŐŐŐ××××××××××××ÔÔÔÔÔÔŐŐŐÔÔÔŇŇŇĐĐĐĐĐĐĐĐĐŃŃŃĘĘĘĹĹĹĂĂĂĂĂĂĘĘĘŮŮŮčččüüüřřřóóóöööďďďćććăăăŰŰŰŕŕŕßßßâââŘŘŘÎÎÎĚĚĚĆĆĆĚĚĚŃŃŃŮŮŮâââÜÜÜŇŇŇŐŐŐÜÜÜŰŰŰŇŇŇŘŘŘŃŃŃŃŃŃ×××ßßßčččćććçççäääâââßßßŮŮŮŃŃŃĆĆĆľľľ¸¸¸ĽĽĽĆĆĆÇÇÇľľľ···´´´°°°ľľľ···¸¸¸ŔŔŔÉÉÉĘĘĘÍÍÍŇŇŇŐŐŐÔÔÔŇŇŇŃŃŃĐĐĐĐĐĐŇŇŇÔÔÔÔÔÔŃŃŃÍÍÍÉÉÉÇÇÇÇÇÇĘĘĘĚĚĚÎÎÎŇŇŇŰŰŰŕŕŕŰŰŰÎÎÎĆĆĆĆĆĆĆĆĆÇÇÇÉÉÉÉÉÉÇÇÇĹĹĹÂÂÂżżżÂÂÂŔŔŔŔŔŔÂÂÂľľľ¸¸¸¸¸¸ĽĽĽľľľżżżÂÂÂĆĆĆĘĘĘĚĚĚĘĘĘÉÉÉĂĂĂ»»»°°°ŞŞŞŞŞŞ°°°´´´···ĘĘĘ×××ŃŃŃŃŃŃŃŃŃÇÇÇŔŔŔ±±±°°°ĂĂĂľľľĽĽĽĽĽĽÇÇÇÂÂÂÉÉÉĂĂĂÂÂÂŔŔŔÂÂÂŔŔŔŔŔŔÂÂÂĹĹĹĹĹĹĹĹĹĹĹĹĹĹĹĹĹĹĹĹĹĹĹĹĹĹĹĆĆĆÉÉÉĘĘĘÉÉÉÍÍÍĐĐĐĘĘĘĂĂĂŇŇŇŃŃŃÎÎÎľľľŞŞŞłłłÉÉÉĐĐĐĘĘĘŃŃŃ»»»ĽĽĽşşşĆĆĆĘĘĘŇŇŇŇŇŇŇŇŇŇŇŇÔÔÔŇŇŇŃŃŃĐĐĐŇŇŇÔÔÔÔÔÔŮŮŮŃŃŃĘĘĘÎÎÎĂĂĂÝÝÝâââăăăçççâââÍÍÍÂÂÂĚĚĚĹĹĹŔŔŔŔŔŔĚĚĚÍÍÍżżżŔŔŔŘŘŘŐŐŐĐĐĐĘĘĘÇÇÇĘĘĘĚĚĚĚĚĚĘĘĘŔŔŔ´´´µµµŰŰŰâââăăăŮŮŮÜÜÜżżż···şşşÂÂÂÂÂÂÇÇÇĐĐĐŃŃŃĚĚĚĚĚĚÍÍÍÎÎÎĐĐĐŇŇŇÔÔÔŐŐŐ××××××ŘŘŘŘŘŘŮŮŮŮŮŮŮŮŮŮŮŮŘŘŘ×××ŐŐŐŐŐŐÔÔÔŇŇŇŃŃŃÎÎÎĚĚĚżżżĽĽĽÍÍÍÜÜÜăăăîîîúúúőőőíííőőőöööęęęääääääčččÎÎÎĘĘĘŃŃŃĚĚĚĚĚĚĐĐĐĘĘĘĐĐĐŃŃŃŇŇŇŮŮŮŮŮŮŇŇŇŐŐŐÝÝÝÜÜÜĐĐĐŐŐŐĐĐĐÔÔÔ×××ŮŮŮçççćććčččćććăăăŕŕŕŮŮŮÍÍÍľľľ±±±şşşµµµĽĽĽżżżµµµ···ľľľ¸¸¸´´´···ĽĽĽĂĂĂĆĆĆÇÇÇĘĘĘÎÎÎŇŇŇŇŇŇŇŇŇŇŇŇŇŇŇŇŇŇŇŇŇŇŇŇÍÍÍĆĆĆżżż»»»żżżĘĘĘ×××ŕŕŕăăăŘŘŘŃŃŃŐŐŐŰŰŰ×××ÍÍÍĹĹĹÉÉÉÇÇÇĹĹĹĂĂĂÂÂÂÂÂÂÂÂÂĂĂĂÂÂÂżżżżżżŔŔŔĽĽĽµµµµµµ»»»ĂĂĂĆĆĆÉÉÉĚĚĚÉÉÉľľľ°°°¦¦¦ŞŞŞ¨¨¨¦¦¦ŞŞŞ°°°µµµ···µµµ¸¸¸ĹĹŸ¸¸¸¸¸ľľľ´´´´´´±±±···×××´´´ÂÂÂÍÍÍĐĐĐ×××ĚĚĚÂÂÂĂĂĂĂĂĂŔŔŔżżżŔŔŔĹĹĹÇÇÇĹĹĹĹĹĹĹĹĹĹĹĹĆĆĆĆĆĆĆĆĆĆĆĆÉÉÉĘĘĘÉÉÉÇÇÇĚĚĚÎÎÎÇÇÇľľľŻŻŻ···ÎÎÎĘĘʵµµĘĘĘßßßĘĘĘĚĚĚĐĐи¸¸°°°¸¸¸żżżĚĚĚĘĘĘĆĆĆÇÇÇÉÉÉĘĘĘÍÍÍÎÎÎÍÍÍĘĘĘĚĚĚÎÎÎĘĘĘĚĚĚÇÇÇĘĘĘŘŘŘŃŃŃĆĆĆÎÎÎĐĐĐŘŘŘäääŕŕŕÍÍÍĂĂĂĘĘĘÔÔÔŇŇŇÍÍÍĚĚĚĹĹĹżżżĆĆĆŰŰŰŐŐŐÎÎÎĘĘĘĘĘĘĚĚĚÉÉÉÇÇÇÇÇÇłłł´´´ŰŰŰŰŰŰÝÝÝŰŰŰŮŮŮĘĘĘĽĽĽşşşľľľĽĽĽÂÂÂĚĚĚÍÍÍĚĚĚĚĚĚÍÍÍÎÎÎĐĐĐŇŇŇŐŐŐ×××ŘŘŘŘŘŘŮŮŮŮŮŮŰŰŰŰŰŰŰŰŰÜÜÜŮŮŮŘŘŘŐŐŐŐŐŐ×××ŐŐŐŃŃŃÎÎÎÉÉÉĽĽĽÂÂÂâââřřřöööîîîîîîůůůçççíííęęęŕŕŕâââÜÜÜßßßŃŃŃÇÇÇĚĚĚÇÇÇĚĚĚŇŇŇĘĘĘÍÍÍĐĐĐĚĚĚÔÔÔŮŮŮ×××ŘŘŘŰŰŰŘŘŘÎÎÎÔÔÔĐĐĐŐŐŐŐŐŐŐŐŐććććććÝÝÝÝÝÝăăăŰŰŰŇŇŇÇÇǵµµ´´´µµµ»»»ŔŔŔÂÂÂŔŔŔľľľ»»»»»»¸¸¸»»»ľľľÂÂÂÇÇÇÍÍÍŇŇŇ××××××ŕŕŕÜÜÜŇŇŇÔÔÔŐŐŐŇŇŇ××׿żżĘĘĘĘĘĘĂĂĂ»»»´´´µµµÇÇÇĚĚĚÉÉÉÍÍÍăăăŐŐŐĐĐĐŔŔŔĹĹĹĂĂĂÂÂÂŔŔŔľľľľľľĽĽĽĽĽĽ»»»ŔŔŔĂĂĂżżżşşş¸¸¸······»»»ĘĘĘÎÎÎľľľŻŻŻ­­­ŻŻŻ­­­ŞŞŞ©©©¸¸¸ľľľ¬¬¬¬¬¬şşşşşşżżż´´´···ĽĽĽ······ľľľżżżÍÍÍĽĽĽŔŔŔşşş···ĘĘĘĚĚĚľľľŔŔŔÂÂÂĂĂĂĂĂĂĹĹĹĹĹĹĹĹĹĹĹĹÉÉÉÉÉÉĹĹĹĹĹĹĚĚĚÉÉÉÇÇÇŇŇŇŇŇŇĹĹĹĐĐĐÉÉÉĚĚĚŃŃѸ¸¸µµµşşşżżżÍÍÍÔÔÔĐĐĐĐĐĐŃŃŃĚĚĚŘŘŘĘĘĘ»»»···ľľľĹĹĹĆĆĆĂĂĂŔŔŔĂĂĂĂĂĂĹĹĹĹĹĹĽĽĽşşşĹĹĹĂĂĂÂÂÂżżżŔŔŔĹĹĹĂĂĂĆĆĆĐĐĐĐĐĐÂÂÂżżżĆĆĆ×××ęęęĆĆĆÉÉÉŮŮŮęęęčččăăăŐŐŐĹĹĹŔŔŔşşşÔÔÔĐĐĐ×××ŃŃŃÍÍÍÎÎÎĆĆĆÍÍÍĘĘĘŔŔŔ···´´´ĐĐĐäääŰŰŰŕŕŕŕŕŕŃŃŃ»»»···ľľľľľľÂÂÂŇŇŇĚĚĚĹĹĹÉÉÉÉÉÉÍÍÍŇŇŇÎÎÎÔÔÔÔÔÔÔÔÔŐŐŐŘŘŘŰŰŰÜÜÜÝÝÝßßßŰŰŰŃŃŃŃŃŃ××××××ŮŮŮÔÔÔĆĆĆĽĽĽÇÇÇćććřřřňňňőőőőőőäääâââäääëëëäääăăăăăăŃŃŃĆĆĆÉÉÉĘĘĘĘĘĘĚĚĚĚĚĚÍÍÍÎÎÎÎÎÎÎÎÎŃŃŃĘĘĘŮŮŮçççŰŰŰŇŇŇŇŇŇŐŐŐĐĐĐÍÍÍÎÎÎŃŃŃ×××âââîîîčččßßßŕŕŕŘŘŘĚĚĚľľľłłł»»»ĽĽĽżżżÂÂÂÂÂÂżżżĽĽĽ»»»»»»ĽĽĽĽĽĽżżżĹĹĹĘĘĘÎÎÎÎÎÎÍÍÍĂĂĂÍÍÍĚĚĚĆĆĆÉÉÉĘĘĘÇÇÇĘĘĘĹĹĹÍÍÍĚĚĚĹĹĹĆĆĆĹĹĹżżżŔŔŔľľľĽĽĽľľľĚĚĚăăăÔÔÔĐĐĐÉÉÉĂĂĂĂĂĂŔŔŔżżżľľľľľľľľľľľľÂÂÂĽĽĽşşşĽĽĽ»»»···¸¸¸ĽĽĽżżżÂÂÂľľľ±±±­­­±±±´´´±±±ŞŞŞ­­­ÂÂÂĚĚĚşşş±±±¸¸¸¸¸¸»»»¸¸¸żżżĂĂø¸¸µµµĂĂĂÎÎÎĽĽĽ¸¸¸¸¸¸ÂÂÂÉÉÉÎÎÎÎÎÎĂĂĂÂÂÂÂÂÂÂÂÂĂĂĂĂĂĂĹĹĹĆĆĆĆĆĆÇÇÇĘĘĘÇÇÇÉÉÉÍÍÍÉÉÉĘĘĘŐŐŐÜÜÜĐĐĐŘŘŘŃŃŃĐĐĐÎÎεµµµµµľľľĽĽĽşşşżżżÍÍÍŐŐŐŐŐŐŇŇŇĹĹĹľľľ¸¸¸ĽĽĽĹĹĹÉÉÉĆĆĆŔŔŔżżżŔŔŔ»»»»»»ÂÂÂĂĂĂĹĹĹĐĐĐÔÔÔŇŇŇĂĂĂŔŔŔĹĹĹżżżĂĂĂÍÍÍŐŐŐŃŃŃĐĐĐĘĘĘĚĚĚăăăŃŃŃŘŘŘăăăâââÝÝÝäääßßßŃŃŃĚĚĚżżżÇÇÇÍÍÍŮŮŮŇŇŇŃŃŃ×××ÎÎÎÍÍÍĘĘĘĹĹĹ»»»´´´ÇÇÇßßßâââăăăßßßŕŕŕÝÝÝŘŘŘÍÍÍ»»»···ĆĆĆĆĆĆĆĆĆĘĘĘĂĂĂĆĆĆŇŇŇŇŇŇŐŐŐŃŃŃÔÔÔ×××ŐŐŐÔÔÔŐŐŐŮŮŮÝÝÝßßßŮŮŮŕŕŕäääŰŰŰŃŃŃĚĚĚĹĹĹÎÎÎÝÝÝńńńőőőíííęęęčččäääßßßÝÝÝăăăŰŰŰ××××××ÍÍÍĚĚĚĘĘĘĘĘĘĘĘĘĚĚĚĚĚĚÍÍÍÍÍÍÍÍÍĘĘĘÍÍÍĘĘĘŰŰŰâââ×××ŇŇŇŃŃŃĐĐĐÍÍÍĚĚĚÎÎÎŃŃŃÔÔÔÜÜÜćććçççßßßÝÝÝÍÍÍĽĽĽ······ÂÂÂÂÂÂÂÂÂĂĂĂŔŔŔżżżľľľľľľżżżĽĽĽĂĂĂĘĘĘÉÉÉĹĹĹĹĹĹĘĘĘŃŃŃÇÇÇÎÎÎÍÍÍÉÉÉÉÉÉĆĆĆĂĂĂĂĂĂĹĹĹĐĐĐÔÔÔÔÔÔŮŮŮŇŇŇĹĹĹľľľĂĂĂŔŔŔ»»»ĂĂĂŐŐŐÍÍÍÍÍÍĹĹĹÂÂÂÂÂÂŔŔŔżżżżżżżżżżżżŔŔŔĹĹĹĽĽĽĽĽĽĂĂĂżżż´´´łłł»»»ĘĘĘ»»»­­­­­­µµµĽĽĽ¸¸¸°°°ŻŻŻ­­­ŔŔŔĐĐĐŔŔŔ´´´¸¸¸»»»ľľľľľľÂÂÂÂÂÂşşş¸¸¸ÂÂÂÉÉÉĂĂĂÂÂÂşşşĘĘĘÔÔÔĆĆĆĂĂĂľľľÂÂÂÂÂÂÂÂÂÂÂÂĂĂĂĹĹĹÇÇÇÇÇÇÇÇÇĚĚĚĚĚĚĚĚĚĚĚĚĘĘĘÍÍÍŘŘŘŮŮŮÍÍÍŐŐŐŃŃŃĐĐĐÎÎÎżżżĆĆĆĂĂĂĂĂø¸¸µµµĚĚĚŰŰŰ×××ŇŇŇĽĽĽ»»»ĽĽĽÂÂÂÉÉÉĘĘĘĹĹĹľľľľľľżżż¸¸¸¸¸¸ĆĆĆŃŃŃÔÔÔŘŘŘÜÜÜßßß»»»ĹĹĹľľľŔŔŔĚĚĚĐĐĐĐĐĐŐŐŐÎÎÎĹĹĹâââÜÜÜâââÎÎÎĹĹĹĂĂĂÔÔÔŰŰŰßßßâââÍÍÍ»»»ÇÇÇ×××ŇŇŇÔÔÔÜÜÜŐŐŐÍÍÍĘĘĘÉÉÉżżżşşşĽĽĽŃŃŃçççäääćććîîîńńńęęęŘŘŘĹĹĹĹĹĹŐŐŐääääääâââÉÉÉŔŔŔÍÍÍÍÍÍÎÎÎÎÎÎŃŃŃŐŐŐ×××ŘŘŘŮŮŮÜÜÜßßßŰŰŰÜÜÜăăăăăăŇŇŇĹĹĹĆĆĆÉÉÉâââňňňůůůňňňçççŕŕŕŕŕŕćććńńńćććäääŮŮŮŃŃŃÍÍÍÇÇÇĐĐĐĘĘĘĘĘĘĘĘĘĚĚĚĚĚĚĚĚĚĚĚĚĚĚĚĆĆĆĆĆĆĚĚĚÝÝÝÜÜÜŃŃŃÔÔÔĐĐĐĚĚĚĘĘĘĚĚĚĐĐĐŃŃŃĐĐĐŐŐŐÜÜÜŰŰŰÜÜÜßßßĹĹű±±şşşżżżÂÂÂĂĂĂĂĂĂĂĂĂÂÂÂŔŔŔŔŔŔŔŔŔÂÂÂľľľĹĹĹĘĘĘÇÇÇÂÂÂĂĂĂÍÍÍ×××ŐŐŐ×××ŐŐŐŃŃŃĐĐĐÍÍÍĘĘĘÉÉÉŃŃŃŮŮŮŘŘŘŐŐŐŰŰŰ×××ĘĘĘĂĂĂĚĚĚÍÍÍŔŔŔĽĽĽĆĆĆĘĘĘÎÎÎŔŔŔĂĂĂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂĂĂĂĂĂĂÂÂÂżżżÂÂÂĹĹĹľľľ´´´···ÂÂÂľľľ´´´°°°···ĽĽĽľľľĽĽĽľľľ¸¸¸¬¬¬łłłŔŔŔ»»»łłłşşşŔŔŔĆĆĆĆĆĆĂĂĂŔŔŔĹĹĹÎÎÎĚĚĚżżżĚĚĚżżż¸¸¸ĚĚĚŃŃŃĂĂĂĂĂĂĆĆĆĂĂĂÂÂÂÂÂÂŔŔŔÂÂÂĹĹĹÉÉÉĘĘĘÉÉÉÍÍÍÎÎÎÍÍÍĘĘĘĚĚĚŇŇŇŰŰŰżżżµµµĽĽĽ»»»»»»»»»¸¸¸ĹĹĹĂĂĂĘĘĘĹĹŸ¸¸ÂÂÂŐŐŐÔÔÔŔŔŔľľľľľľľľľÂÂÂÇÇÇĘĘĘÇÇÇĹĹĹĽĽĽŔŔŔ»»»ĽĽĽĐĐĐÜÜÜŰŰŰŘŘŘ×××ÝÝÝĽĽĽµµµÇÇÇŔŔŔÂÂÂĚĚĚÉÉÉĆĆĆÎÎÎŃŃŃĹĹĹŰŰŰŐŐŐŐŐŐĚĚĚÉÉÉĆĆĆÉÉÉÇÇÇŘŘŘăăăĆĆĆşşşÂÂÂÍÍÍÎÎÎŃŃŃ×××ÔÔÔŃŃŃÍÍÍÇÇÇŔŔŔŔŔŔ···ĂĂĂććććććęęęęęęëëëęęęăăăÝÝÝâââîîîëëëíííëëëÔÔÔĹĹĹÇÇÇŔŔŔÂÂÂÍÍÍÎÎÎŃŃŃ×××ÜÜÜÝÝÝÜÜÜŮŮŮâââŕŕŕŮŮŮĚĚĚÂÂÂÉÉÉŰŰŰęęęďďďöööůůůďďďăăăŕŕŕäääçççćććÔÔÔĐĐĐĚĚĚĘĘĘÉÉÉÇÇÇÔÔÔĘĘĘĘĘĘĘĘĘĘĘĘĘĘĘĘĘĘĘĘĘĘĘĘĂĂĂĂĂĂÍÍÍßßßŮŮŮÎÎÎŐŐŐŃŃŃĘĘĘÉÉÉÍÍÍŃŃŃŇŇŇÎÎÎĐĐĐÔÔÔŮŮŮÝÝÝćććÍÍ͵µµĽĽĽĂĂĂĹĹĹĆĆĆĆĆĆĹĹĹĂĂĂĂĂĂŔŔŔżżżľľľÂÂÂżżżżżżĹĹĹÍÍÍŃŃŃŃŃŃÎÎÎĐĐĐÍÍÍÍÍÍÎÎÎÎÎÎÎÎÎÎÎÎÍÍÍŇŇŇŰŰŰŘŘŘŐŐŐŮŮŮ×××ÍÍÍÉÉÉÉÉÉĘĘĘżżżĂĂĂÉÉÉĐĐĐÔÔÔÇÇÇĹĹĹĂĂĂĂĂĂĂĂĂĂĂĂĹĹĹĆĆĆĆĆĆĂĂĂŔŔŔľľľĽĽĽĽĽĽżżżĂĂĂĆĆĆ´´´şşşĂĂĂÉÉÉÂÂÂľľľĚĚĚÝÝÝÉÉÉłłł­­­···¸¸¸´´´şşşÂÂÂÂÂÂĆĆĆŔŔŔ»»»ÉÉÉŘŘŘÍÍÍ´´´ŃŃѸ¸¸ŔŔŔÎÎÎÇÇÇĂĂĂÂÂÂÇÇÇĂĂĂĂĂĂÂÂÂÂÂÂĂĂĂÇÇÇĘĘĘĚĚĚÍÍÍÎÎÎÎÎÎĚĚĚÉÉÉÍÍÍŐŐŐŮŮŮĂĂĂŔŔŔÇÇÇÇÇÇĂĂĂŔŔŔľľľĆĆĆŔŔŔĆĆĆÇÇǸ¸¸···ŐŐŐŘŘŘłłłĽĽĽĽĽĽľľľżżżÂÂÂĹĹĹÇÇÇÇÇÇľľľŔŔŔ»»»ĽĽĽÎÎÎŰŰŰ×××ŇŇŇĐĐĐŮŮŮŔŔŔĽĽĽĐĐĐĘĘĘĂĂĂĘĘĘĚĚĚĹĹĹĘĘĘŐŐŐĂĂĂÉÉÉĂĂĂÉÉÉŮŮŮŮŮŮŘŘŘŇŇŇĂĂĂĚĚĚßßßÎÎÎĂĂĂÂÂÂÂÂÂÉÉÉĘĘĘÇÇÇÍÍÍÔÔÔĐĐĐĹĹĹÂÂÂÇÇÇ···ĽĽĽŕŕŕçççććććććëëëńńńďďďíííîîîďďďńńńňňňůůůîîîßßßŃŃŃŔŔŔľľľµµµ»»»ĂĂĂÉÉÉÍÍÍŇŇŇŘŘŘÝÝÝÜÜÜßßß×××ĘĘĘĐĐĐăăăóóóůůůöööńńńóóóîîîŕŕŕăăăęęęŕŕŕăăăĚĚĚĆĆĆĆĆĆĘĘĘĘĘĘĹĹĹÎÎÎĘĘĘĘĘĘĘĘĘÉÉÉÉÉÉÇÇÇÇÇÇÇÇÇÂÂÂÂÂÂĚĚĚßßßŮŮŮÎÎÎ×××ŇŇŇĚĚĚĚĚĚĐĐĐÔÔÔÔÔÔĐĐĐĐĐĐŇŇŇćććßßßęęęÝÝÝ»»»żżżÇÇÇĚĚĚÉÉÉĆĆĆĂĂĂÂÂÂżżż»»»¸¸¸ĽĽĽľľľĂĂĂĚĚĚŇŇŇÔÔÔĐĐĐĘĘĘÎÎÎÇÇÇĘĘĘÎÎÎĚĚĚĘĘĘĘĘĘÇÇÇĘĘĘŐŐŐŘŘŘŐŐŐŘŘŘ×××ĐĐĐÎÎÎÇÇÇŔŔŔĽĽĽÔÔÔÔÔÔĐĐĐÍÍÍÉÉÉĹĹĹĹĹĹĂĂĂĂĂĂĂĂĂĹĹĹĹĹĹĆĆĆĆĆĆĹĹĹŔŔŔŔŔŔĹĹĹĹĹĹĽĽĽ°°°µµµ´´´´´´µµµłłłłłłĽĽĽÉÉÉŐŐŐ¸¸¸ĽĽĽżżż»»»ĽĽĽÂÂÂĚĚĚŇŇŇÍÍÍĹĹĹĚĚĚŃŃŃĂĂĂłłłĚĚ̸¸¸ĘĘĘŃŃŃĂĂĂÂÂÂżżżŔŔŔĂĂĂĂĂĂĂĂĂĹĹĹĆĆĆÉÉÉĚĚĚÍÍÍĐĐĐÍÍÍÍÍÍĚĚĚĘĘĘŃŃŃŐŐŐŃŃŃżżżĆĆĆÎÎÎĐĐĐĚĚĚÇÇÇĹĹĹĹĹĹÉÉÉĂĂĂĹĹĹ»»»ĽĽĽŕŕŕççç»»»żżżŔŔŔÂÂÂŔŔŔĽĽĽşşşşşş»»»ĽĽĽĽĽĽµµµ¸¸¸ÇÇÇĐĐĐÎÎÎÎÎÎŇŇŇŮŮŮĐĐĐĘĘĘŘŘŘŐŐŐĂĂĂĹĹĹĆĆĆĹĹĹÇÇÇÔÔÔĂĂĂÂÂÂÂÂÂŃŃŃŃŃŃĐĐĐŇŇŇŘŘŘĘĘĘÇÇÇÝÝÝäääŃŃŃÉÉÉżżżĆĆĆĹĹĹľľľÉÉÉÔÔÔŃŃŃĂĂĂĂĂĂÇÇÇ»»»ĂĂĂâââęęęëëëíííóóóőőőëëëćććččččččëëëčččňňňóóóňňňńńńçççëëëëëëďďďńńńäääÔÔÔĘĘĘÍÍÍÔÔÔÎÎÎÔÔÔÎÎÎÍÍÍÝÝÝńńńőőőňňňřřříííďďďëëëÜÜÜŕŕŕçççŮŮŮçççŃŃŃĚĚĚĘĘĘÍÍÍĘĘĘżżżĹĹĹĘĘĘÉÉÉÉÉÉÇÇÇĆĆĆĆĆĆĹĹĹĹĹĹÂÂÂĂĂĂÇÇÇŮŮŮŰŰŰŃŃŃ×××ÔÔÔŃŃŃĐĐĐŃŃŃÔÔÔŇŇŇĐĐĐŃŃŃ×××ęęęÜÜÜçççßß߸¸¸ľľľÇÇÇĚĚĚÇÇÇÂÂÂżżżżżżżżżľľľĽĽĽ»»»ĂĂĂÍÍÍĐĐĐÍÍÍĘĘĘĚĚĚÎÎÎÎÎÎÇÇÇÍÍÍÔÔÔĐĐĐĚĚĚÉÉÉÂÂÂŃŃŃŮŮŮÔÔÔĘĘĘĘĘĘÍÍÍÔÔÔÝÝÝĘĘĘżżż»»»ŮŮŮŇŇŇÉÉÉĹĹĹĂĂĂĂĂĂÂÂÂÂÂÂŔŔŔŔŔŔÂÂÂÂÂÂĂĂĂĆĆĆĹĹĹĹĹĹÇÇÇĂĂĂşşş°°°¬¬¬ÎÎθ¸¸şşşÂÂÂĆĆĆĂĂĂŔŔŔŐŐŐÍÍÍÇÇÇĆĆĆĹĹĹÂÂÂĆĆĆÍÍÍßßßßßßŘŘŘŐŐŐ×××ĚĚĚÂÂÂĹĹŸ¸¸»»»ÉÉÉĚĚĚÂÂÂĂĂĂĆĆĆĹĹĹĂĂĂĹĹĹĆĆĆÇÇÇÉÉÉĚĚĚÍÍÍÎÎÎÎÎÎĘĘĘĚĚĚÎÎÎĐĐĐŐŐŐŇŇŇĹĹĹĹĹĹÎÎÎŇŇŇĐĐĐĐĐĐÔÔÔŐŐŐŇŇŇÎÎÎĹĹĹĹĹĹĂĂĂĹĹĹŰŰŰßßßĹĹĹĆĆĆÇÇÇĆĆĆŔŔŔşşş···¸¸¸ĽĽĽµµµ···µµµĽĽĽĘĘĘĚĚĚÉÉÉÍÍÍŇŇŇŐŐŐÜÜÜÔÔÔŰŰŰŰŰŰŔŔŔżżżşşşżżżĽĽĽĘĘĘÇÇÇĚĚĚĘĘĘ×××ÇÇÇĹĹĹĂĂĂŇŇŇÎÎÎĹĹĹŇŇŇÜÜÜŰŰŰŐŐŐÇÇÇÇÇÇĹĹĹľľľĚĚĚŇŇŇĐĐĐĆĆĆÇÇÇŔŔŔľľľÔÔÔęęęńńńńńńďďďóóóîîîŕŕŕßßßçççęęęîîîçççęęęćććęęęňňňíííëëëîîîňňňňňňęęęŰŰŰĚĚĚĂĂĂÂÂÂÍÍÍÇÇÇľľľĹĹĹÜÜÜęęęîîîňňňńńńííííííäääŘŘŘŰŰŰßßßŮŮŮÎÎÎĂĂĂĆĆĆĹĹĹĆĆĆĆĆĆŔŔŔÉÉÉÉÉÉÉÉÉÇÇÇĆĆĆĹĹĹĂĂĂÂÂÂÂÂÂÂÂÂĂĂĂŔŔŔŃŃŃŰŰŰŇŇŇŇŇŇÔÔÔŐŐŐŃŃŃŃŃŃŃŃŃŃŃŃĐĐĐÔÔÔŮŮŮâââŘŘŘăăăŐŐŐşşş¸¸¸żżżĹĹĹĆĆĆÂÂÂĽĽĽ»»»ľľľŔŔŔĂĂĂĹĹĹÉÉÉĘĘĘĘĘĘÉÉÉÇÇÇÇÇÇĘĘĘÎÎÎĆĆĆżżżÉÉÉ×××ÔÔÔĐĐĐÍÍÍĹĹĹĐĐĐŰŰŰŮŮŮÍÍÍÉÉÉÉÉÉÎÎÎŮŮŮÇÇÇżżż¸¸¸ŃŃŃÉÉÉÇÇÇÇÇÇĂĂĂÂÂÂŔŔŔżżżżżżľľľżżżżżżżżżÂÂÂżżżŔŔŔżżżłłł©©©´´´ÉÉɸ¸¸······»»»ŔŔŔĂĂĂÂÂÂżżżÎÎÎĐĐĐÍÍÍÇÇÇĂĂĂĂĂĂÎÎÎÜÜÜŇŇŇÉÉÉÂÂÂÍÍÍŇŇŇŔŔŔ»»»ĚĚĚĽĽĽÎÎÎĚĚĚĆĆĆľľľ¸¸¸ŔŔŔĽĽĽĂĂĂĹĹĹĆĆĆÉÉÉĚĚĚÍÍÍÎÎÎÎÎÎÍÍÍÇÇÇĚĚĚŃŃŃÔÔÔŘŘŘŃŃŃ»»»ÂÂÂĚĚĚĆĆĆĽĽĽ»»»ĆĆĆŃŃŃÎÎÎÇÇÇÂÂÂĹĹĹÇÇÇĂĂĂĂĂĂĂĂĂľľľĂĂĂĹĹĹĹĹĹżżż»»»żżżÉÉÉŇŇŇŻŻŻ´´´»»»ÇÇÇÔÔÔÎÎÎÉÉÉÎÎÎĐĐĐÎÎÎŕŕŕŐŐŐŘŘŘÜÜÜľľľ»»»µµµżżż´´´ĂĂĂÍÍÍ×××ĘĘĘĘĘĘľľľżżżĽĽĽĘĘĘŇŇŇÎÎÎŃŃŃŇŇŇÝÝÝßßßĐĐĐĚĚĚĆĆĆĂĂĂŃŃŃĐĐĐÍÍÍĘĘĘĚĚĚşşşľľľăăăóóóöööęęęçççëëëëëëăăăćććîîîëëëęęęëëëńńńęęęďďďůůůęęęÜÜÜÜÜÜÝÝÝäääîîîóóóëëëŘŘŘÇÇÇżżż»»»ľľľ×××ńńńîîîäääęęęçççíííëëëßßß××××××ŮŮŮßßßĚĚĚÇÇÇĐĐĐĚĚĚĆĆĆĆĆĆĂĂĂÎÎÎÉÉÉÇÇÇĆĆĆĹĹĹĂĂĂÂÂÂŔŔŔżżżŔŔŔĂĂĂ»»»ĘĘĘŰŰŰŇŇŇĐĐĐŇŇŇ×××ŇŇŇĐĐĐĐĐĐÎÎÎÎÎÎÔÔÔÜÜÜâââÜÜÜčččÔÔÔ···»»»ľľľĽĽĽĆĆĆ»»»şşşşşş···ľľľĹĹĹÂÂÂĂĂĂĘĘĘÍÍÍĚĚĚĚĚĚÎÎÎĚĚĚĆĆĆÉÉÉÍÍÍŃŃŃŃŃŃÎÎÎÍÍÍÎÎÎŃŃŃÝÝÝŃŃŃĚĚĚÔÔÔŐŐŐÎÎÎĚĚĚĐĐĐŃŃŃÜÜÜÔÔÔľľľÉÉÉÔÔÔĹĹĹĆĆĆÂÂÂĽĽĽ»»»żżżÂÂÂŔŔŔżżżÂÂÂĽĽĽĆĆĆŔŔŔ°°°­­­şşşżżż¸¸¸ĽĽĽµµµµµµ´´´°°°»»»ÍÍÍŃŃŃŔŔŔÍÍÍŮŮŮßßßÜÜÜ×××ÔÔÔÔÔÔĹĹĹĽĽĽşşşľľľŔŔŔżżżŔŔŔĆĆĆ»»»ĆĆĆĚĚĚÇÇÇŔŔŔŔŔŔÂÂÂĂĂĂżżżÍÍÍÇÇÇĘĘĘÎÎÎÇÇÇĘĘĘĐĐĐĘĘĘĚĚĚÉÉÉŘŘŘŇŇŇŐŐŐÉÉÉĘĘĘĐĐĐĹĹĹĹĹĹÍÍÍÉÉÉżżżĹĹĹŇŇŇĆĆĆÇÇÇÇÇÇĆĆĆĆĆĆĹĹĹĹĹĹÇÇÇĂĂĂĆĆĆĘĘĘĂĂø¸¸ŐŐŐĐĐĐÎÎÎÎÎÎÎÎÎÎÎÎĚĚĚÉÉÉÇÇÇÉÉÉĘĘĘÍÍÍÎÎÎŘŘŘÎÎÎŮŮŮ×××´´´ĽĽĽÜÜÜŘŘŘÎÎÎÂÂÂŔŔŔÇÇÇÉÉÉĹĹĹÂÂÂÔÔÔŃŃŃĂĂĂĘĘĘŐŐŐŃŃŃÉÉÉŐŐŐäääÍÍÍĘĘĘĂĂĂżżżÝÝÝÔÔÔŃŃŃÍÍÍĆĆĆ···çççëëëďďďčččďďďîîîęęęćććčččďďďňňňďďďőőőíííńńńîîîëëëćććŮŮŮŰŰŰ×××ŮŮŮâââíííňňňńńńęęęäääÇÇÇ­­­ľľľăăăćććŕŕŕčččíííçççîîîëëëßßßŘŘŘŘŘŘŐŐŐÍÍÍÎÎÎÉÉÉÍÍÍÎÎÎĆĆĆĹĹĹĆĆĆżżżĆĆĆÇÇÇÇÇÇĹĹĹÂÂÂŔŔŔÂÂÂĹĹĹżżżĂĂĂÂÂÂżżżÇÇÇŐŐŐ×××ÎÎÎÉÉÉĚĚĚŇŇŇ×××ŇŇŇÍÍÍÎÎÎÔÔÔäääŰŰŰâââ××׼ĽĽ¸¸¸ŔŔŔÂÂÂżżżşşşľľľÂÂÂżżżĂĂĂĆĆĆżżżÉÉÉĘĘĘÉÉÉÇÇÇĆĆĆÉÉÉĘĘĘÉÉÉÔÔÔŃŃŃÍÍÍÇÇÇĂĂĂĆĆĆÍÍÍÔÔÔÝÝÝÔÔÔĐĐĐŃŃŃŃŃŃÉÉÉÂÂÂÂÂÂĘĘĘÔÔÔ×××ŔŔŔşşşĘĘĘĚĚĚÉÉÉÉÉÉĆĆĆÂÂÂżżżŔŔŔĂĂĂĆĆĆÇÇÇÇÇÇľľľłłł°°°łłł¸¸¸ĽĽĽľľľµµµľľľĚĚĚĘĘĘşşş¸¸¸ĆĆĆÍÍÍĽĽĽĂĂĂĚĚĚĐĐĐĐĐĐĘĘĘĂĂĂżżżÉÉÉĹĹĹżżż»»»ĽĽĽŔŔŔĹĹĹĆĆĆŇŇŇŇŇŇÍÍÍĹĹĹÂÂÂĂĂĂĹĹĹÂÂÂĆĆĆĚĚĚĆĆĆĚĚĚŇŇŇÎÎÎĐĐĐĚĚĚŔŔŔÎÎÎŃŃŃŇŇŇĂĂĂÉÉÉĘĘĘĐĐĐĹĹĹÂÂÂĘĘĘŐŐŐŃŃŃĹĹĹÂÂÂÉÉÉÔÔÔÔÔÔÔÔÔŐŐŐÔÔÔÍÍÍĆĆĆŔŔŔÂÂÂĹĹĹÉÉÉĹĹĹĽĽĽ×××ŃŃŃĚĚĚĚĚĚÍÍÍĚĚĚĘĘĘĆĆĆĆĆĆÇÇÇÉÉÉÇÇÇĘĘĘŐŐŐÎÎÎŮŮŮŐŐŐµµµ»»»ŐŐŐ×××ŐŐŐÎÎÎĹĹĹŔŔŔÉÉÉŃŃŃŃŃŃ××××××ĐĐĐÍÍÍÔÔÔŇŇŇĘĘĘÎÎÎŕŕŕÍÍÍÍÍÍĂĂĂľľľŮŮŮŇŇŇĘĘĘĆĆĆżżżŔŔŔçççîîîëëëëëëńńńńńńďďďëëëëëëďďďďďďíííďďďŕŕŕÝÝÝÝÝÝâââćććÜÜÜÝÝÝäääâââÜÜÜŘŘŘÝÝÝçççëëëęęęŰŰŰĆĆĆÍÍÍääääääÝÝÝâââçççňňňňňňęęęÜÜÜ×××ŘŘŘÔÔÔĘĘĘĆĆĆĂĂĂÇÇÇÉÉÉÂÂÂĂĂĂÇÇÇĂĂĂÉÉÉÉÉÉÉÉÉÇÇÇĹĹĹÂÂÂŔŔŔŔŔŔÂÂÂĹĹĹÂÂÂżżżĆĆĆŐŐŐŮŮŮŐŐŐÔÔÔŃŃŃĐĐĐÎÎÎÉÉÉĆĆĆÍÍÍŐŐŐßßßŘŘŘŰŰŰÜÜÜĹĹŵµµĽĽĽĽĽĽĹĹĹĽĽĽşşşşşşşşşżżżĆĆĆĆĆĆÉÉÉĹĹĹĂĂĂĂĂĂĆĆĆÇÇÇĚĚĚĐĐĐŐŐŐĐĐĐÉÉÉÂÂÂŔŔŔĆĆĆÎÎÎÔÔÔŕŕŕŘŘŘŃŃŃĐĐĐŃŃŃŃŃŃŃŃŃŇŇŇ»»»ÇÇÇŐŐŐĆĆĆżżżĚĚĚÇÇÇÂÂÂĂĂĂĹĹĹĆĆĆĆĆĆÉÉÉÍÍÍŇŇŇŐŐŐĽĽĽşşşµµµµµµĽĽĽŔŔŔľľľ···´´´ŔŔŔĐĐĐÎÎÎľľľ»»»ÉÉÉŇŇŇÇÇÇ»»»şşşľľľÇÇÇÎÎÎŃŃŃÎÎÎŐŐŐÔÔÔÍÍÍÉÉÉĘĘĘÇÇÇŔŔŔŮŮŮŇŇŇÇÇÇÂÂÂĹĹĹĘĘĘĘĘĘĆĆĆŔŔŔĹĹĹĆĆĆŃŃŃÔÔÔŇŇŇŘŘŘĐĐĐŮŮŮÎÎÎżżżĂĂĂÇÇÇĐĐĐĹĹĹľľľ»»»ĂĂĂĐĐĐŰŰŰŰŰŰÎÎÎĆĆĆÇÇÇÇÇÇÇÇÇĚĚĚĐĐĐÔÔÔŐŐŐŃŃŃĘĘĘĹĹĹĆĆĆĹĹĹĂĂĂĽĽĽÔÔÔĐĐĐÉÉÉÉÉÉÉÉÉÇÇÇĆĆĆĂĂĂĂĂĂĆĆĆÇÇÇĘĘĘÍÍÍ×××ŃŃŃ×××ĐĐб±±´´´ŇŇŇŇŇŇŐŐŐŐŐŐÍÍÍĹĹĹĚĚĚŮŮŮÔÔÔĚĚĚŃŃŃ×××ŃŃŃŇŇŇŘŘŘÔÔÔÇÇÇÝÝÝÎÎÎŃŃŃĆĆĆľľľŇŇŇŇŇŇĐĐĐĘĘĘżżż×××îîîůůůńńńůůůőőőöööóóóëëëćććäääŕŕŕÜÜÜâââÜÜÜŕŕŕŰŰŰ×××ŘŘŘŘŘŘăăăÝÝÝââââââŮŮŮŮŮŮăăăëëëîîîńńńććććććííííííääääääëëëăăăăăăÜÜÜÔÔÔÔÔÔ×××ÎÎÎĂĂĂÇÇÇĆĆĆÉÉÉÇÇÇÂÂÂŔŔŔĹĹĹĂĂĂżżżĽĽĽşşşşşş»»»ľľľżżżŔŔŔĹĹĹĆĆĆĂĂĂĽĽĽżżżĚĚĚŇŇŇŇŇŇŇŇŇŃŃŃŃŃŃĐĐĐĘĘĘĆĆĆÇÇÇĚĚĚÔÔÔŘŘŘŮŮŮŕŕŕÎÎÎşşş»»»°°°´´´łłłłłłµµµşşşżżżĂĂĂĂĂĂÇÇÇÂÂÂżżżĹĹĹÇÇÇĹĹĹÇÇÇĚĚĚÍÍÍĚĚĚÉÉÉÉÉÉĘĘĘÍÍÍĐĐĐŃŃŃŇŇŇŐŐŐŘŘŘŮŮŮŘŘŘÔÔÔĘĘĘÂÂÂÍÍÍÍÍÍĆĆƸ¸¸ľľľÇÇÇĂĂĂÍÍÍÂÂÂĽĽĽ¸¸¸···±±±¬¬¬ŻŻŻµµµ­­­»»»ĆĆĆĹĹĹ»»»···ľľľĹĹĹĆĆĆÉÉÉÍÍÍÉÉÉŔŔŔĽĽĽľľľŔŔŔĚĚĚÍÍÍÎÎÎÎÎÎĚĚĚĆĆĆżżż»»»żżżĆĆĆĘĘĘĆĆĆĂĂĂÂÂÂľľľşşşŃŃŃĘĘĘĂĂĂÂÂÂĆĆĆĘĘĘÉÉÉĹĹĹÉÉÉÎÎÎ×××ŕŕŕŐŐŐŃŃŃÜÜÜ×××ŇŇŇĐĐĐÉÉÉĆĆĆĂĂĂĆĆĆÇÇÇĘĘĘĚĚĚŐŐŐŰŰŰŕŕŕâââÜÜÜŘŘŘÝÝÝÎÎÎĚĚĚĚĚĚÉÉÉĹĹĹĘĘĘÎÎÎĘĘĘÉÉÉÇÇÇżżżżżż¸¸¸ĐĐĐÎÎÎÉÉÉĆĆĆĆĆĆĂĂĂÂÂÂŔŔŔÂÂÂĹĹĹĆĆĆĚĚĚÎÎÎŐŐŐŃŃŃŐŐŐÎÎθ¸¸¸¸¸ÔÔÔÎÎÎÍÍÍŃŃŃŐŐŐÔÔÔŇŇŇÔÔÔÎÎÎĂĂĂÇÇÇÔÔÔŇŇŇÎÎÎÔÔÔŮŮŮÉÉÉŕŕŕŃŃŃÔÔÔĆĆĆŔŔŔÎÎÎŇŇŇÍÍÍĹĹĹ»»»âââčččőőőčččřřřăăăççççççâââÝÝÝÝÝÝÝÝÝÜÜÜŕŕŕŘŘŘÜÜÜÜÜÜÝÝÝßßßŮŮŮßßßÝÝÝßßßŕŕŕßßßÝÝÝÜÜÜŮŮŮŘŘŘăăăćććâââŕŕŕăăăÝÝÝŰŰŰääääääßßß×××ŇŇŇ×××ŰŰŰÔÔÔÉÉÉÉÉÉĘĘĘÍÍÍĚĚĚĆĆĆĂĂĂĹĹĹĹĹĹÉÉÉŔŔŔ···±±±´´´»»»ÂÂÂĆĆĆĆĆĆÇÇÇĂĂĂ»»»¸¸¸ľľľÂÂÂÂÂÂĆĆĆÉÉÉĚĚĚĐĐĐĐĐĐÎÎÎÎÎÎÎÎÎÍÍÍŘŘŘŰŰŰŕŕŕŐŐŐĘĘĘÇÇǵµµŻŻŻŻŻŻ¬¬¬ŻŻŻµµµ»»»żżżÂÂÂÂÂÂĽĽĽĽĽĽĂĂĂĹĹĹŔŔŔĽĽĽľľľĚĚĚÍÍÍÎÎÎĐĐĐŃŃŃĐĐĐÎÎÎÍÍÍÍÍÍŇŇŇŘŘŘŰŰŰŰŰŰŘŘŘĐĐĐÇÇÇĚĚĚÉÉÉŃŃŃ×××ŘŘŘÉÉÉłłłµµµĽĽĽ°°°ŻŻŻ···¸¸¸´´´ľľľŃŃŃÂÂÂşşşşşşÂÂÂŔŔŔ¸¸¸żżżĐĐĐĹĹĹÇÇÇÉÉÉĘĘĘĚĚĚÇÇÇżżżşşşľľľŔŔŔÂÂÂŔŔŔÂÂÂĘĘĘŐŐŐßßßľľľ»»»»»»ĽĽĽĽĽĽľľľĹĹĹÍÍÍÎÎÎĘĘĘĹĹĹĂĂĂĂĂĂĹĹĹĹĹĹĆĆĆĐĐĐÔÔÔ×××ŰŰŰÎÎÎĆĆĆĐĐĐÇÇÇĹĹĹÇÇÇÉÉÉĆĆĆĘĘĘÎÎÎ×××ŘŘŘĐĐĐŇŇŇÉÉÉĂĂĂĆĆĆĆĆĆĚĚĚŮŮŮÜÜÜŰŰŰŮŮŮÎÎÎŔŔŔĂĂĂÍÍÍĘĘĘŔŔŔÂÂÂĽĽĽĂĂĂľľľĐĐĐĐĐĐĆĆĆĹĹĹÂÂÂŔŔŔżżżżżżÂÂÂĂĂĂĹĹĹÇÇÇÉÉÉÎÎÎÍÍÍŇŇŇŇŇŇÉÉÉĘĘĘÎÎÎĘĘĘÇÇÇÉÉÉŇŇŇŰŰŰŐŐŐĘĘĘĐĐĐÉÉÉĆĆĆÎÎÎÔÔÔĘĘĘÉÉÉŘŘŘÍÍÍçççŐŐŐÔÔÔĆĆĆÉÉÉÎÎÎŇŇŇÉÉÉĂĂĂĹĹĹîîîęęęďďďâââëëëăăăćććăăăÜÜÜ×××××××××ŐŐŐÝÝÝŐŐŐŮŮŮŮŮŮŰŰŰÝÝÝŮŮŮŕŕŕßßßŐŐŐĐĐĐÔÔÔŮŮŮŘŘŘŇŇŇĐĐĐŰŰŰäääâââßßßäääßßßŰŰŰăăăęęęŕŕŕÔÔÔÍÍÍŃŃŃŐŐŐŃŃŃÉÉÉĆĆĆÉÉÉĘĘĘĘĘĘÇÇÇĹĹĹÂÂÂĂĂĂĽĽĽµµµ­­­ŞŞŞŻŻŻ···żżżĹĹĹÂÂÂĆĆĆĹĹĹżżżşşş¸¸¸¸¸¸¸¸¸ŐŐŐÔÔÔĐĐĐÍÍÍĘĘĘĘĘĘÇÇÇĆĆĆĚĚĚŐŐŐŘŘŘŮŮŮŘŘŘŮŮŮŘŘŘĚĚĚĆĆĆ···°°°łłł´´´···»»»´´´łłł···żżżĹĹĹĹĹĹÂÂÂŔŔŔŐŐŐŐŐŐÔÔÔŃŃŃÎÎÎÍÍÍĚĚĚĚĚĚÔÔÔŇŇŇŇŇŇŐŐŐ××××××ŘŘŘŰŰŰŘŘŘÂÂÂÉÉÉÍÍÍĂĂĂĆĆĆĐĐĐÜÜÜŰŰŰĐĐĐÎÎÎÔÔÔÎÎÎĽĽĽ¸¸¸ŔŔŔÉÉÉ»»»µµµľľľĆĆĆĆĆĆĂĂĂĂĂĂľľľĂĂĂĹĹĹĆĆĆĚĚĚĚĚĚĚĚĚŃŃŃ­­­»»»ÍÍÍŘŘŘŘŘŘŐŐŐŇŇŇÔÔÔÔÔÔÍÍÍĚĚĚĐĐĐĐĐĐĚĚĚĐĐĐŮŮŮÍÍÍÉÉÉĹĹĹĂĂĂĹĹĹĆĆĆÍÍÍŇŇŇŃŃŃÎÎÎÇÇÇÍÍÍÍÍÍÉÉÉÍÍÍÂÂÂŃŃŃĽĽĽľľľĚĚĚŰŰŰÎÎÎŃŃŃŮŮŮŕŕŕŰŰŰÉÉÉľľľŔŔŔżżżÉÉÉŕŕŕŐŐŐŐŐŐŮŮŮŃŃŃÂÂÂÇÇÇŃŃŃĘĘʵµµżżżľľľÎÎÎÇÇÇŇŇŇĐĐĐĂĂĂĂĂĂŔŔŔľľľĽĽĽżżżÂÂÂĹĹĹĆĆĆĘĘĘĘĘĘĘĘĘÉÉÉĚĚĚÍÍÍĘĘĘÍÍÍĂĂĂĆĆĆĹĹĹÂÂÂÇÇÇĐĐĐĐĐĐÉÉÉĘĘĘĚĚĚĆĆĆĚĚĚŐŐŐĐĐĐÎÎÎÝÝÝĐĐĐííí×××ŃŃŃĆĆĆÔÔÔŃŃŃŃŃŃĆĆĆÇÇÇŰŰŰřřřďďďíííăăăßßßŰŰŰÝÝÝÝÝÝŮŮŮŮŮŮßßßâââŕŕŕŕŕŕŘŘŘŮŮŮŇŇŇĚĚĚĚĚĚĚĚĚŘŘŘŮŮŮŮŮŮÜÜÜÜÜÜŘŘŘŇŇŇŐŐŐŮŮŮĚĚĚÔÔÔÔÔÔŇŇŇŐŐŐĐĐĐĘĘĘĐĐĐ×××ŇŇŇĐĐĐĐĐĐŇŇŇŃŃŃĘĘĘÂÂÂÉÉÉĚĚĚÇÇÇĂĂĂĂĂĂľľľ······±±±ŻŻŻ¬¬¬¬¬¬ŻŻŻ±±±´´´µµµ»»»żżżĹĹĹĂĂĂŔŔŔľľľ»»»¸¸¸ÂÂÂĹĹĹÇÇÇĘĘĘĐĐĐÔÔÔŇŇŇÍÍÍĚĚĚĚĚĚŃŃŃÔÔÔŘŘŘÜÜÜ×××ÔÔÔĐĐĐŇŇŇĚĚĚÇÇÇÉÉÉ······µµµ···şşşżżżÇÇÇĐĐĐŃŃŃÎÎÎŘŘŘŘŘŘŐŐŐĐĐĐĘĘĘÉÉÉĘĘĘÎÎÎŇŇŇĐĐĐŇŇŇŘŘŘŇŇŇÇÇÇżżżżżżâââŃŃŃŰŰŰŘŘŘÇÇÇÇÇÇĹĹĹŔŔŔ»»»»»»żżżĹĹĹĹĹĹľľľ···µµµ···ŔŔŔÇÇÇĹĹĹŔŔŔŔŔŔÂÂÂżżżĆĆĆĘĘĘĆĆĆŔŔŔÂÂÂĂĂĂÇÇÇŇŇŇĘĘĘÎÎÎŇŇŇŐŐŐÔÔÔŇŇŇÔÔÔ×××ŐŐŐŇŇŇŃŃŃŃŃŃĐĐĐÍÍÍĘĘĘÉÉÉÉÉÉĂĂĂŔŔŔĹĹĹĘĘĘĚĚĚĐĐĐŐŐŐ×××ŐŐŐÇÇÇĘĘĘŇŇŇŃŃŃŇŇŇÍÍÍÉÉÉĂĂĂŇŇŇ×××ÎÎα±±ŔŔŔßßßŐŐŐĐĐĐŔŔŔĽĽĽŔŔŔ»»»ÂÂÂÜÜÜ×××ŃŃŃÔÔÔÍÍÍżżżĹĹĹÉÉÉşşşľľľÉÉÉĆĆĆŐŐŐĚĚĚĐĐĐÎÎÎŔŔŔĹĹĹŔŔŔĽĽĽĽĽĽżżżĂĂĂĆĆĆÇÇÇÍÍÍĚĚĚÇÇÇĹĹĹÂÂÂŔŔŔÂÂÂŔŔŔľľľżżżżżżľľľľľľÂÂÂĆĆĆÉÉÉĹĹĹĆĆĆÇÇÇÉÉÉĐĐĐŐŐŐŮŮŮÝÝÝÍÍÍíííÔÔÔÍÍÍĆĆĆßßßÔÔÔÎÎÎĂĂĂÇÇÇäääëëëćććÝÝÝăăăŐŐŐâââäääâââÝÝÝÝÝÝßßßÝÝÝŮŮŮäääŇŇŇĚĚĚÇÇÇĘĘĘÍÍÍĹĹĹĆĆĆŇŇŇäääëëëŕŕŕÔÔÔÔÔÔ××××××ÔÔÔ××××××ŘŘŘ×××ŃŃŃÍÍÍĐĐĐÍÍÍÎÎÎŇŇŇŐŐŐ×××ÔÔÔÎÎÎĘĘĘĚĚĚĚĚĚÂÂÂĽĽĽŔŔŔľľľ···¸¸¸ÇÇÇĆĆĆĹĹĹŔŔŔ»»»µµµłłłłłłłłł¸¸¸żżżĂĂĂĹĹĹŔŔŔĽĽĽşşş¸¸¸ľľľĂĂĂÉÉÉŃŃŃ×××ŇŇŇÉÉÉĘĘĘÂÂÂĚĚĚŇŇŇŘŘŘ×××ÉÉÉÍÍÍŃŃŃŐŐŐĐĐĐÎÎÎŐŐŐŇŇŇÍÍÍĐĐĐĘĘĘĘĘĘÇÇÇĹĹĹĚĚĚ×××ŘŘŘŇŇŇÔÔÔŐŐŐŐŐŐĐĐĐĘĘĘÉÉÉĚĚĚĐĐĐ×××ŃŃŃŇŇŇŮŮŮÔÔÔĹĹĹľľľÂÂÂŮŮŮŐŐŐŘŘŘŇŇŇŐŐŐŘŘŘĹĹŵµµľľľŔŔŔĽĽĽ···»»»ĆĆĆĘĘĘĆĆĆĹĹĹľľľ»»»ľľľÂÂÂŔŔŔľľľľľľĽĽĽÂÂÂŔŔŔżżżĆĆĆĹĹĹÂÂÂÉÉÉÍÍÍÎÎÎŇŇŇ×××ŮŮŮ×××ĐĐĐĘĘĘĘĘĘĘĘĘĆĆĆżżżŔŔŔÉÉÉĘĘĘĆĆĆÉÉÉÂÂÂŔŔŔÉÉÉÎÎÎÍÍÍÇÇÇĹĹĹŇŇŇ×××ĹĹĹżżżÂÂÂĽĽĽľľľŔŔŔĂĂĂĚĚĚÔÔÔĂĂĂĂĂĂżżżĘĘĘÇÇÇĆĆĆĆĆĆľľľĂĂĂĚĚĚÂÂÂĂĂĂßßßŰŰŰĐĐĐÎÎÎÇÇÇľľľÉÉÉĚĚĚ···ĐĐĐ×××ÍÍÍ×××ÇÇÇÉÉÉĘĘĘżżżĹĹĹŔŔŔĽĽĽ»»»żżżĂĂĂĆĆĆÇÇÇÇÇÇĆĆĆÂÂÂŔŔŔĽĽĽşşşľľľĽĽĽżżż¸¸¸µµµşşş»»»şşşľľľĆĆĆĆĆĆĆĆĆĘĘĘÉÉÉĆĆĆŇŇŇŰŰŰŇŇŇÇÇÇëëëŃŃŃÉÉÉÇÇÇççç×××ĚĚĚÎÎÎŃŃŃďďďăăăŕŕŕŮŮŮďďďßßßßßßâââŕŕŕßßßßßßŕŕŕÜÜÜŐŐŐÍÍÍĹĹĹĘĘĘĘĘĘÍÍÍĐĐĐÉÉÉÎÎÎżżżÎÎÎÎÎÎĹĹĹÎÎÎçççëëëŰŰŰ×××ÔÔÔÔÔÔ×××ÔÔÔĐĐĐÍÍÍÎÎÎŐŐŐŃŃŃĘĘĘĹĹĹÂÂÂĂĂĂÉÉÉÍÍÍĂĂĂĂĂĂşşş¸¸¸ĂĂĂÇÇÇĆĆĆĘĘĘĂĂĂĂĂĂĹĹĹĂĂĂÂÂÂÂÂÂĹĹĹÉÉÉŻŻŻłłłşşşŔŔŔÂÂÂľľľşşşµµµ»»»ĽĽĽĽĽĽľľľÇÇÇŇŇŇÔÔÔÎÎÎŃŃŃÉÉÉÎÎÎÎÎÎ×××ßßßÔÔÔÔÔÔĐĐĐŃŃŃÔÔÔŮŮŮÝÝÝÝÝÝŰŰŰ×××ŇŇŇŇŇŇŇŇŇŐŐŐŮŮŮŰŰŰŮŮŮŘŘŘ×××ÎÎÎÍÍÍŇŇŇÔÔÔÎÎÎÍÍÍŃŃŃÎÎÎŐŐŐŐŐŐÍÍÍĹĹĹÂÂÂĂĂĂĂĂĂÂÂÂÇÇÇÎÎÎŃŃŃĐĐĐÎÎÎÍÍÍÍÍÍĚĚĚĚĚĚĚĚĚĘĘĘÇÇÇĂĂĂżżżĽĽĽżżżľľľľľľĽĽĽĽĽĽĽĽĽľľľľľľŔŔŔżżżÂÂÂĆĆĆÇÇÇĆĆĆÉÉÉÎÎÎÍÍÍŇŇŇşşş¸¸¸żżżÇÇÇŘŘŘÇÇÇĹĹĹÉÉÉĚĚĚÉÉÉĂĂĂŔŔŔĹĹĹÉÉÉÂÂÂÉÉÉÉÉÉŐŐŐŐŐŐĂĂĂÉÉÉŘŘŘżżżÉÉÉŇŇŇŘŘŘ×××ÔÔÔŇŇŇŇŇŇÝÝÝŃŃŃĹĹĹŔŔŔŔŔŔŔŔŔÂÂÂĆĆĆĹĹĹÂÂÂÂÂÂĹĹĹĂĂĂĂĂĂÍÍÍŘŘŘŐŐŐŃŃŃÇÇÇĽĽĽĆĆĆÇÇÇżżż×××ĚĚĚĐĐĐĘĘĘĆĆĆÉÉÉĹĹĹżżżÂÂÂĂĂĂÂÂÂÂÂÂÂÂÂĹĹĹÇÇÇĘĘĘĚĚĚÇÇÇĹĹĹŔŔŔľľľ»»»şşşşşşşşşşşşşşşşşşşşş»»»ĽĽĽżżżżżżÂÂÂÇÇÇÍÍÍÉÉÉĹĹĹŇŇŇŰŰŰĐĐĐŇŇŇŇŇŇââ⼼ĽĹĹĹŕŕŕÜÜÜÎÎÎÉÉÉâââëëë×××ßßßčččŮŮŮäääÍÍÍĐĐĐĚĚĚÔÔÔßßßíííĐĐĐĘĘĘÍÍÍÍÍÍÍÍÍÎÎÎÍÍÍÍÍÍĚĚĚĚĚĚÉÉÉÉÉÉĘĘĘĘĘĘĘĘĘÉÉÉÇÇÇĆĆĆÉÉÉâââÝÝÝĐĐĐĘĘĘĐĐĐ×××ÂÂÂĽĽĽÇÇÇĆĆĆĂĂĂĘĘĘÉÉÉÂÂÂĂĂĂľľľĘĘĘŃŃŃĚĚĚĘĘĘÎÎÎĐĐĐĚĚĚĂĂĂĂĂĂÂÂÂÂÂÂÂÂÂĂĂĂĂĂĂĹĹĹĂĂĂĂĂĂ´´´µµµľľľÂÂÂÇÇÇ···ĽĽĽĆĆĆĂĂĂżżżÇÇÇÎÎÎÎÎÎĐĐĐĐĐĐÇÇÇÍÍÍÍÍÍÔÔÔŰŰŰŇŇŇÔÔÔÔÔÔŇŇŇŃŃŃŃŃŃŐŐŐŮŮŮÜÜÜßßßŰŰŰŐŐŐÎÎÎĚĚĚÍÍÍÔÔÔŮŮŮÝÝÝÔÔÔŃŃŃĚĚĚĘĘĘĚĚĚŃŃŃÔÔÔŐŐŐŇŇŇŐŐŐŇŇŇÇÇÇľľľľľľŔŔŔĂĂĂŃŃŃŇŇŇŇŇŇÎÎÎÉÉÉĹĹĹÂÂÂŔŔŔĂĂĂĂĂĂÂÂÂÂÂÂŔŔŔľľľĽĽĽ»»»żżżľľľľľľĽĽĽĽĽĽĽĽĽľľľľľľÂÂÂŔŔŔŔŔŔĹĹĹĹĹĹĹĹĹÉÉÉĐĐĐ´´´ĹĹĹşşşşşş¸¸¸ĽĽĽŃŃŃĘĘĘÉÉÉĆĆĆĹĹĹĹĹĹÇÇÇÉÉÉÉÉÉÉÉÉĚĚĚÔÔÔŔŔŔ¸¸¸ĆĆĆÔÔÔŃŃŃľľľŐŐŐŇŇŇÍÍÍÉÉÉÉÉÉÎÎÎŮŮŮâââŮŮŮÎÎÎĂĂĂżżżĽĽĽşşşşşşĽĽĽÂÂÂŔŔŔŔŔŔŔŔŔżżżŔŔŔÉÉÉŃŃŃŰŰŰŇŇŇĂĂĂľľľÇÇÇĂĂĂĽĽĽÍÍÍĚĚĚÍÍÍÇÇÇĹĹĹĘĘĘĆĆĆŔŔŔÂÂÂŔŔŔŔŔŔÂÂÂÂÂÂĹĹĹĆĆĆÉÉÉĘĘĘĹĹĹĂĂĂŔŔŔĽĽĽşşş¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸şşş»»»ľľľżżżŔŔŔĂĂĂĆĆĆĚĚĚĘĘĘĆĆĆŃŃŃŮŮŮŐŐŐŃŃŃÔÔÔŕŕŕÉÉÉÔÔÔÜÜÜŐŐŐÍÍÍĆĆĆçççëëëŰŰŰŕŕŕßßßĐĐĐŮŮŮŃŃŃÔÔÔÎÎÎÎÎÎŇŇŇßßßĚĚĚĚĚĚĐĐĐĐĐĐĐĐĐĐĐĐĐĐĐÎÎÎÎÎÎÎÎÎÉÉÉÉÉÉĘĘĘĘĘĘÉÉÉÇÇÇĆĆĆĹĹĹĽĽĽĘĘĘĹĹĹżżżĽĽĽżżżÇÇÇľľľĹĹĹÉÉÉÇÇÇĆĆĆÉÉÉÂÂÂŔŔŔÉÉÉŔŔŔĘĘĘÎÎÎÇÇÇĂĂĂÇÇÇÉÉÉĆĆĆÇÇÇĹĹĹżżż»»»»»»żżżĂĂĂĆĆĆĆĆĆÉÉÉşşşµµµ´´´¸¸¸ĆĆĆÂÂÂĂĂĂÉÉÉĹĹĹżżżĂĂĂĂĂĂÂÂÂĹĹĹÍÍÍÉÉÉĚĚĚĘĘĘÎÎÎÔÔÔĐĐĐŃŃŃ×××ÔÔÔŃŃŃÎÎÎĐĐĐÔÔÔŮŮŮÝÝÝŐŐŐÔÔÔÔÔÔŐŐŐ××××××ÔÔÔŃŃŃĐĐĐŇŇŇÎÎÎĆĆĆÉÉÉŇŇŇŐŐŐĐĐĐÔÔÔŰŰŰŰŰŰĐĐĐĂĂĂĽĽĽşşş···ŇŇŇŃŃŃÎÎÎÉÉÉĂĂĂŔŔŔżżżŔŔŔĽĽĽ»»»»»»»»»şşş»»»»»»»»»żżżľľľľľľĽĽĽĽĽĽľľľľľľżżżĂĂĂŔŔŔżżżÂÂÂÂÂÂÂÂÂÉÉÉĐĐĐ°°°ĹĹĹĹĹĹÇÇÇÂÂÂŔŔŔÔÔÔŇŇŇÍÍÍĘĘĘÇÇÇĆĆĆĘĘĘÎÎÎŃŃŃŃŃŃŘŘŘŐŐŐÇÇÇĘĘĘÍÍÍÂÂÂĂĂĂÉÉÉÉÉÉĆĆĆÂÂÂżżżĽĽĽżżżÂÂÂĆĆĆĹĹĹżżż»»»»»»»»»···¸¸¸»»»ĽĽĽżżżżżż»»»¸¸¸ĽĽĽÂÂÂĆĆĆ×××ŃŃŃżżżÂÂÂĚĚĚŔŔŔ¸¸¸ľľľĐĐĐÎÎÎĆĆĆÂÂÂĹĹĹĂĂĂŔŔŔŔŔŔľľľżżżŔŔŔĂĂĂĹĹĹĹĹĹĆĆĆĆĆĆŔŔŔŔŔŔľľľĽĽĽşşş¸¸¸···µµµ···¸¸¸¸¸¸şşşĽĽĽżżżŔŔŔÂÂÂĹĹĹĹĹĹĘĘĘĚĚĚÉÉÉÎÎÎŘŘŘÜÜÜÔÔÔ×××ŮŮŮŃŃŃŕŕŕÔÔÔÍÍÍÍÍÍľľľęęęçççÜÜÜăăăŐŐŐÉÉÉŇŇŇŐŐŐ×××ŇŇŇÎÎÎÍÍÍŐŐŐÉÉÉÎÎÎŇŇŇŇŇŇŃŃŃŃŃŃŃŃŃŃŃŃŃŃŃŃŃŃĘĘĘĘĘĘĘĘĘÉÉÉÇÇÇĆĆĆĂĂĂĂĂĂĘĘĘÉÉÉÂÂÂĹĹĹĂĂĂżżżĆĆĆÉÉÉÉÉÉÍÍÍÇÇÇľľľŔŔŔĆĆĆĹĹĹĂĂĂżżżĆĆĆĆĆĆľľľ¸¸¸»»»»»»¸¸¸ľľľşşşµµµ±±±°°°łłł···şşşÂÂÂÉÉÉ»»»±±±°°°ŔŔŔÉÉÉŔŔŔĂĂĂŔŔŔżżżŔŔŔżżżżżżĘĘĘÍÍÍĚĚĚĚĚĚÉÉÉÉÉÉĚĚĚĘĘĘÍÍÍŐŐŐŐŐŐ×××ÔÔÔŇŇŇŃŃŃÔÔÔ×××ŘŘŘŘŘŘŮŮŮÜÜÜÝÝÝŰŰŰŐŐŐŃŃŃĚĚĚŃŃŃŃŃŃÍÍÍÍÍÍĐĐĐĘĘĘŔŔŔ»»»ÇÇÇŇŇŇÔÔÔŃŃŃŃŃŃŃŃŃĐĐĐĚĚĚĘĘĘÇÇÇĂĂĂŔŔŔżżżŔŔŔŔŔŔĽĽĽ»»»şşş¸¸¸¸¸¸»»»ĽĽĽľľľľľľľľľĽĽĽĽĽĽĽĽĽľľľżżżżżżÂÂÂżżżĽĽĽżżżżżżŔŔŔÇÇÇĐĐи¸¸ĆĆĆÇÇÇĚĚĚÇÇÇÂÂÂÍÍÍÍÍÍŔŔŔÉÉÉŇŇŇ×××ŐŐŐŐŐŐŮŮŮÜÜÜ´´´ĘĘĘÇÇÇĂĂĂĆĆĆÎÎÎÝÝÝâââĹĹĹĹĹĹĂĂĂĂĂĂÂÂÂŔŔŔľľľĽĽĽµµµłłł´´´¸¸¸¸¸¸···¸¸¸»»»şşşŔŔŔŔŔŔşşşµµµşşşľľľĽĽĽÇÇÇĚĚĚ»»»ŔŔŔĘĘĘ»»»°°°ĐĐĐÎÎÎÉÉÉÂÂÂżżżľľľľľľŔŔŔĽĽĽľľľŔŔŔĂĂĂĂĂĂĂĂĂĂĂĂÂÂÂľľľľľľĽĽĽ»»»şşş···µµµ´´´······¸¸¸şşşĽĽĽżżżÂÂÂĂĂĂĹĹĹĹĹĹÉÉÉÍÍÍĘĘĘĚĚĚ×××ăăăÔÔÔŰŰŰŃŃŃÍÍÍßßßÉÉÉÇÇÇĘĘĘ···čččŕŕŕÝÝÝćććĐĐĐĘĘĘŐŐŐŘŘŘÔÔÔÔÔÔĐĐĐĐĐĐŐŐŐÍÍÍĐĐĐŃŃŃŃŃŃĐĐĐĐĐĐĐĐĐĐĐĐŃŃŃŃŃŃĚĚĚĚĚĚĘĘĘÉÉÉÇÇÇĹĹĹĂĂĂĂĂĂÉÉÉĹĹĹÂÂÂÇÇÇÇÇÇĹĹĹĆĆĆĘĘĘÉÉÉĆĆĆľľľ¸¸¸ľľľĆĆĆĹĹĹżżżÂÂÂÇÇÇÇÇÇŔŔŔ»»»»»»şşş···¬¬¬­­­±±±´´´µµµ···µµµµµµµµµżżżĆĆĆĹĹĹşşş±±±¸¸¸ÂÂÂÉÉÉĘĘĘĹĹĹĂĂĂÂÂÂşşşşşşĆĆĆÍÍÍÎÎÎĚĚĚÉÉÉĆĆĆĹĹĹÇÇÇÇÇÇĐĐĐŇŇŇŐŐŐŐŐŐÔÔÔŇŇŇÔÔÔŐŐŐŰŰŰÜÜÜßßßăăăăăăŕŕŕŮŮŮÔÔÔĚĚĚÍÍÍÎÎÎĐĐĐĐĐĐĚĚĚĹĹĹľľľĆĆĆÎÎÎÔÔÔĐĐĐĚĚĚĚĚĚÎÎÎÎÎÎĚĚĚĘĘĘĆĆĆÂÂÂżżżĽĽĽşşş¸¸¸ĽĽĽ»»»¸¸¸······¸¸¸»»»ĽĽĽĽĽĽĽĽĽĽĽĽĽĽĽĽĽĽľľľľľľżżżŔŔŔĽĽĽĽĽĽľľľżżżŔŔŔÇÇÇĐĐĐŔŔŔĘĘĘĚĚĚĐĐĐĘĘĘĂĂĂĘĘĘÎÎÎĐĐĐŃŃŃĐĐĐÉÉÉŔŔŔĽĽĽżżżĹĹĹÂÂÂĘĘĘĂĂĂÉÉÉĐĐĐÇÇÇĂĂĂ»»»ĆĆĆÂÂÂşşş´´´´´´···ĽĽĽżżż···´´´´´´······´´´´´´¸¸¸»»»ÂÂÂĂĂĂĽĽĽ···¸¸¸şşş¸¸¸»»»ÇÇÇşşş···żżżÂÂÂĂĂĂłłłŔŔŔĹĹĹĚĚĚĘĘĘĂĂĂľľľľľľľľľ»»»ĽĽĽżżżÂÂÂĂĂĂĂĂĂŔŔŔŔŔŔĽĽĽĽĽĽ»»»»»»şşş¸¸¸···µµµ···¸¸¸¸¸¸»»»ĽĽĽżżżÂÂÂĂĂĂĹĹĹĹĹĹÇÇÇĚĚĚÍÍÍĚĚĚŐŐŐäääÎÎÎŮŮŮĚĚĚĆĆĆŮŮŮĹĹĹĹĹĹżżżĽĽĽçççŰŰŰÝÝÝćććÎÎÎÎÎÎŘŘŘŐŐŐĘĘĘĚĚĚÇÇÇÍÍÍÔÔÔĐĐĐĐĐĐĘĘĘĚĚĚĚĚĚĚĚĚÍÍÍÎÎÎÎÎÎĐĐĐÍÍÍĚĚĚĘĘĘÇÇÇĆĆĆĹĹĹĂĂĂĂĂĂľľľżżżĂĂĂĂĂĂĆĆĆÇÇÇĹĹĹĂĂĂĹĹŵµµ´´´ŔŔŔÂÂÂşşşľľľĚĚĚĐĐĐÔÔÔŐŐŐŃŃŃÎÎÎĚĚĚÉÉÉĹĹĹÇÇÇÉÉÉĘĘĘÉÉÉĹĹĹĽĽĽµµµ°°°°°°´´´ŔŔŔÇÇǸ¸¸µµµĽĽĽĘĘĘĚĚĚÉÉÉÇÇÇĆĆĆżżżżżżĚĚĚĚĚĚÎÎÎÉÉÉĘĘĘÇÇÇĂĂĂÇÇÇĹĹĹĚĚĚĚĚĚÍÍÍÎÎÎĐĐĐÔÔÔŘŘŘŰŰŰŘŘŘŮŮŮÜÜÜŕŕŕâââßßßŮŮŮŐŐŐĐĐĐÍÍÍĘĘĘĘĘĘĚĚĚĘĘĘÉÉÉÇÇÇĽĽĽÇÇÇĐĐĐÎÎÎĚĚĚĚĚĚÍÍÍĚĚĚÉÉÉĆĆĆĂĂĂŔŔŔľľľ»»»···´´´¸¸¸···´´´łłłłłł´´´µµµ···»»»»»»şşş»»»»»»ĽĽĽľľľżżżľľľĽĽĽľľľĂĂĂĹĹĹĆĆĆĚĚĚŇŇŇĂĂĂÉÉÉĐĐĐŇŇŇĘĘĘÂÂÂĘĘĘŐŐŐÔÔÔĐĐĐĘĘĘĆĆĆÇÇÇĚĚĚÎÎÎĐĐĐĐĐĐĘĘĘĹĹĹÔÔÔŃŃŃ´´´łłłÂÂÂłłłµµµ¸¸¸ĽĽĽŔŔŔĹĹĹÉÉÉĚĚĚľľľ¸¸¸µµµ···¸¸¸···¸¸¸ĽĽĽĽĽĽÂÂÂĂĂĂżżżşşş¸¸¸·········ĂĂĂľľľłłłµµµżżżÇÇÇŔŔŔłłłşşşÇÇÇÎÎÎÉÉÉĹĹĹ»»»»»»ĽĽĽżżżÂÂÂÂÂÂÂÂÂŔŔŔżżżĽĽĽĽĽĽ»»»şşşşşş¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸şşş»»»ľľľżżżÂÂÂĂĂĂĹĹĹĆĆĆÇÇÇĘĘĘÍÍÍÍÍÍŇŇŇâââÍÍÍÔÔÔĚĚĚĆĆĆŘŘŘÇÇÇĂĂĂ´´´ĘĘĘćććŘŘŘÝÝÝăăăÍÍÍÎÎÎŐŐŐĐĐĐżżżÂÂÂľľľĹĹĹÉÉÉĘĘĘĘĘĘĂĂĂĹĹĹĆĆĆÉÉÉĚĚĚĚĚĚÍÍÍÍÍÍĘĘĘÉÉÉÇÇÇĆĆĆĹĹĹĂĂĂĂĂĂĂĂĂĹĹĹÇÇÇÍÍÍĹĹĹŔŔŔĹĹĹľľľşşş¸¸¸łłł»»»ĂĂĂľľľ¸¸¸ĆĆĆŐŐŐ×××ŘŘŘŰŰŰŮŮŮŘŘŘÔÔÔĐĐĐÍÍÍÍÍÍÎÎÎÎÎÎÎÎÎÎÎÎĚĚĚÉÉÉÇÇǸ¸¸±±±şşşÂÂÂĂĂĂĽĽĽµµµľľľĂĂĂÉÉÉÇÇÇÇÇÇĚĚĚÉÉÉÉÉÉŃŃŃÇÇÇĚĚĚĆĆĆĘĘĘĘĘĘĆĆĆĘĘĘĹĹĹÉÉÉÇÇÇÇÇÇÉÉÉÍÍÍŃŃŃÔÔÔŐŐŐŰŰŰŐŐŐÎÎÎĚĚĚÎÎÎÔÔÔŮŮŮÜÜÜÔÔÔŐŐŐĐĐĐÇÇÇÇÇÇÎÎÎĐĐĐĘĘʵµµĂĂĂĐĐĐŇŇŇĐĐĐÎÎÎÍÍÍĘĘĘĹĹĹÂÂÂżżżľľľľľľĽĽĽşşş···´´´łłłłłł±±±±±±łłł´´´µµµ¸¸¸¸¸¸¸¸¸şşşşşş»»»ĽĽĽľľľľľľľľľĂĂĂĘĘĘÍÍÍÍÍÍŃŃŃ×××ÂÂÂżżżĹĹĹĚĚĚÇÇÇŔŔŔÂÂÂĚĚ̸¸¸»»»ŔŔŔĆĆĆĘĘĘÇÇÇĂĂĂľľľĹĹĹŘŘŘĚĚ̸¸¸´´´ĽĽĽĐĐĐŐŐŐĐĐĐ×××ÝÝÝßßßÜÜÜŐŐŐŃŃŃÎÎÎĘĘĘŔŔŔ¸¸¸¸¸¸şşş»»»ľľľÂÂÂľľľżżżÂÂÂĂĂĂĽĽĽµµµ´´´···¸¸¸żżżÇÇÇŔŔŔ¸¸¸ĽĽĽÂÂÂĘĘĘĽĽĽ···ĽĽĽĹĹĹĆĆĆÉÉÉĆĆĆ»»»ĽĽĽľľľżżżŔŔŔÂÂÂŔŔŔŔŔŔżżżľľľĽĽĽ»»»şşşşşşşşş»»»ĽĽĽşşşşşş»»»»»»ľľľżżżŔŔŔÂÂÂĂĂĂÉÉÉÇÇÇÉÉÉÎÎÎÎÎÎŃŃŃÜÜÜ×××ĐĐĐĘĘĘÉÉÉŘŘŘĘĘĘĆĆƵµµ×××ŕŕŕ×××ÝÝÝŕŕŕÎÎÎÎÎÎÎÎÎĆĆƸ¸¸ÇÇÇÂÂÂĹĹĹżżżżżżľľľĽĽĽżżżĂĂĂÇÇÇĘĘĘĚĚĚĚĚĚĚĚĚĆĆĆĹĹĹĂĂĂŔŔŔŔŔŔŔŔŔŔŔŔŔŔŔĹĹĹĂĂĂĆĆƸ¸¸±±±µµµŻŻŻłłł···ĽĽĽÂÂÂżżż»»»ÉÉÉ×××ŐŐŐŘŘŘŘŘŘŘŘŘŘŘŘ×××ŇŇŇĐĐĐÍÍÍÎÎÎÎÎÎÎÎÎÍÍÍÍÍÍĚĚĚĚĚĚĘĘĘĂĂĂ´´´şşşŔŔŔĂĂĂżżż¸¸¸ĹĹĹÇÇÇÎÎÎĚĚĚÇÇÇĘĘĘÇÇÇĂĂĂĹĹĹĹĹĹĘĘĘĂĂĂĘĘĘÍÍÍÉÉÉÎÎÎÇÇÇÇÇÇÇÇÇÇÇÇÉÉÉĚĚĚÍÍÍĘĘĘÉÉÉÍÍÍĘĘĘÉÉÉÉÉÉÍÍÍĐĐĐŇŇŇŇŇŇŘŘŘßßßŮŮŮÉÉÉÇÇÇŇŇŇŃŃŃĹĹĹÇÇÇĐĐĐÔÔÔĐĐĐĘĘĘĘĘĘĘĘĘĘĘĘÇÇÇĂĂĂľľľ»»»»»»şşş¸¸¸µµµłłłłłłłłłłłł´´´µµµ···¸¸¸¸¸¸¸¸¸¸¸¸¸¸¸şşş»»»ĽĽĽľľľľľľŔŔŔÇÇÇĐĐĐÔÔÔŇŇŇŐŐŐŮŮŮŇŇŇĹĹĹĂĂĂÍÍÍŇŇŇÍÍÍĹĹĹĆĆĆĹĹĹÇÇÇĘĘĘÉÉÉÇÇÇĚĚĚŐŐŐßßßŔŔŔżżżŻŻŻ···ĘĘĘÍÍÍĚĚĚĹĹĹÉÉÉÉÉÉÉÉÉÇÇÇÉÉÉĐĐĐÜÜÜćććÜÜÜÎÎÎŔŔŔ»»»şşş¸¸¸şşşĽĽĽľľľĽĽĽŔŔŔĹĹĹľľľ´´´±±±µµµ···»»»ŇŇŇŇŇŇĂĂĂ»»»¸¸¸ĘĘĘĐĐĐĽĽĽ´´´···ĽĽĽÇÇÇÇÇÇ»»»ľľľľľľżżżŔŔŔŔŔŔŔŔŔŔŔŔżżżżżżľľľ»»»şşşşşş»»»ĽĽĽľľľ»»»»»»»»»ĽĽĽĽĽĽżżżŔŔŔÂÂÂÂÂÂĘĘĘÇÇÇĆĆĆÎÎÎĐĐĐĐĐĐŘŘŘäääÎÎÎÉÉÉÇÇÇŐŐŐĚĚĚĘĘĘżżżŮŮŮŮŮŮÔÔÔÝÝÝßßßŇŇŇĐĐĐÍÍÍľľľ¸¸¸ŇŇŇĐĐĐĚĚĚ»»»···´´´¸¸¸ĽĽĽÂÂÂÇÇÇĚĚĚÍÍÍĚĚĚĚĚĚÂÂÂŔŔŔżżżľľľĽĽĽľľľľľľżżżľľľ···»»»°°°¬¬¬±±±±±±żżżĹĹĹľľľĽĽĽľľľĹĹĹŘŘŘŕŕŕÔÔÔÝÝÝÜÜÜŮŮŮŮŮŮ×××ŐŐŐŇŇŇŃŃŃÍÍÍÎÎÎĐĐĐĐĐĐĐĐĐÎÎÎĚĚĚĘĘĘÉÉÉ···ľľľĂĂĂĹĹĹŔŔŔ···ĆĆĆżżżÉÉÉÇÇÇĂĂĂÉÉÉĚĚĚĆĆĆĹĹĹĆĆĆĹĹĹĹĹĹÉÉÉÍÍÍĐĐĐÍÍÍÉÉÉÍÍÍÉÉÉĆĆĆĆĆĆĘĘĘÎÎÎĐĐĐŃŃŃŘŘŘ×××ÔÔÔŃŃŃĘĘĘĹĹĹÉÉÉŃŃŃŇŇŇÎÎÎÔÔÔŐŐŐĆĆĆżżżĘĘĘŃŃŃÉÉÉĂĂĂÔÔÔŘŘŘŃŃŃÍÍÍĹĹĹĹĹĹĂĂĂÂÂÂżżż»»»ĽĽĽŔŔŔľľľ······łłł±±±µµµµµµłłłµµµĽĽĽµµµ···¸¸¸şşşşşşşşşşşşşşşşşşĐĐĐÇÇÇŔŔŔľľľşşşżżż¸¸¸ŐŐŐÂÂÂĂĂĂÔÔÔÔÔÔÍÍÍĐĐĐŐŐŐŇŇŇĘĘĘľľľżżżĚĚĚĘĘĘŔŔŔľľľ´´´ľľľĘĘĘÎÎÎĘĘĘĆĆĆĆĆĆÉÉÉĹĹĹĂĂĂÂÂÂÂÂÂĹĹĹÉÉÉÍÍÍĐĐĐĐĐĐŇŇŇŐŐŐŇŇŇÉÉÉŔŔŔ»»»»»»¸¸¸ĽĽĽŔŔŔŔŔŔşşş···şşşĽĽĽĽĽĽĂĂĂĚĚĚĐĐĐŃŃŃĂĂø¸¸ÂÂÂĚĚĚŔŔŔŔŔŔŔŔŔµµµµµµĂĂĂĘĘĘŔŔŔ»»»żżżŔŔŔ»»»ľľľĂĂĂľľľĽĽĽĽĽĽĽĽĽĽĽĽľľľľľľżżżŔŔŔżżżľľľĽĽĽ»»»»»»ĽĽĽżżżŔŔŔĆĆĆĚĚĚÉÉÉÍÍÍŇŇŇÍÍÍÍÍÍŰŰŰÇÇÇŃŃŃÉÉÉÉÉɸ¸¸ŃŃŃŔŔŔĆĆĆŻŻŻëëëßßßŘŘŘßßßĐĐĐŃŃŃ»»»ľľľÍÍÍŰŰŰŃŃѸ¸¸±±±»»»···ĽĽĽĂĂĂÉÉÉĚĚĚĚĚĚĚĚĚĚĚĚÂÂÂŔŔŔżżżľľľĽĽĽşşş¸¸¸···±±±±±±±±±ÂÂÂĹĹĹĂĂĂĘĘĘ»»»ĹĹĹ»»»±±±»»»ĐĐĐÔÔÔĚĚĚÉÉÉÎÎÎÝÝÝŃŃŃĐĐĐÔÔÔÎÎÎŃŃŃĐĐĐÍÍÍĘĘĘÇÇÇÉÉÉÎÎÎŃŃŃÍÍÍÉÉɵµµşşş»»»ÂÂÂÉÉÉ»»»ŔŔŔĆĆĆĆĆĆÇÇÇÉÉÉĘĘĘĘĘĘĘĘĘÉÉÉÇÇÇÉÉÉĘĘĘÉÉÉÉÉÉĘĘĘÎÎÎŇŇŇĘĘĘĘĘĘÉÉÉĘĘĘĚĚĚÍÍÍÍÍÍĚĚĚŇŇŇŃŃŃŇŇŇŇŇŇÍÍÍĹĹĹĂĂĂÇÇÇÎÎÎÉÉÉÎÎÎŇŇŇÍÍÍĚĚĚÎÎÎĚĚĚĘĘĘŔŔŔĚĚĚÎÎÎÉÉÉĘĘĘÇÇÇĘĘĘĹĹĹÇÇÇĹĹĹżżż»»»»»»¸¸¸´´´şşşşşş¸¸¸¸¸¸´´´łłłµµµ»»»şşş»»»ĽĽĽĽĽĽľľľżżżŔŔŔĂĂĂŔŔŔŇŇŇĚĚĚĘĘĘÍÍÍĚĚĚŃŃŃÎÎÎĘĘĘÇÇÇĘĘĘÉÉÉĽĽĽşşşľľľľľľşşşľľľ»»»ĹĹĹŃŃѱ±±»»»ĹĹĹĚĚĚŃŃŃĐĐĐÇÇÇżżż»»»»»»ľľľľľľĽĽĽĽĽĽľľľÂÂÂĆĆĆÉÉÉÎÎÎÍÍÍĐĐĐĐĐĐŇŇŇÎÎÎŔŔŔĽĽĽ»»»ĽĽĽŔŔŔÂÂÂŔŔŔŔŔŔÂÂÂÂÂÂŃŃŃÔÔÔĆĆĆĂĂĂŇŇŇÎÎλ»»şşşĹĹĹĆĆĆÇÇÇĆĆĆĹĹĹŔŔŔŔŔŔĹĹĹÉÉÉŔŔŔżżżŔŔŔĽĽĽ»»»ĽĽĽĽĽĽľľľľľľĽĽĽĽĽĽľľľżżżŔŔŔŔŔŔľľľĽĽĽĽĽĽ»»»»»»ĽĽĽľľľżżżÂÂÂÉÉÉĚĚĚĚĚĚÍÍÍĚĚĚŃŃŃÜÜÜÍÍÍĐĐĐÎÎÎŇŇŇĽĽĽĐĐĐÂÂÂĂĂĂ°°°çççŰŰŰŇŇŇÔÔÔÇÇÇŃŃŃĚĚĚşşş¸¸¸żżżÉÉÉĆĆƸ¸¸µµµĽĽĽ¸¸¸ľľľĹĹĹĘĘĘÍÍÍÍÍÍÍÍÍÍÍÍĚĚĚĹĹĹľľľşşş¸¸¸¸¸¸···´´´łłł¸¸¸»»»ĹĹĹĂĂĂÂÂÂÉÉÉ»»»···µµµµµµĂĂĂŐŐŐ×××ÍÍÍĚĚĚÍÍÍŰŰŰÔÔÔŃŃŃÔÔÔÍÍÍŃŃŃÎÎÎÎÎÎĚĚĚĚĚĚÍÍÍÎÎÎÉÉÉĽĽĽłłł´´´żżżĂĂĂĂĂĂżżżµµµ¸¸¸ÇÇÇĆĆĆÇÇÇÇÇÇÇÇÇÇÇÇĆĆĆÇÇÇÇÇÇĹĹĹÉÉÉĚĚĚÇÇÇĂĂĂĹĹĹÍÍÍ×××ĘĘĘÍÍÍĐĐĐŃŃŃĐĐĐÎÎÎÍÍÍĚĚĚÎÎÎÍÍÍÎÎÎŇŇŇŃŃŃĘĘĘÇÇÇÉÉÉĆĆĆÂÂÂĹĹĹĘĘĘÎÎÎÔÔÔŃŃŃĹĹĹÎÎÎżżżŔŔŔşşşłłł······şşşĂĂĂĘĘĘÍÍÍÉÉÉĂĂĂżżżşşş´´´±±±µµµ···´´´´´´¸¸¸ĽĽĽżżż¸¸¸şşşşşş¸¸¸···şşşľľľÂ°°°ŔŔŔŔŔŔŔŔŔÂÂÂżżżÇÇÇÎÎÎÔÔÔŇŇŇÔÔÔĐĐĐÉÉÉĚĚĚĚĚĚÂÂÂÇÇÇÍÍÍĆĆĆĘĘĘŐŐŐĹĹĹľľľÜÜÜÉÉÉĚĚĚÎÎÎÍÍÍÇÇÇŔŔŔĽĽĽ»»»»»»şşş¸¸¸¸¸¸»»»ľľľÂÂÂĂĂĂÍÍÍÉÉÉĘĘĘÉÉÉŘŘŘŮŮŮľľľ¸¸¸»»»ľľľĽĽĽĽĽĽÂÂÂÉÉÉÎÎÎŇŇŇŐŐŐ××׼ĽĽµµµŃŃŃŮŮŮĘĘĘĂĂĂľľľĘĘĘĘĘĘÇÇÇÍÍÍÉÉÉżżżŔŔŔĚĚĚĆĆĆŔŔŔżżżżżżşşş¸¸¸ľľľżżżżżżľľľľľľľľľżżżŔŔŔ»»»»»»»»»»»»ĽĽĽĽĽĽĽĽĽľľľżżżĹĹĹÍÍÍĚĚĚÇÇÇĚĚĚŐŐŐŮŮŮŇŇŇÍÍÍÔÔÔŰŰŰľľľÎÎÎĹĹĹľľľ¬¬¬ßßßŰŰŰ××××××ĘĘĘŃŃŃÉÉÉŔŔŔ»»»¸¸¸»»»ĽĽĽşşşşşşĽĽĽ»»»ŔŔŔÇÇÇĚĚĚÍÍÍÎÎÎÎÎÎÎÎÎÎÎÎÉÉÉŔŔŔ»»»¸¸¸µµµłłł°°°···żżżĂĂĂĆĆĆÂÂÂŔŔŔĹĹĹ»»»łłł»»»ĂĂĂÎÎÎŘŘŘŃŃŃĆĆĆĆĆĆÉÉÉ×××ŐŐŐÔÔÔŇŇŇÍÍÍÎÎÎÍÍÍĹĹĹÉÉÉÍÍÍÎÎÎĘĘĘĂĂĂ»»»µµµşşşĹĹĹĆĆĆľľľµµµ¬¬¬±±±ĂĂĂĹĹĹÇÇÇÉÉÉĆĆĆĂĂĂÂÂÂĹĹĹĆĆĆŔŔŔĹĹĹÇÇÇĆĆĆÂÂÂĂĂĂÉÉÉĐĐĐĚĚĚĐĐĐÔÔÔÔÔÔŇŇŇŃŃŃĐĐĐŃŃŃÎÎÎÉÉÉÉÉÉÎÎÎŇŇŇŃŃŃŇŇŇŐŐŐŔŔŔŔŔŔżżżŔŔŔÉÉÉŃŃŃÎÎÎĂĂĂĐĐĐĂĂĂĆĆĆŔŔŔ¸¸¸¸¸¸°°°¬¬¬µµµľľľĂĂĂĆĆĆÇÇÇĆĆĆľľľłłłłłłµµµ´´´±±±´´´»»»ĽĽĽ···ÂÂÂÂÂÂÂÂÂżżżżżżÂÂÂĘĘĘĐĐĐÂÂÂĆĆĆÂÂÂÂÂÂĹĹĹŔŔŔÂÂÂÇÇÇÇÇÇĂĂĂĚĚĚÔÔÔ×××ÜÜÜÝÝÝŘŘŘ×××ÝÝÝÜÜÜÜÜÜŰŰŰÇÇÇĽĽĽĚĚĚĂĂĂĹĹĹĹĹĹĆĆĆĹĹĹĂĂĂŔŔŔżżżĽĽĽ»»»»»»»»»ĽĽĽżżżÂÂÂĹĹĹĘĘĘĹĹĹĹĹĹÂÂÂÔÔÔŘŘŘşşşłłłşşşżżż»»»···ľľľÉÉÉŐŐŐŕŕŕĐĐĐÍÍ͸¸¸µµµÇÇÇŇŇŇŐŐŐŇŇŇ»»»ĆĆĆÇÇÇĆĆĆĚĚĚĚĚĚĆĆĆÂÂÂŔŔŔĘĘĘÇÇÇżżżżżż»»»şşşÂÂÂżżżżżżŔŔŔŔŔŔÂÂÂŔŔŔŔŔŔżżżşşşşşş»»»ĽĽĽĽĽĽĽĽĽĽĽĽĽĽĽżżżÂÂÂĚĚĚÍÍÍÇÇÇĐĐĐŘŘŘĐĐĐÔÔÔÉÉÉŇŇŇŰŰŰĽĽĽÉÉÉĂĂĂşşş¬¬¬ŰŰŰÝÝÝÜÜÜÝÝÝŘŘŘŮŮŮÇÇÇĘĘĘĆĆĆÂÂÂľľľĽĽĽĽĽĽĽĽĽĽĽĽĽĽĽŔŔŔÇÇÇĚĚĚÍÍÍÍÍÍÎÎÎĐĐĐĘĘĘĘĘĘĆĆĆŔŔŔ¸¸¸´´´łłłłłłĽĽĽĹĹĹÇÇÇĹĹĹŔŔŔÂÂÂŔŔŔ···¸¸¸ĹĹĹÎÎÎ×××ŘŘŘĚĚĚÂÂÂĆĆĆĆĆĆŇŇŇŘŘŘ×××ŇŇŇÎÎÎÍÍÍĚĚĚÍÍÍŇŇŇŇŇŇĘĘĘľľľ···¸¸¸ĽĽĽŔŔŔ»»»´´´´´´°°°­­­´´´żżżĂĂĂÇÇÇÇÇÇĂĂĂÂÂÂĂĂĂĆĆĆÂÂÂÂÂÂĂĂĂĆĆĆÉÉÉĘĘĘÉÉÉÇÇÇÉÉÉĘĘĘÍÍÍÎÎÎÍÍÍÍÍÍĐĐĐŃŃŃĚĚĚĆĆĆĆĆĆĚĚĚŃŃŃŃŃŃŇŇŇÔÔÔĂĂĂĆĆĆĂĂĂżżżĂĂĂĘĘĘĚĚĚÇÇÇżżżşşşĆĆĆĆĆĆ···­­­ŞŞŞ­­­°°°µµµŔŔŔÇÇǸ¸¸¸¸¸···łłłłłł»»»ĂĂĂŔŔŔ······µµµłłłŻŻŻ­­­ŻŻŻ´´´¸¸¸ĹĹĹÂÂÂľľľĂĂĂÔÔÔŰŰŰŘŘŘÝÝÝŃŃŃÔÔÔŰŰŰ×××ÇÇÇÂÂÂÂÂÂľľľŔŔŔŔŔŔżżżľľľżżżĂĂĂÇÇÇÉÉÉĂĂĂÂÂÂŔŔŔŔŔŔŔŔŔżżżľľľ»»»ĽĽĽĽĽĽĽĽĽĽĽĽľľľŔŔŔÂÂÂĂĂĂĆĆĆĹĹĹĹĹĹŔŔŔÎÎÎÔÔÔżżż¸¸¸···ĹĹĹĹĹĹĽĽĽľľľĂĂĂĚĚĚŘŘŘ×××ÇÇÇ···ľľľľľľŔŔŔŇŇŇÍÍÍ»»»ŔŔŔÉÉÉĚĚĚĚĚĚĐĐĐĐĐĐĹĹĹ···ÎÎÎŇŇŇĂĂĂľľľĽĽĽ»»»ŔŔŔľľľżżżÂÂÂĹĹĹĹĹĹÂÂÂżżżĽĽĽ¸¸¸şşş»»»»»»ĽĽĽĽĽĽľľľľľľĂĂĂÂÂÂÉÉÉÍÍÍÍÍÍŐŐŐŐŐŐÇÇÇŃŃŃÇÇÇÎÎÎÎÎλ»»ÇÇǸ¸¸±±±ÜÜÜäääŕŕŕÜÜÜÜÜÜććć×××ĚĚĚÎÎÎĚĚĚĆĆĆÂÂÂŔŔŔżżżĽĽĽľľľÂÂÂÇÇÇĘĘĘĚĚĚÍÍÍÎÎÎĐĐĐÉÉÉĚĚĚÉÉÉŔŔŔµµµłłłşşşŔŔŔĹĹĹĆĆĆĆĆĆŔŔŔŔŔŔ»»»´´´ľľľÉÉÉŇŇŇ××××××ĚĚĚĆĆĆÎÎÎĹĹĹĐĐĐŰŰŰŘŘŘŃŃŃĐĐĐÍÍÍĚĚĚÍÍÍĚĚĚÇÇÇŔŔŔşşş···»»»żżż¸¸¸¸¸¸°°°ŻŻŻ···¸¸¸±±±±±±şşşŔŔŔĆĆĆÉÉÉĆĆĆĂĂĂĹĹĹĆĆĆĆĆĆĂĂĂÂÂÂĆĆĆÍÍÍÎÎÎĚĚĚĆĆĆÂÂÂĂĂĂĂĂĂĹĹĹĹĹĹĆĆĆÉÉÉĚĚĚĆĆĆĂĂĂĹĹĹĘĘĘÍÍÍÉÉÉĆĆĆĹĹĹÉÉÉÎÎÎĚĚĚĆĆĆĆĆĆÇÇÇÉÉÉÍÍÍĂĂĂ»»»żżżşşş´´´ĽĽĽ»»»şşşłłł°°°¬¬¬ŻŻŻ»»»ÉÉÉĚĚĚĆĆĆĂĂĂżżż»»»»»»ŔŔŔĂĂĂżżż¸¸¸ŔŔŔŔŔŔżżżŔŔŔĂĂĂÉÉÉÍÍÍÎÎÎľľľĂĂĂÇÇÇżżżŔŔŔĆĆĆĆĆĆÔÔÔŐŐŐŰŰŰŰŰŰĚĚĚ»»»ĽĽĽ»»»ŻŻŻ¸¸¸łłł±±±°°°łłłĂĂĂÍÍÍĹĹĹżżżżżżľľľľľľľľľĽĽĽ»»»»»»»»»»»»»»»»»»ĽĽĽľľľŔŔŔŔŔŔÂÂÂĆĆĆĹĹĹĆĆĆĚĚĚŇŇŇÎÎÎŔŔŔ¸¸¸ÎÎÎŇŇŇÉÉÉÇÇÇÂÂÂľľľĂĂĂÜÜÜĂĂĂ´´´Â»»»ĽĽĽÔÔÔĆĆĆĽĽĽľľľĚĚĚÔÔÔĐĐĐŇŇŇÔÔÔÉÉÉşşşÎÎÎŐŐŐÉÉÉżżżĽĽĽĽĽĽĽĽĽĽĽĽżżżĂĂĂĹĹĹĹĹĹÂÂÂľľľ»»»şşşşşşşşş»»»ĽĽĽľľľżżżżżżĆĆĆĹĹĹÉÉÉÎÎÎŇŇŇ×××ŇŇŇÉÉÉĘĘĘĚĚĚĘĘĘŔŔŔŔŔŔÍÍÍŔŔŔľľľ°°°ŃŃŃćććëëëßßßŮŮŮäääßßßÇÇÇĚĚĚÍÍÍĚĚĚÉÉÉĆĆĆĂĂĂŔŔŔŔŔŔĹĹĹÉÉÉĚĚĚÍÍÍÍÍÍÎÎÎĐĐĐÎÎÎÍÍÍĆĆĆ»»»łłł···ĂĂĂĐĐĐÉÉÉÇÇÇĆĆĆżżżŔŔŔżżżµµµ»»»ĚĚĚŇŇŇŐŐŐŘŘŘŘŘŘÍÍÍÇÇÇÎÎÎÇÇÇĚĚĚŰŰŰŮŮŮŃŃŃÔÔÔÎÎÎĚĚĚżżż»»»···¸¸¸ľľľżżżĽĽĽ···¨¨¨ŻŻŻŻŻŻ°°°»»»ľľľ»»»ĽĽĽşşşżżżĹĹĹÇÇÇÇÇÇĆĆĆĆĆĆÇÇÇÇÇÇÂÂÂľľľżżżĹĹĹÉÉÉĘĘĘÉÉÉÂÂÂŔŔŔŔŔŔŔŔŔÂÂÂĹĹĹĹĹĹĹĹĹÇÇÇĂĂĂĂĂĂÇÇÇÇÇÇĂĂĂŔŔŔÂÂÂÇÇÇÍÍÍÍÍÍĚĚĚÍÍÍĹĹĹŔŔŔÇÇÇŇŇŇÉÉÉÉÉÉ»»»±±±»»»ľľľľľľşşşşşş¸¸¸µµµşşşÂÂÂĹĹĹĂĂĂÇÇÇĆĆĆĂĂĂÂÂÂľľľ···µµµµµµľľľ»»»¸¸¸···¸¸¸şşş···´´´»»»ÇÇÇĐĐĐĽĽĽ´´´şşş»»»ÍÍÍŇŇŇÎÎÎÉÉÉĽĽĽłłł¸¸¸»»»±±±ŞŞŞ±±±żżżÍÍÍÔÔÔŇŇŇÇÇÇşşşĽĽĽĽĽĽľľľľľľľľľĽĽĽĽĽĽĽĽĽĽĽĽĽĽĽĽĽĽĽĽĽľľľżżżŔŔŔŔŔŔĂĂĂĆĆĆÂÂÂĘĘĘĘĘĘÎÎÎŘŘŘĽĽĽżżżŐŐŐ×××ÎÎÎŇŇŇĚĚĚĽĽĽ»»»ŮŮŮÉÉÉ···ŔŔŔĽĽĽŔŔŔŮŮŮÉÉÉľľľżżżÇÇÇÍÍÍĚĚĚĘĘĘĚĚĚÎÎÎÂÂÂĹĹĹĚĚĚÍÍÍĂĂĂżżżżżżľľľżżżŔŔŔÂÂÂÂÂÂÂÂÂŔŔŔľľľĽĽĽ»»»»»»şşş»»»ĽĽĽľľľŔŔŔÂÂÂĆĆĆÉÉÉĘĘĘÎÎÎÔÔÔŇŇŇŃŃŃŐŐŐĂĂĂÔÔÔÉÉɸ¸¸ĚĚĚŘŘŘĂĂĂĹĹŵµµĽĽĽŃŃŃíííççç×××ŰŰŰÜÜÜÎÎÎĚĚĚĘĘĘÎÎÎŃŃŃÎÎÎÉÉÉĆĆĆĹĹĹÇÇÇĚĚĚÎÎÎÎÎÎĐĐĐŃŃŃÔÔÔŇŇŇĚĚĚŔŔŔşşş»»»ÂÂÂĚĚĚŃŃŃĚĚĚÉÉÉĘĘĘĂĂĂżżżşşş´´´ÇÇÇÔÔÔ×××ŘŘŘŰŰŰÝÝÝŇŇŇÇÇÇÉÉÉĘĘĘĘĘĘŰŰŰŘŘŘŃŃŃ×××ĐĐĐĚĚĚľľľĽĽĽĽĽĽľľľľľľ¸¸¸°°°©©©ĄĄĄ°°°łłł´´´ľľľĂĂĂÂÂÂĂĂĂŔŔŔÂÂÂĹĹĹĆĆĆĆĆĆÇÇÇÉÉÉÉÉÉĹĹĹżżżşşşµµµ¸¸¸żżżĆĆĆĘĘĘĆĆĆĂĂĂÂÂÂĂĂĂĆĆĆĆĆĆĹĹĹĂĂĂĚĚĚĆĆĆĂĂĂĂĂĂĂĂĂĂĂĂĆĆĆĘĘĘÂÂÂÇÇÇÉÉÉÍÍÍĐĐĐĂĂø¸¸ľľľŔŔŔŔŔŔĚĚĚĹĹĹşşşşşş±±±©©©łłłşşşľľľşşş´´´łłłłłł±±±©©©ŻŻŻ¸¸¸żżżĽĽĽ¸¸¸ŔŔŔÎÎδ´´´´´···ŔŔŔÎÎÎ×××ŘŘŘ×××ÍÍÍÎÎÎĚĚĚ···¸¸¸Â¸¸¸»»»ĂĂĂ»»»ľľľľľľ···şşşÍÍÍŰŰŰŇŇŇÎÎÎĂĂĂÂÂÂĹĹĹľľľ¸¸¸ľľľŔŔŔÂÂÂÂÂÂŔŔŔľľľ»»»şşşşşşżżżżżżżżżŔŔŔŔŔŔÂÂÂÂÂÂĂĂĂĹĹĹĆĆĆľľľĘĘĘÇÇÇÉÉÉ×××±±±ĆĆĆŘŘŘÔÔÔÍÍÍŘŘŘŐŐŐĹĹĹżżżŘŘŘ×××ŔŔŔżżż»»»ŔŔŔŰŰŰĚĚĚŔŔŔÂÂÂľľľľľľÂÂÂľľľÂÂÂŇŇŇÉÉÉşşşżżżÍÍÍĘĘĘĂĂĂĂĂĂĹĹĹÂÂÂŔŔŔŔŔŔżżżżżżľľľľľľżżżĽĽĽ»»»şşşşşş»»»ľľľÂÂÂĂĂĂĂĂĂĘĘĘĚĚĚÎÎÎÔÔÔÎÎÎŃŃŃâââŔŔŔŰŰŰĘĘĘ´´´ŐŐŐâââĆĆĆĘĘĘÉÉÉŻŻŻ´´´ÝÝÝćććÔÔÔ×××ÜÜÜŰŰŰĐĐĐĘĘĘŃŃŃŘŘŘŐŐŐÎÎÎĘĘĘÇÇÇĘĘĘÎÎÎŃŃŃŃŃŃŇŇŇÔÔÔŐŐŐŇŇŇÉÉÉľľľľľľĆĆĆÍÍÍÍÍÍĘĘĘĚĚĚĘĘĘĐĐĐÇÇÇľľľ´´´łłłŇŇŇÎÎÎŃŃŃÔÔÔÜÜÜäääÜÜÜÎÎÎÍÍÍĚĚĚĘĘĘŰŰŰŘŘŘŇŇŇŘŘŘŃŃŃĚĚĚ´´´ľľľĆĆĆĆĆĆĽĽĽ´´´±±±´´´­­­µµµµµµµµµŔŔŔÇÇÇĂĂĂŔŔŔÇÇÇĆĆĆĹĹĹĂĂĂĹĹĹÇÇÇÉÉÉĘĘĘŔŔŔłłł°°°¸¸¸»»»µµµľľľÎÎÎĆĆĆÇÇÇÇÇÇĆĆĆĹĹĹĆĆĆÉÉÉĚĚĚŐŐŐŇŇŇĚĚĚŔŔŔµµµÇÇÇÇÇÇĹĹĹŔŔŔĐĐĐŐŐŐÔÔÔĚĚĚ···¸¸¸···şşşÂÂÂĚĚĚĘĘĘÂÂÂĽĽĽľľľ±±±°°°±±±şşşŔŔŔľľľµµµ­­­ŻŻŻĽĽĽżżż¸¸¸żżżĆĆƸ¸¸ŻŻŻŻŻŻ°°°±±±¬¬¬±±±±±±´´´ÝÝÝŰŰŰĂĂĂżżżľľľĽĽĽŔŔŔľľľżżżĆĆƱ±±¸¸¸łłłŔŔŔÇÇÇÉÉÉÂÂÂŔŔŔĂĂĂĆĆĆÂÂÂĽĽĽ¸¸¸»»»ľľľĆĆĆľľľ»»»ľľľ»»»´´´łłł···µµµ»»»ľľľĽĽĽľľľĂĂĂĂĂĂżżżÉÉÉ»»»ĹĹĹÇÇÇĹĹĹĚĚĚĆĆĆĽĽĽĆĆĆŐŐŐŃŃŃĚĚĚĹĹĹŰŰŰ´´´żżżŇŇŇŐŐŐÔÔÔşşşşşşŃŃŃĐĐĐĚĚĚÉÉÉÂÂÂÂÂÂĚĚĚĐĐĐÉÉÉŔŔŔĽĽĽĹĹĹĚĚĚĽĽĽŐŐŐĚĚĚĂĂĂÇÇÇŔŔŔŔŔŔŔŔŔżżżżżżľľľľľľĽĽĽĽĽĽľľľşşş»»»żżżÂÂÂżżżŔŔŔĹĹĹĂĂĂÍÍÍÉÉÉÎÎÎŮŮŮÍÍÍÇÇÇÜÜÜĘĘĘÎÎÎâââÉÉÉłłł»»»ŘŘŘĚĚĚŔŔŔŔŔŔżżżĚĚĚŰŰŰŘŘŘŃŃŃŮŮŮŮŮŮčččŐŐŐÉÉÉÎÎÎĘĘĘĐĐĐŮŮŮŃŃŃŇŇŇŇŇŇŇŇŇÔÔÔŐŐŐ×××ŘŘŘĐĐĐĆĆƸ¸¸»»»ÍÍÍÍÍÍ»»»°°°¸¸¸ĚĚĚÎÎÎĂĂĂÂÂÂżżżşşş¸¸¸ÔÔÔÔÔÔŮŮŮŰŰŰŘŘŘŮŮŮŇŇŇĂĂĂĚĚĚŇŇŇâââŘŘŘŰŰŰÔÔÔĐĐи¸¸şşşĂĂĂĹĹĹşşş´´´şşşľľľľľľ¸¸¸°°°ŻŻŻłłł¸¸¸ÂÂÂĹĹĹĽĽĽĂĂĂÉÉÉĘĘĘĹĹĹĂĂĂĆĆĆĆĆĆĂĂĂ»»»şşşŔŔŔÉÉɱ±±±±±ľľľÉÉÉĘĘĘĚĚĚĚĚĚĚĚĚÍÍÍŃŃŃÔÔÔŃŃŃŃŃŃÇÇǵµµ¸¸¸´´´ĆĆĆÂÂÂĹĹĹÂÂÂÍÍÍŃŃŃŇŇŇÎÎÎĽĽĽ¸¸¸ĽĽĽ¸¸¸»»»ĆĆĆĐĐĐŇŇŇĐĐĐÎÎÎÉÉÉÇÇÇŔŔŔşşşĽĽĽŔŔŔĽĽĽ´´´şşşĽĽĽşşş»»»ĂĂĂŔŔŔłłłŻŻŻŻŻŻŞŞŞŞŞŞ©©©łłł¸¸¸şşşŇŇŇ···ĽĽĽ»»»şşşŔŔŔżżżżżżÂÂÂĽĽĽŐŐŐÎÎÎŃŃŃÍÍÍÇÇÇÂÂÂľľľŔŔŔÂÂÂżżżĽĽĽşşş»»»ľľľĽĽĽĽĽĽĽĽĽ»»»´´´­­­­­­±±±´´´şşşľľľĽĽĽĽĽĽŔŔŔÂÂÂżżżÇÇÇľľľĹĹĹĹĹĹĆĆĆĘĘĘŔŔŔ»»»ĘĘĘÔÔÔÎÎÎÍÍÍĘĘĘŕŕŕĂĂĂ×××ÍÍÍŇŇŇ×××ĆĆĆÇÇÇŘŘŘĐĐĐĹĹĹÂÂÂĹĹĹĘĘĘĐĐĐÔÔÔŃŃŃĆĆĆĽĽĽľľľÍÍÍŔŔŔÔÔÔÍÍÍÂÂÂÂÂÂżżżżżżżżżżżżľľľľľľľľľľľľĽĽĽ»»»¸¸¸şşşżżżÂÂÂŔŔŔÂÂÂĆĆĆĹĹĹĹĹĹÉÉÉÎÎÎĐĐĐÍÍÍŃŃŃÜÜÜĚĚĚŐŐŐŮŮŮÉÉÉ»»»´´´ĂĂĂŇŇŇĆĆĆĂĂĂşşşşşşÍÍÍÝÝÝŰŰŰŃŃŃÜÜÜŕŕŕÍÍÍĘĘĘŐŐŐŃŃŃĚĚĚĂĂĂĚĚĚÍÍÍĐĐĐÔÔÔ×××ŘŘŘŘŘŘ×××ŐŐŐĐĐĐŔŔŔ···¸¸¸şşş»»»Â¸¸¸ĆĆĆĐĐĐĘĘĘŔŔŔľľľĽĽĽ···ÍÍÍÎÎÎŘŘŘÜÜÜÜÜÜâââŕŕŕŐŐŐŇŇŇÎÎÎÜÜÜŰŰŰŰŰŰĐĐĐÍÍ͸¸¸ŔŔŔĹĹĹżżż´´´°°°¸¸¸ľľľĽĽĽşşş°°°ŻŻŻŻŻŻ¬¬¬´´´ŔŔŔĹĹĹŔŔŔĹĹĹĹĹĹÂÂÂĂĂĂÇÇÇÇÇÇĂĂĂ´´´»»»ÇÇÇÎÎÎÂÂÂłłł···ĹĹĹĚĚĚÍÍÍÎÎÎÎÎÎÎÎÎĐĐĐŇŇŇŐŐŐÎÎÎŃŃŃĆĆƱ±±´´´µµµÇÇÇżżżĂĂĂĂĂĂĘĘĘĚĚĚĐĐĐŃŃŃĂĂĂ»»»ĽĽĽµµµ±±±···ĽĽĽľľľľľľĽĽĽłłłżżżĹĹĹľľľşşşżżżľľľ···ĂĂĂ»»»łłłĽĽĽĆĆĆ»»»łłłµµµŻŻŻ¬¬¬¬¬¬¦¦¦©©©±±±łłłĽĽĽľľľşşşĹĹĹÂÂÂľľľĹĹĹÂÂÂżżżÂ»»»ŰŰŰÎÎÎÍÍÍĚĚĚĆĆĆÉÉÉĽĽĽĽĽĽĽĽĽĽĽĽĽĽĽ»»»»»»»»»ľľľĽĽĽµµµ¬¬¬©©©­­­°°°°°°ŻŻŻµµµ»»»ĽĽĽľľľÂÂÂĂĂĂĂĂĂĹĹĹÂÂÂĂĂĂŔŔŔÉÉÉĘĘĘ»»»»»»ÝÝÝŘŘŘÇÇÇĹĹĹĂĂĂÔÔÔ···ĂĂĂŇŇŇŐŐŐŐŐŐÇÇÇÉÉÉŘŘŘÔÔÔĚĚĚŔŔŔÉÉÉĐĐĐĐĐĐĐĐĐĐĐĐĹĹŵµµ¸¸¸ÍÍÍĂĂĂĐĐĐÍÍÍŔŔŔĽĽĽľľľĽĽĽĽĽĽľľľľľľľľľľľľľľľľľľĽĽĽ»»»ĽĽĽżżżÂÂÂŔŔŔĂĂĂĆĆĆÉÉÉĹĹĹĐĐĐŐŐŐĘĘĘĘĘĘŇŇŇÍÍÍĆĆĆŮŮŮÎÎÎĂĂĂ······ŮŮŮĘĘĘÇÇÇĽĽĽ°°°ĽĽĽÜÜÜććć×××ÔÔÔÜÜÜÔÔÔÎÎÎĘĘĘĆĆĆÉÉÉĹĹĹÍÍÍĚĚĚĚĚĚÎÎÎŇŇŇŐŐŐŐŐŐÔÔÔŐŐŐŘŘŘŃŃŃĹĹĹĽĽĽ¸¸¸»»»ĂĂĂĽĽĽżżżÍÍÍĐĐĐĂĂĂżżżŔŔŔ¸¸¸ĚĚĚĐĐĐŮŮŮÝÝÝŰŰŰÝÝÝŕŕŕŮŮŮŕŕŕŃŃŃŕŕŕăăăâââÔÔÔÔÔÔżżżĆĆĆĹĹĹ»»»°°°­­­···ľľľĽĽĽµµµłłł»»»ŔŔŔµµµ±±±ĽĽĽĆĆĆżżżŔŔŔŔŔŔŔŔŔĹĹĹÉÉÉĆĆƱ±±»»»ÇÇÇÎÎÎĆĆĆ»»»żżżÉÉÉĚĚĚÍÍÍÎÎÎÍÍÍĚĚĚĘĘĘĘĘĘĚĚĚÎÎÎĐĐĐÉÉÉ»»»żżżşşşÇÇÇżżżżżżĆĆĆĚĚĚĘĘĘĚĚĚÎÎÎÉÉÉŔŔŔ»»»»»»ĽĽĽ»»»¸¸¸µµµµµµ···­­­ĽĽĽĆĆĆŔŔŔşşşşşşŔŔŔĹĹĹ···şşş¸¸¸ÇÇÇÎÎÎľľľ´´´µµµµµµ¸¸¸şşşŻŻŻĄĄĄŞŞŞ±±±´´´´´´ŻŻŻşşş»»»»»»ĹĹĹĹĹĹĹĹĹżżżµµµ×××ÍÍÍÍÍÍĚĚĚżżżľľľľľľ»»»şşşşşş»»»»»»şşş···µµµ´´´°°°ŻŻŻ¸¸¸ŔŔŔµµµ¤¤¤···»»»ŔŔŔŔŔŔżżżľľľľľľżżżŔŔŔĂĂĂÂÂÂľľľÍÍÍĚĚ̸¸¸ľľľ×××ÍÍÍ»»»»»»ŔŔŔŇŇŇ···µµµżżżĹĹĹĂĂø¸¸»»»ĘĘĘŃŃŃŃŃŃĐĐĐÔÔÔ×××ÔÔÔĐĐĐÉÉÉĽĽĽ±±±···ĚĚĚŔŔŔĹĹĹÍÍÍ»»»»»»»»»»»»ĽĽĽĽĽĽľľľżżżżżżżżżÂÂÂŔŔŔżżżżżżŔŔŔÂÂÂĂĂĂĆĆĆĆĆĆĹĹĹÔÔÔŮŮŮÍÍÍÎÎÎŇŇŇÇÇÇĚĚĚâââĘĘĘżżżÂÂÂżżż±±±ÎÎÎĚĚĚÇÇÇĹĹŸ¸¸´´´ĘĘĘäääćććŃŃŃŰŰŰŮŮŮ×××ÍÍÍÇÇÇÍÍÍĹĹĹĚĚĚĘĘĘĚĚĚŃŃŃŐŐŐ×××ŃŃŃĚĚĚŃŃŃ××××××ÔÔÔŃŃŃÎÎÎĘĘĘÇÇÇĂĂĂŔŔŔÇÇÇÍÍÍĘĘĘĆĆĆĂĂĂĽĽĽĽĽĽÂÂÂŃŃŃŮŮŮŮŮŮÝÝÝâââßßßŕŕŕŇŇŇăăăçççäääŰŰŰŮŮŮżżżĹĹĹĹĹĹżżż´´´°°°µµµ»»»ĽĽĽ´´´łłłżżżÉÉÉĽĽĽ±±±···ŔŔŔŔŔŔŔŔŔŔŔŔĂĂĂÇÇÇÇÇÇÂÂÂĽĽĽşşşŔŔŔĚĚĚŃŃŃÎÎÎĹĹĹ»»»¸¸¸ĆĆĆÉÉÉĘĘĘĘĘĘÉÉÉĆĆĆĆĆĆĆĆĆĚĚĚĘĘĘĘĘĘĘĘĘÍÍÍşşşÂÂÂżżżşşşĆĆĆÍÍÍĚĚĚÇÇÇÉÉÉĚĚĚÉÉÉĆĆĆĘĘĘÍÍÍĘĘĘĹĹĹĽĽĽµµµ±±±´´´···żżżĹĹŸ¸¸´´´µµµ¬¬¬żżżĂĂĂÍÍÍÎÎλ»»´´´°°°¬¬¬±±±±±±ŞŞŞ¦¦¦­­­¸¸¸···ĆĆƵµµ¸¸¸şşşşşşÂÂÂÂÂÂĹĹĹĆĆĆżżżÜÜÜŇŇŇŃŃŃĘĘĘżżżĽĽĽżżż»»»¸¸¸¸¸¸şşş¸¸¸µµµłłłłłł±±±­­­ŻŻŻżżżÎÎÎĹĹĹ°°°łłł···ĽĽĽÂÂÂĂĂĂĂĂĂĹĹĹĆĆĆľľľĂĂĂÂÂÂľľľÎÎÎÍÍ͸¸¸żżżĹĹĹÉÉÉĂĂĂĂĂĂÇÇÇŐŐŐŔŔŔ¸¸¸ŻŻŻ¸¸¸ĽĽĽ»»»ĽĽĽĹĹĹĐĐĐŇŇŇ××××××ŮŮŮÜÜÜ×××ĆĆƸ¸¸±±±»»»ÉÉÉĽĽĽ¸¸¸ÉÉÉĹĹĹľľľşşş»»»»»»ĽĽĽľľľľľľżżżŔŔŔŔŔŔÂÂÂÂÂÂŔŔŔżżżÂÂÂĆĆĆĘĘĘÍÍÍÎÎÎŇŇŇ×××ŐŐŐÍÍÍÉÉÉÉÉÉĹĹĹßßßäääĘĘĘÂÂÂŔŔŔľľľ¬¬¬ĽĽĽĐĐĐĹĹĹĆĆĆĹĹĹ´´´µµµĐĐĐäääčččäääŐŐŐÔÔÔÔÔÔ×××ŮŮŮĚĚĚĂĂĂÇÇÇĐĐĐŰŰŰăăăâââŰŰŰŇŇŇÔÔÔÔÔÔÔÔÔÔÔÔ×××ÝÝÝÝÝÝ×××ÎÎÎĘĘĘÂÂÂĹĹĹĐĐĐĐĐĐĆĆĆĂĂĂşşşľľľÍÍÍŮŮŮŮŮŮÜÜÜßßßÜÜÜÔÔÔĐĐĐŕŕŕÝÝÝßßßŰŰŰ×××···ŔŔŔĆĆĆĹĹĹĽĽĽµµµµµµ»»»ľľľľľľ±±±±±±µµµ­­­©©©´´´żżżĂĂĂĂĂĂĆĆĆÉÉÉÉÉÉĂĂĂĽĽĽ···ĆĆĆĆĆĆÇÇÇĘĘĘÍÍÍĘĘĘżżż´´´żżżĂĂĂÇÇÇÉÉÉÉÉÉÇÇÇÇÇÇÇÇÇĹĹĹĂĂĂĘĘĘĐĐĐŇŇŇ···ľľľĽĽĽ¸¸¸ĆĆĆĘĘĘĚĚĚÇÇÇĂĂĂĚĚĚĘĘĘÎÎÎÍÍÍĚĚĚÉÉÉÉÉÉĂĂĂ···ŞŞŞŻŻŻ¤¤¤¨¨¨ľľľÍÍÍĹĹĹ···°°°»»»ĚĚĚŔŔŔĽĽĽşşşŻŻŻ···łłł¬¬¬łłł­­­±±±żżżÉÉÉĐĐĐĚĚĚÝÝÝÍÍÍĘĘĘŔŔŔ»»»ÂÂÂÂÂÂÂÂÂĆĆĆÇÇÇÝÝÝŐŐŐĐĐĐĹĹĹÉÉÉÇÇÇľľľ»»»¸¸¸¸¸¸¸¸¸···´´´±±±µµµ´´´­­­ŞŞŞşşşÎÎÎŐŐŐÍÍͱ±±łłł¸¸¸ÂÂÂĆĆĆÇÇÇÇÇÇÉÉÉľľľÂÂÂÂÂÂżżżÍÍÍĚĚĚ···ĽĽĽşşşÇÇÇŃŃŃŇŇŇĘĘĘĆĆƸ¸¸´´´¸¸¸ľľľşşşşşş¸¸¸¸¸¸ĂĂĂĂĂĂĂĂĂĂĂĂĘĘĘŐŐŐÔÔÔĂĂĂłłł­­­ĽĽĽĹĹĹĽĽĽ±±±ÂÂÂĹĹĹ»»»ĽĽĽĽĽĽľľľľľľżżżŔŔŔŔŔŔŔŔŔżżżÂÂÂÂÂÂĂĂĂÇÇÇÎÎÎÔÔÔÔÔÔŃŃŃÔÔÔĐĐĐĘĘĘÉÉÉĆĆĆĆĆĆĐĐĐŕŕŕŇŇŇÂÂÂĹĹĹŔŔŔşşş´´´żżżŐŐŐĹĹĹÂÂÂĆĆĆşşş­­­şşşÎÎÎÝÝÝęęęäääßßßŘŘŘŇŇŇŰŰŰŰŰŰŕŕŕßßßÝÝÝÝÝÝßßßÝÝÝŮŮŮŐŐŐŰŰŰÜÜÜßßßŘŘŘÔÔÔŮŮŮŰŰŰŇŇŇŐŐŐŇŇŇĹĹĹÂÂÂŃŃŃÔÔÔĚĚĚĘĘĘĆĆĆĹĹĹĐĐĐÜÜÜÝÝÝÜÜÜÜÜÜ×××ŃŃŃŐŐŐâââŮŮŮßßßŰŰŰÔÔÔ¸¸¸ŔŔŔĹĹĹĆĆĆżżż¸¸¸···»»»żżżĹĹŵµµŻŻŻŻŻŻŞŞŞ­­­¸¸¸ľľľÂÂÂĹĹĹÇÇÇĘĘĘĹĹĹĽĽĽ¸¸¸¸¸¸ĘĘĘÇÇÇĂĂĂĂĂĂÉÉÉÍÍÍĆĆĆĽĽĽşşşľľľĂĂĂĆĆĆĆĆĆĹĹĹĹĹĹĹĹĹŔŔŔĆĆĆÎÎÎÎÎÎÎÎη··żżżľľľĽĽĽĂĂĂÂÂÂĘĘĘĘĘĘĂĂĂĘĘĘÉÉÉÉÉÉÇÇÇĂĂĂĂĂĂÉÉÉÎÎÎĚĚĚĹĹĹľľľ¬¬¬˘˘˘­­­ŔŔŔÉÉÉÇÇÇĹĹĹĂĂĂÍÍÍ´´´ŻŻŻŻŻŻ¨¨¨´´´°°°©©©´´´©©©±±±ÂÂÂÂÂÂŔŔŔľľľÉÉÉĘĘĘĐĐĐľľľµµµÇÇÇÍÍÍĘĘĘĘĘĘÎÎÎÜÜÜŰŰŰŐŐŐĂĂĂĘĘĘżżż»»»şşş¸¸¸¸¸¸······µµµłłł­­­­­­¬¬¬±±±ĂĂĂŐŐŐŘŘŘŃŃŃĽĽĽ¸¸¸»»»ÂÂÂĹĹĹŔŔŔ»»»şşşżżżŔŔŔŔŔŔżżżÉÉÉÇÇÇ´´´µµµ°°°µµµĹĹĹÔÔÔÎÎÎľľľµµµ¸¸¸»»»şşşŻŻŻłłłµµµ±±±µµµ­­­łłł´´´»»»ĹĹĹÉÉÉĂĂø¸¸°°°¸¸¸żżżĂĂñ±±»»»ÂÂÂÇÇÇżżżľľľľľľżżżżżżŔŔŔŔŔŔŔŔŔÂÂÂżżżĹĹĹÉÉÉĘĘĘÎÎÎÔÔÔŐŐŐŃŃŃżżżŔŔŔŔŔŔĹĹĹĘĘĘÉÉÉĐĐĐßßßÉÉÉľľľľľľľľľľľľ»»»ĹĹĹÍÍÍÎÎÎÉÉÉĂĂĂĂĂĂŔŔŔ¸¸¸···Â´´´ŐŐŐŕŕŕäääâââÔÔÔÔÔÔŘŘŘÜÜÜŮŮŮ××××××ŰŰŰâââçççëëëßßßâââçççâââŮŮŮÜÜÜŰŰŰÎÎÎŘŘŘŘŘŘŃŃŃÉÉÉÍÍÍÔÔÔÔÔÔĐĐĐÇÇÇŔŔŔÇÇÇŘŘŘßßßäääćććŕŕŕŘŘŘÝÝÝăăăŮŮŮâââ×××ÎÎÎŔŔŔĆĆĆÂÂÂĽĽĽşşş¸¸¸şşşĽĽĽżżżŔŔŔ¸¸¸¸¸¸¸¸¸´´´···»»»¸¸¸ĽĽĽżżżĹĹĹĹĹĹĽĽĽµµµ¸¸¸ÂÂÂĆĆĆÉÉÉÉÉÉÉÉÉÍÍÍÎÎÎĂĂĂ´´´···»»»ŔŔŔÂÂÂÂÂÂżżżľľľĽĽĽŔŔŔĚĚĚÔÔÔÍÍÍĘĘĘşşşĹĹĹŔŔŔŔŔŔŔŔŔ»»»ÉÉÉÎÎÎĆĆĆÉÉÉĹĹĹÇÇÇÇÇÇĂĂĂ»»»»»»ĂĂĂĘĘĘÍÍÍĆĆĆşşş¬¬¬¦¦¦¬¬¬łłłłłł°°°µµµżżż­­­···ĽĽĽ­­­¬¬¬žžžÉÉÉŰŰŰÎÎÎĐĐĐŘŘŘÇÇÇŔŔŔÂÂÂŔŔŔÔÔÔâââĆĆƸ¸¸ŃŃŃŮŮŮŃŃŃóóóčččÜÜÜŇŇŇĐĐĐżżżĚĚĚşşş¸¸¸¸¸¸¸¸¸············µµµłłł©©©¤¤¤­­­ĆĆĆŰŰŰŰŰŰŃŃŃ°°°­­­°°°ĽĽĽĆĆĆĆĆĆÂÂÂÂÂÂŔŔŔżżżŔŔŔżżżĹĹĹĂĂĂ°°°ŻŻŻ¸¸¸­­­···ÔÔÔŘŘŘŔŔŔµµµ¸¸¸´´´´´´°°°ĹĹĹŇŇŇÍÍÍĹĹű±±···şşşşşş»»»ĂĂĂĚĚĚÉÉÉżżżłłłĽĽĽÉÉÉ´´´···ľľľÉÉÉÂÂÂżżżżżżżżżŔŔŔŔŔŔŔŔŔÂÂÂÂÂÂÂÂÂĘĘĘĐĐĐŃŃŃŇŇŇŐŐŐŃŃŃĘĘĘĂĂĂŔŔŔĹĹĹÍÍÍĘĘĘÂÂÂÂÂÂÍÍ͵µµşşşĂĂõµµ···şşşÎÎÎĐĐĐÂÂÂĐĐĐĚĚĚÂÂÂĹĹĹĆĆĆÂÂÂĂĂĂşşşŔŔŔ°°°şşşŰŰŰâââŰŰŰÔÔÔŮŮŮŰŰŰÝÝÝßßßÝÝÝŰŰŰŘŘŘ×××ÝÝÝÝÝÝâââŕŕŕßßßęęęíííÝÝÝ×××ŮŮŮŰŰŰŃŃŃÇÇÇŃŃŃŰŰŰŇŇŇŃŃŃĂĂĂĆĆĆÔÔÔÜÜÜââââââŰŰŰŰŰŰÝÝÝÝÝÝÔÔÔßßßĚĚĚĂĂĂÂÂÂĚĚĚŔŔŔ´´´±±±···ĽĽĽżżżľľľ¸¸¸µµµ¸¸¸¸¸¸±±±´´´¸¸¸łłłµµµ»»»ŔŔŔżżżµµµ±±±»»»ĘĘĘĂĂĂÂÂÂŔŔŔĂĂĂÇÇÇĚĚĚÍÍÍÍÍÍÇÇÇ»»»şşşľľľŔŔŔŔŔŔżżżÎÎÎĚĚĚÍÍÍĐĐĐĘĘĘŔŔŔżżżĹĹĹĂĂĂÂÂÂÂÂÂĹĹĹÉÉÉĘĘĘÉÉÉĆĆƸ¸¸żżżşşşşşşľľľ»»»ĚĚĚĚĚĚşşş¨¨¨ĄĄĄ¦¦¦¨¨¨©©©­­­łłł­­­ŻŻŻµµµ±±±©©©°°°Â»»»ĂĂĂĹĹĹľľľĂĂĂÉÉÉĂĂĂÂÂÂĘĘĘÉÉÉŮŮŮÎÎÎŇŇŇăăăÔÔÔŐŐŐÜÜÜŰŰŰŘŘŘŇŇŇÍÍÍÇÇÇÂÂÂľľľ¸¸¸······´´´łłłłłł´´´µµµĄĄĄ˘˘˘łłłĘĘĘŇŇŇ××××××ĐĐĐĄĄĄ°°°şşşľľľÂÂÂÇÇÇĆĆĆżżżŔŔŔľľľżżżŔŔŔÂÂÂÉÉÉÇÇÇ»»»­­­¬¬¬ĽĽĽ×××××׾ľľ°°°···łłł´´´±±±ĂĂĂßßßŰŰŰÉÉÉĘĘʵµµ······±±±»»»ÂÂÂľľľÍÍÍĆĆƱ±±şşşÇÇÇĚĚĚľľľłłłÇÇÇĹĹĹÂÂÂżżżŔŔŔĂĂĂĂĂĂĂĂĂĂĂĂĘĘĘĘĘĘÎÎÎÔÔÔŇŇŇĚĚĚÇÇÇÉÉÉĚĚĚÔÔÔÎÎÎÂÂÂŔŔŔÍÍÍĐĐĐÇÇÇĽĽĽżżż±±±¸¸¸ĚĚĚŃŃŃŃŃŃĘĘĘĘĘĘĘĘĘÉÉÉĆĆĆĹĹĹĹĹĹĹĹĹĆĆĆÍÍÍĘĘĘżżżĂĂĂĽĽĽ···×××îîîÔÔÔŘŘŘ×××ŘŘŘ×××ÝÝÝčččŰŰŰńńńííííííúúúńńńŕŕŕçççŕŕŕŕŕŕćććÝÝÝŮŮŮÜÜÜÍÍÍÂÂÂŃŃŃŘŘŘÔÔÔŔŔŔÂÂÂÝÝÝäääŮŮŮÝÝÝŃŃŃŮŮŮŕŕŕŮŮŮĘĘĘŔŔŔÂÂÂÇÇÇżżżÇÇDZ±±¸¸¸ÂÂÂĽĽĽĹĹĹ»»»ŔŔŔĽĽĽ¸¸¸şşş¸¸¸±±±±±±»»»şşşÂÂÂĘĘĘ···µµµĘĘĘÍÍÍÍÍÍĹĹĹÂÂÂżżżÂÂÂĆĆĆĘĘĘĘĘĘĘĘĘÉÉÉĂĂĂľľľşşş»»»ĽĽĽ»»»şşşĚĚĚÎÎÎŃŃŃÎÎÎĹĹĹľľľŔŔŔĆĆĆĹĹĹĂĂĂÂÂÂÂÂÂĂĂĂĹĹĹĹĹĹĂĂĂ»»»···»»»şşş»»»ľľľżżżÉÉÉŔŔŔ¸¸¸­­­©©©¨¨¨¤¤¤ˇˇˇˇˇˇ˘˘˘©©©°°°łłł±±±łłł¸¸¸żżżÂÂÂ×××ŮŮŮÇÇÇŔŔŔÂÂÂÂÂÂĹĹĹĆĆĆĚĚĚÜÜÜÍÍÍĐĐĐćććÝÝÝßßßŰŰŰŮŮŮ×××ŇŇŇĚĚĚĆĆĆŔŔŔľľľ´´´±±±±±±µµµ¸¸¸µµµ°°°ŞŞŞµµµ±±±żżżĐĐĐÔÔÔ××××××ŇŇŇŻŻŻ°°°···ľľľľľľşşş···¸¸¸ľľľ»»»żżżŔŔŔŔŔŔĆĆĆÇÇÇĽĽĽłłł±±±şşşĆĆĆÉÉÉŔŔŔ¸¸¸¸¸¸´´´şşş´´´ľľľŰŰŰâââŃŃŃÉÉÉ´´´łłł´´´¬¬¬¬¬¬±±±°°°ľľľľľľÂÂÂżżż´´´ĽĽĽĆĆĆżżżĚĚĚÍÍÍÇÇÇŔŔŔľľľĂĂĂÇÇÇÇÇÇĂĂĂĂĂĂÇÇÇÎÎÎŃŃŃĚĚĚÂÂÂŔŔŔĹĹĹŃŃŃĘĘĘÂÂÂŔŔŔÍÍÍŐŐŐÎÎÎżżż»»»ĽĽĽ···ĘĘĘÜÜÜŐŐŐÎÎÎĚĚĚÎÎÎĘĘĘĘĘĘÍÍÍÍÍÍĘĘĘĚĚĚĐĐĐÉÉÉÉÉÉÂÂÂĚĚĚÍÍÍÂÂÂľľľłłłćććßßßŮŮŮŕŕŕŰŰŰŮŮŮććććććíííęęęâââďďďöööíííďďďďďďăăăćććăăăßßßŮŮŮ×××ĐĐĐÉÉÉŐŐŐŘŘŘĚĚĚĂĂĂŇŇŇÜÜÜÜÜÜßßßÜÜÜŮŮŮÔÔÔĘĘĘĂĂĂŔŔŔĂĂĂÇÇÇÉÉÉÇÇÇŞŞŞŻŻŻ»»»¸¸¸ÂÂÂĽĽĽľľľ»»»»»»···­­­©©©­­­łłł¸¸¸ľľľÂµµµ»»»ÉÉÉĂĂĂÂÂÂĹĹĹŔŔŔĽĽĽżżżĹĹĹĘĘĘĚĚĚĚĚĚĚĚĚÉÉÉĂĂĂżżżĽĽĽ»»»şşşşşşĚĚĚŇŇŇÔÔÔĘĘĘľľľ»»»ÂÂÂÇÇÇĹĹĹĹĹĹĂĂĂŔŔŔżżżľľľżżżÂÂÂşşşľľľ»»»ľľľĽĽĽżżżÉÉÉĆĆĆľľľĽĽĽşşşµµµ±±±ŻŻŻ©©©˘˘˘¤¤¤ŻŻŻ±±±ŞŞŞ¬¬¬şşşĹĹĹÇÇǸ¸¸ŃŃŃŇŇŇÂÂÂĽĽĽĂĂĂÍÍÍÔÔÔżżżÎÎÎăăă××××××čččßßßŘŘŘŰŰŰŮŮŮ×××ŃŃŃĚĚĚĆĆĆÂÂÂżżż´´´ŻŻŻŻŻŻ´´´···łłł°°°ŻŻŻĘĘĘÇÇÇĐĐĐŘŘŘŘŘŘŘŘŘŘŘŘŐŐŐÉÉÉşşş´´´żżżĂĂĂşşşµµµşşş¸¸¸¸¸¸ľľľŔŔŔżżżĂĂĂÇÇÇŔŔŔşşşłłł±±±şşşŔŔŔżżżĽĽĽşşş···ŔŔŔşşş¸¸¸ŃŃŃŕŕŕ×××ĘĘĘĆĆĆÂÂÂÉÉÉĽĽĽ­­­°°°±±±···şşşÇÇÇÍÍÍşşş¸¸¸ĹĹĹŔŔŔĽĽĽÇÇÇÍÍÍÍÍÍÇÇÇĂĂĂÇÇÇĘĘĘĘĘĘÉÉÉÎÎÎŐŐŐÔÔÔÉÉÉľľľŔŔŔĘĘĘŃŃŃľľľşşşĹĹĹŮŮŮÔÔÔÇÇÇ»»»şşş¸¸¸»»»ŮŮŮćććŇŇŇĚĚĚÎÎÎĐĐĐĘĘĘÉÉÉĚĚĚĚĚĚÉÉÉĘĘĘÎÎÎŃŃŃŃŃŃÇÇÇÉÉÉĐĐĐŇŇŇŃŃŃĹĹĹÉÉÉŔŔŔ¸¸¸ľľľ»»»ĽĽĽŇŇŇÜÜÜäääăăăĐĐĐĆĆĆĂĂĂľľľÎÎÎçççÝÝÝëëëîîîćććŘŘŘÝÝÝŘŘŘÍÍÍŇŇŇŰŰŰ×××ÉÉÉĆĆĆŇŇŇŰŰŰŰŰŰÜÜÜŃŃŃĆĆĆŔŔŔÂÂÂĆĆĆÇÇÇÇÇÇÉÉÉĹĹĹŞŞŞŻŻŻµµµ­­­···»»»şşş¸¸¸żżżľľľ´´´ĽĽĽĆĆĆ´´´···şşş¸¸¸ĆĆĆÎÎÎĹĹĹĆĆĆĆĆĆŔŔŔ»»»»»»ŔŔŔÉÉÉÍÍÍĐĐĐÎÎÎÎÎÎĚĚĚÇÇÇĂĂĂŔŔŔÂÂÂĂĂĂÎÎÎŇŇŇĐĐĐĂĂĂ»»»ľľľĂĂĂĹĹĹĂĂĂĂĂĂĹĹĹÂÂÂżżżľľľżżżŔŔŔżżżÇÇÇľľľŔŔŔżżżżżżŃŃŃĹĹĹľľľľľľ¸¸¸´´´µµµşşş´´´©©©˘˘˘­­­°°°©©©ŞŞŞ···żżżżżżżżżÍÍÍÇÇÇĂĂĂĆĆĆĆĆĆÉÉÉĆĆĆ×××ÝÝÝëëëăăăäääîîîâââŰŰŰÜÜÜŰŰŰ×××ŇŇŇÍÍÍÉÉÉĹĹĹĂĂø¸¸···´´´±±±­­­ŻŻŻ»»»ÉÉÉŘŘŘŘŘŘÜÜÜßßßÝÝÝŰŰŰŮŮŮŘŘŘŐŐŐ»»»ŞŞŞ°°°¸¸¸···łłłłłł´´´µµµĽĽĽŔŔŔľľľÂÂÂĆĆĆĂĂĂĂĂĂłłł¬¬¬···żżż»»»şşşľľľĽĽĽĹĹĹĽĽĽ´´´ĂĂĂŇŇŇÔÔÔŃŃŃÉÉÉĹĹĹŇŇŇÇÇÇ­­­¬¬¬­­­©©©łłł°°°ĹĹĹÍÍÍŔŔŔÂÂÂÇÇÇŔŔŔľľľĘĘĘŃŃŃÎÎÎĚĚĚÎÎÎĐĐĐÍÍÍÔÔÔÔÔÔÔÔÔĐĐĐĆĆĆżżżĆĆĆĐĐĐĘĘʸ¸¸żżżĐĐĐÝÝÝÇÇÇľľľĽĽĽ¸¸¸şşşżżżŮŮŮŕŕŕÎÎÎÎÎÎŃŃŃÍÍÍĚĚĚÉÉÉÇÇÇÉÉÉÍÍÍĐĐĐĐĐĐŐŐŐÍÍÍżżż»»»ŔŔŔĘĘĘŃŃŃĐĐĐĘĘĘÎÎÎĘĘĘĘĘĘĂĂĂľľľÉÉÉĘĘĘżżżĂĂĂĹĹĹĚĚĚŇŇŇÎÎÎĐĐĐŮŮŮŇŇŇňňňřřřîîîÝÝÝÜÜÜŐŐŐŰŰŰŇŇŇŐŐŐŮŮŮŇŇŇĆĆĆĚĚĚÔÔÔŃŃŃĚĚĚĆĆĆŔŔŔĂĂĂĘĘĘÎÎÎĚĚĚÇÇÇĆĆĆĘĘĘŔŔŔĹĹĹżżż¬¬¬±±±ĽĽĽżżż»»»ŔŔŔľľľ´´´ÂÂÂÍÍÍľľľĂĂĂĆĆĆÂÂÂĹĹĹÎÎÎÉÉÉżżżĆĆĆÎÎÎÉÉÉŔŔŔĽĽĽľľľĂĂĂĘĘĘÎÎÎŃŃŃŇŇŇŇŇŇŃŃŃÍÍÍĚĚĚÍÍÍĐĐĐŃŃŃĐĐĐÇÇÇľľľ»»»ÂÂÂĂĂĂżżżżżżÂÂÂĆĆĆĆĆĆĂĂĂŔŔŔŔŔŔÂÂÂżżżĆĆĆşşşŔŔŔľľľżżż×××ĆĆĆĽĽĽ´´´¨¨¨˘˘˘ŞŞŞ´´´°°°ĄĄĄ©©©···ÇÇÇŇŇŇÔÔÔĐĐĐÇÇÇÂÂÂĆĆĆĘĘĘżżżÇÇÇŇŇŇĚĚĚÍÍÍÉÉÉßßßÔÔÔĐĐĐÍÍÍĐĐĐŐŐŐŇŇŇŐŐŐÜÜÜŰŰŰŘŘŘÔÔÔĐĐĐÍÍÍĘĘĘÉÉÉÂÂÂżżż¸¸¸°°°ŻŻŻ¸¸¸ĚĚĚÜÜÜÜÜÜŕŕŕâââââââââßßßŰŰŰŮŮŮÜÜÜĚĚĚ···­­­­­­±±±´´´´´´łłłłłł»»»ŔŔŔľľľżżżĆĆĆĹĹĹĘĘĘ»»»°°°łłł¸¸¸¸¸¸ĽĽĽŔŔŔÂÂÂĂĂĂĽĽĽ´´´µµµĽĽĽÉÉÉŘŘŘľľľĽĽĽŇŇŇĚĚ̱±±°°°°°°¦¦¦···©©©şşşŃŃŃĆĆĆşşşĂĂĂĆĆĆŔŔŔÂÂÂĂĂĂÇÇÇŃŃŃŘŘŘŐŐŐĚĚĚŘŘŘÎÎÎĹĹĹŔŔŔżżżŔŔŔÉÉÉŃŃŃÉÉɸ¸¸ĆĆĆŐŐŐßßßżżż¸¸¸ĽĽĽµµµŔŔŔĘĘĘŰŰŰŰŰŰĐĐĐÔÔÔŇŇŇĚĚĚŃŃŃĐĐĐÉÉÉÍÍÍŮŮŮÜÜÜÔÔÔĂĂĂľľľŔŔŔĚĚĚŘŘŘŰŰŰÔÔÔĐĐĐÇÇÇ×××ßßßëëëäääŇŇŇÎÎÎÍÍÍÍÍÍÍÍÍŘŘŘŕŕŕßßßßßßŕŕŕŕŕŕŇŇŇęęęńńńöööăăăßßßŐŐŐŕŕŕŐŐŐĚĚĚÔÔÔŰŰŰĐĐĐĘĘĘĚĚĚĆĆĆÂÂÂĂĂĂĆĆĆÍÍÍŃŃŃŃŃŃÍÍÍÉÉÉŔŔŔÇÇÇĹĹĹÉÉɬ¬¬©©©łłłľľľľľľÇÇÇŔŔŔ±±±ľľľĚĚĚżżżĆĆĆĘĘĘÉÉÉĚĚĚÍÍÍÂÂÂĂĂĂŇŇŇŮŮŮÔÔÔĚĚĚĂĂĂľľľżżżĹĹĹÉÉÉŃŃŃŇŇŇŐŐŐŐŐŐŇŇŇŃŃŃŃŃŃŇŇŇĐĐĐĘĘĘŔŔŔ»»»ľľľÂÂÂŔŔŔĽĽĽľľľŔŔŔĹĹĹÇÇÇĆĆĆĹĹĹ»»»ľľľ´´´żżżĽĽĽżżż×××ÇÇÇľľľ°°°ˇˇˇťťť¤¤¤ŞŞŞ©©©ˇˇˇźźź©©©ľľľŃŃŃŐŐŐĘĘĘŔŔŔľľľŔŔŔĂĂĂ­­­´´´ÂÂÂÉÉÉßßßčččäääŐŐŐÎÎÎÔÔÔŮŮŮŘŘŘŘŘŘÝÝÝŰŰŰŮŮŮ×××ÔÔÔŃŃŃÎÎÎÎÎÎÍÍÍÉÉÉĆĆĆ»»»łłłşşşĚĚĚŮŮŮÜÜÜÜÜÜââââââŕŕŕäääăăăßßßÜÜÜŕŕŕŕŕŕŐŐŐľľľŻŻŻ°°°µµµ¸¸¸łłł±±±şşşÂÂÂľľľżżżĹĹĹĆĆĆĚĚĚĘĘĘżżż±±±ŻŻŻşşşŔŔŔÂÂÂĂĂĂżżżşşşµµµŻŻŻŻŻŻŔŔŔŰŰŰľľľżżżŐŐŐĐĐĐĽĽĽÂÂÂŔŔŔ···łłł´´´···ĘĘĘÍÍÍ»»»···»»»ŔŔŔżżżľľľŔŔŔĆĆĆÍÍÍŇŇŇÔÔÔ×××ÉÉÉĽĽĽĽĽĽÂÂÂÇÇÇĐĐĐ×××ĚĚĚşşşÇÇÇŃŃŃâââŔŔŔ»»»¸¸¸´´´ÉÉÉŮŮŮäääÜÜÜŐŐŐŮŮŮĐĐĐŃŃŃ×××ŐŐŐÍÍÍÎÎÎÔÔÔĐĐĐĂĂĂşşş»»»ĘĘĘŇŇŇŇŇŇÍÍÍÂÂÂĆĆĆÉÉÉĚĚĚÎÎÎăăăŕŕŕĹĹĹĂĂĂĐĐĐëëëŕŕŕäääŰŰŰĘĘĘĐĐĐŰŰŰäääŰŰŰŮŮŮŕŕŕúúúäääçççÜÜÜŰŰŰŮŮŮĘĘĘĐĐĐÝÝÝŮŮŮĐĐĐÉÉÉÂÂÂĹĹĹÉÉÉÍÍÍĐĐĐĐĐĐÍÍÍĘĘĘÉÉÉÇÇÇĹĹĹżżżÂÂÂĂĂĂ···­­­±±±´´´żżżĘĘĘ°°°¸¸¸ÉÉÉÇÇÇĽĽĽÂÂÂĹĹĹĚĚĚÇÇÇŔŔŔŃŃŃŕŕŕŰŰŰŮŮŮŐŐŐĚĚĚÂÂÂżżżÂÂÂÇÇÇĐĐĐŃŃŃŇŇŇŃŃŃÎÎÎĚĚĚĘĘĘÉÉÉĚĚĚĂĂĂľľľľľľżżżľľľĽĽĽĽĽĽżżżŔŔŔÂÂÂĹĹĹĆĆĆĹĹĹÂÂÂŔŔŔ»»»¸¸¸ÇÇÇÂÂÂÂÂÂŇŇŇĹĹŸ¸¸ŻŻŻ¨¨¨¦¦¦©©©©©©¨¨¨¦¦¦¬¬¬ŻŻŻµµµżżżĂĂĂĹĹĹÇÇÇÍÍÍĂĂĂÍÍÍ°°°©©©łłłÂÂÂŕŕŕäääŇŇŇĐĐĐĐĐĐ××××××ŃŃŃŇŇŇŐŐŐ×××ŐŐŐŇŇŇŃŃŃĐĐĐĐĐĐĐĐĐĐĐĐÉÉÉĚĚ̵µµľľľŐŐŐÝÝÝ×××ÝÝÝăăăßßßŰŰŰăăăćććâââŕŕŕŰŰŰâââÝÝÝĘĘĘşşşµµµłłłŻŻŻµµµ±±±¸¸¸ÂÂÂżżżŔŔŔĹĹĹĹĹĹÉÉÉŃŃŃĐĐĐżżż´´´¸¸¸ľľľľľľżżżşşş···´´´ŻŻŻŻŻŻŔŔŔŐŐŐĂĂĂÂÂÂÎÎÎĹĹĹşşşÂÂÂŔŔŔşşşžžž­­­¬¬¬ĽĽĽÎÎÎÇÇÇĂĂĂŔŔŔľľľżżżÂÂÂÂÂÂşşş···ĆĆĆŘŘŘÉÉÉŔŔŔ»»»żżżÇÇÇÍÍÍÔÔÔŮŮŮĚĚĚľľľĘĘĘÍÍÍßßßĹĹĹŔŔŔ¸¸¸´´´ĚĚĚßßßčččŰŰŰŇŇŇŮŮŮĐĐĐŐŐŐÔÔÔÔÔÔ×××ÔÔÔĘĘĘĽĽĽłłłľľľÇÇÇŘŘŘŃŃŃĚĚĚĐĐĐŃŃŃÝÝÝĆĆĆÂÂÂżżżŐŐŐŰŰŰÉÉÉÔÔÔíííĐĐĐÍÍÍŰŰŰßßßäääęęęßßßŰŰŰŘŘŘŃŃŃŐŐŐöööäääëëëÝÝÝ×××ÜÜÜŇŇŇŃŃŃŮŮŮÜÜÜ×××ÎÎÎĆĆĆÇÇÇĘĘĘÎÎÎĐĐĐÎÎÎĚĚĚÉÉÉĆĆĆÎÎÎĚĚĚĹĹĹĂĂĂĘĘĘÇÇÇżżżŔŔŔłłłşşşľľľ···ŻŻŻłłł»»»ĽĽĽĆĆĆĆĆĆÇÇÇĐĐĐŔŔŔĽĽĽŇŇŇŘŘŘŐŐŐŮŮŮŮŮŮŇŇŇÇÇÇÂÂÂĹĹĹĘĘĘÎÎÎĐĐĐÎÎÎÍÍÍĘĘĘĹĹĹÂÂÂżżżĆĆĆŔŔŔżżżŔŔŔżżżşşşşşşżżżÂÂÂŔŔŔŔŔŔŔŔŔĂĂĂĂĂĂŔŔŔżżżÍÍÍÂÂÂĂĂĂŃŃŃĘĘĘĹĹĹÎÎά¬¬©©©ŞŞŞŻŻŻ­­­¨¨¨¨¨¨¬¬¬´´´łłłŻŻŻŻŻŻłłłĽĽĽÇÇÇĐĐĐľľľŐŐŐŔŔŔ¸¸¸ĂĂĂĐĐĐßßßÍÍÍÍÍÍŇŇŇÔÔÔŇŇŇÍÍÍĘĘĘŃŃŃŐŐŐŇŇŇŃŃŃĐĐĐÎÎÎÎÎÎÎÎÎĐĐĐĐĐĐĆĆĆŃŃŃĘĘĘ···şşşŃŃŃÝÝÝŘŘŘŕŕŕäääÜÜÜŘŘŘâââçççääääääâââăăăâââŮŮŮŇŇŇĘĘĘĽĽĽŻŻŻ···±±±¸¸¸ÂÂÂŔŔŔŔŔŔĹĹĹĹĹĹĹĹĹĐĐĐŘŘŘŇŇŇ···µµµşşşĽĽĽ···´´´´´´±±±µµµÂÂÂĐĐĐĐĐĐĚĚĚÍÍÍĽĽĽ´´´żżżĽĽĽ¸¸¸¦¦¦¬¬¬˘˘˘ŻŻŻżżżĆĆĆĐĐĐÇÇÇżżżĽĽĽŔŔŔĂĂĂşşş±±±»»»ÎÎεµµłłłµµµľľľĆĆĆÉÉÉÎÎÎŇŇŇÉÉÉżżżĐĐĐĘĘĘÜÜÜĂĂĂĆĆĆľľľ···ĘĘĘÜÜÜćććŐŐŐĘĘĘŐŐŐŇŇŇŃŃŃĚĚĚŇŇŇâââăăăĐĐĐľľľ»»»ÂÂÂÉÉÉŐŐŐÇÇÇĹĹĹÎÎÎĂĂĂżżżĂĂĂĆĆĆŔŔŔÎÎÎŇŇŇĹĹĹĘĘĘŰŰŰÎÎÎŐŐŐŕŕŕÝÝÝââââââŇŇŇŮŮŮÎÎÎŐŐŐÔÔÔďďďăăăëëëŮŮŮŰŰŰßßßŰŰŰŐŐŐŐŐŐŮŮŮŰŰŰÔÔÔÍÍÍĹĹĹÇÇÇĚĚĚĐĐĐŃŃŃÎÎÎÉÉÉĹĹĹĽĽĽżżżżżż»»»ŔŔŔ»»»żżż±±±±±±ŻŻŻ±±±żżżĘĘĘĚĚĚĘĘĘÉÉÉĹĹĹÇÇÇŇŇŇÂÂÂÂÂÂÜÜÜŘŘŘ×××ÔÔÔÔÔÔŐŐŐÎÎÎĹĹĹÂÂÂĹĹĹĘĘĘĂĂĂĹĹĹĆĆĆÂÂÂĆĆĆĘĘĘĂĂĂĆĆĆĂĂĂŔŔŔżżżŔŔŔÂÂÂŔŔŔżżżľľľżżżĂĂĂľľľ»»»ĚĚĚŐŐŐĚĚĚşşş­­­°°°···±±±¬¬¬°°°łłłŞŞŞŞŞŞ©©©©©©ŞŞŞ­­­ŻŻŻŻŻŻłłł±±±······­­­ĹĹĹÂÂÂÇÇÇŕŕŕŮŮŮŃŃŃĐĐĐÔÔÔŐŐŐŇŇŇÍÍÍÔÔÔÔÔÔŇŇŇŇŇŇŇŇŇŇŇŇŇŇŇŇŇŇŇŇŇŇŇŇŃŃŃĐĐĐÎÎÎÎÎÎÎÎÎĐĐĐĚĚĚĐĐĐÍÍÍżżż»»»ŇŇŇçççŰŰŰććććććâââäääŕŕŕâââîîîčččęęęęęęçççääääääßßßĐĐĐżżż°°°łłłşşşÂÂÂĂĂĂŔŔŔŔŔŔĂĂĂÇÇÇŔŔŔÉÉÉĐĐĐĂĂø¸¸¸¸¸···´´´±±±°°°łłłłłłłłł»»»ĹĹĹĹĹĹĹĹĹÇÇÇĂĂĂ»»»şşşµµµ©©©źźź¤¤¤©©©ŻŻŻ´´´ľľľÇÇÇÎÎÎĆĆƸ¸¸ĽĽĽĹĹĹľľľ´´´±±±°°°łłłµµµ´´´şşşĹĹĹĆĆĆÇÇÇÔÔÔĘĘĘľľľÇÇÇŇŇŇŕŕŕĚĚĚĂĂĂľľľÂÂÂĆĆĆßßßăăăÔÔÔÍÍÍÉÉÉÎÎÎÍÍÍ×××ÜÜÜÜÜÜŘŘŘĘĘĘľľľżżżÍÍÍÜÜÜĘĘĘĘĘĘĐĐĐÂÂÂŔŔŔşşşŃŃŃÎÎÎÍÍÍĐĐĐŇŇŇÔÔÔĐĐĐĚĚĚĚĚĚâââćććçççÝÝÝŐŐŐÝÝÝŮŮŮÔÔÔŰŰŰÎÎÎŔŔŔčččŕŕŕçççŘŘŘâââŕŕŕŐŐŐżżżŮŮŮÜÜÜÔÔÔÍÍÍÂÂÂßßßÎÎÎĆĆĆĆĆĆĂĂĂĘĘʸ¸¸żżż¸¸¸···ľľľĂĂĂĂĂĂĂĂĂĹĹĹ©©©ŻŻŻ°°°ĂĂĂĚĚĚĂĂĂĘĘĘÇÇÇÇÇÇÇÇÇĆĆĆĹĹĹĆĆĆĘĘĘŃŃŃŐŐŐżżżľľľľľľŔŔŔŔŔŔżżżÂÂÂĆĆĆÉÉÉĂĂĂÇÇÇĚĚĚÇÇÇÇÇÇÇÇÇŔŔŔżżżÂÂÂĆĆĆĘĘĘĚĚĚÉÉÉĹĹĹŔŔŔĹĹĹżżż»»»ľľľĹĹĹÍÍÍĂĂĂ°°°¸¸¸¬¬¬ŻŻŻµµµ°°°¬¬¬°°°łłł­­­¬¬¬ŞŞŞŞŞŞ¬¬¬­­­ŻŻŻ°°°¸¸¸···şşş¸¸¸¬¬¬ĂĂĂÇÇÇĐĐĐÝÝÝÝÝÝŕŕŕćććčččäääŮŮŮŃŃŃŐŐŐŐŐŐŐŐŐÔÔÔÔÔÔŇŇŇŃŃŃŃŃŃŇŇŇŇŇŇŃŃŃĐĐĐĐĐĐĐĐĐĐĐĐŃŃŃĚĚĚĚĚĚĘĘĘŔŔŔľľľĐĐĐääääääçççăăăâââëëëäääŕŕŕííííííďďďíííçççŕŕŕŕŕŕâââŰŰŰŇŇҸ¸¸±±±°°°¸¸¸żżżżżżżżżĂĂĂĆĆĆÇÇÇĚĚĚÇÇÇĽĽĽ»»»ĽĽĽ···łłłŻŻŻ°°°······±±±¬¬¬ŞŞŞ¸¸¸···żżżŔŔŔ´´´©©©¤¤¤ťťť˘˘˘¤¤¤¨¨¨¬¬¬­­­łłłŔŔŔÎÎθ¸¸ĽĽĽĹĹĹľľľµµµ´´´łłłłłłµµµµµµşşşĂĂĂĹĹĹÇÇÇÔÔÔĐĐĐżżżĆĆĆŃŃŃßßßĚĚĚĹĹĹŔŔŔĽĽĽľľľŐŐŐßßßŰŰŰŮŮŮŐŐŐ×××ĐĐĐŮŮŮŐŐŐĘĘĘĆĆĆÂÂÂŔŔŔĆĆĆĐĐĐĐĐĐŔŔŔÉÉÉÎÎÎĹĹĹĘĘĘĐĐĐÍÍÍĚĚĚĘĘĘĚĚĚÎÎÎĐĐĐÍÍÍĚĚĚÉÉÉÔÔÔŇŇŇ×××ŐŐŐŐŐŐăăăâââçççßßßŘŘŘĚĚĚëëëëëëäääĐĐĐŮŮŮâââŰŰŰÉÉÉßßßŕŕŕÔÔÔÉÉÉçççóóóŰŰŰÎÎÎĆĆĆşşşĂĂĂżżżĚĚĚŔŔŔşşşżżżÉÉÉĚĚĚÉÉÉĆĆĆĆĆĆĘĘĘĹĹĹÉÉÉĆĆĆŔŔŔĘĘĘĘĘĘĘĘĘÍÍÍĐĐĐĐĐĐĚĚĚÇÇÇĹĹĹĹĹĹĘĘĘÉÉÉĹĹĹŔŔŔĂĂĂÉÉÉÍÍÍÎÎÎĘĘĘĆĆĆÇÇÇÉÉÉĆĆĆĹĹĹĂĂĂĽĽĽżżżĹĹĹÍÍÍŇŇŇŇŇŇĐĐĐĚĚĚÇÇÇĘĘĘÉÉÉĹĹĹÇÇÇÎÎÎÉÉÉşşşŻŻŻ···­­­ŻŻŻ´´´±±±­­­°°°łłł±±±°°°ŻŻŻ¬¬¬¬¬¬­­­±±±łłłşşş······şşşŻŻŻĹĹĹÍÍÍŮŮŮÜÜÜŘŘŘÔÔÔŇŇŇŐŐŐŘŘŘŘŘŘŮŮŮŮŮŮŮŮŮŮŮŮŘŘŘ×××ÔÔÔŃŃŃĐĐĐÔÔÔŇŇŇŃŃŃĐĐĐĐĐĐŃŃŃŇŇŇŇŇŇÎÎÎÉÉÉĆĆĆŔŔŔşşşżżżĐĐĐŕŕŕčččăăăäääńńńęęęŕŕŕîîîňňňńńńďďďčččăăăăăăććććććăăăŃŃŃżżż´´´şşşŔŔŔżżżľľľŔŔŔĆĆĆÍÍÍÎÎÎŔŔŔµµµľľľŔŔŔµµµ¸¸¸±±±°°°µµµ»»»¸¸¸±±±¬¬¬¨¨¨ĄĄĄ°°°···¬¬¬¤¤¤ĄĄĄ¨¨¨©©©¨¨¨¨¨¨ŞŞŞ©©©­­­ĽĽĽÍÍÍľľľ¸¸¸ľľľĂĂĂľľľ···µµµµµµłłłµµµ···şşşŔŔŔĂĂĂĘĘĘŐŐŐŘŘŘĹĹĹÉÉÉÔÔÔäääĐĐĐÉÉÉĆĆĆľľľşşşĚĚĚŘŘŘÝÝÝŕŕŕŮŮŮŘŘŘŐŐŐŰŰŰÎÎλ»»µµµ»»»ÂÂÂĚĚĚÝÝÝŃŃŃŔŔŔÇÇÇÍÍÍŔŔŔĆĆĆŮŮŮÇÇÇÇÇÇÇÇÇÇÇÇĘĘĘĚĚĚĚĚĚĚĚĚŃŃŃÔÔÔĐĐĐŐŐŐŐŐŐŃŃŃŐŐŐŐŐŐäääĐĐĐŘŘŘĐĐĐŕŕŕňňňćććŮŮŮÜÜÜäääŰŰŰĚĚĚŰŰŰÝÝÝŮŮŮŇŇŇçççëëëÜÜÜÝÝÝŐŐŐĂĂĂÎÎÎŐŐŐŐŐŐĘĘĘŔŔŔŔŔŔĂĂĂĹĹĹĂĂĂĂĂĂŔŔŔĘĘĘĘĘĘÉÉÉĂĂĂżżżÇÇÇÇÇÇĹĹĹĘĘĘĐĐĐŇŇŇĐĐĐĚĚĚÇÇÇĆĆĆŇŇŇŇŇŇĚĚĚĂĂĂĹĹĹÍÍÍÎÎÎĚĚĚĐĐĐĘĘĘĹĹĹÂÂÂŔŔŔŔŔŔŔŔŔżżżÉÉÉĚĚĚĐĐĐŃŃŃĐĐĐĐĐĐŃŃŃŃŃŃÍÍÍĐĐĐĚĚĚÍÍÍŃŃŃĹĹŸ¸¸ĽĽĽ¸¸¸±±±°°°´´´´´´±±±łłł´´´···µµµ±±±ŻŻŻ­­­°°°łłł···µµµ±±±°°°ĽĽĽ¸¸¸ĚĚĚŃŃŃŮŮŮÔÔÔÔÔÔÔÔÔŐŐŐŐŐŐ×××ŮŮŮŮŮŮÝÝÝÝÝÝÝÝÝÜÜÜŮŮŮ×××ŇŇŇĐĐĐÔÔÔŃŃŃĐĐĐĐĐĐŃŃŃŇŇŇŇŇŇŃŃŃĘĘĘÂÂÂÂÂÂŔŔŔ»»»···ĂĂĂăăăęęęčččęęęńńńčččăăăóóóöööďďďďďďďďďíííęęęčččçççäääÔÔÔ···ľľľÂÂÂľľľĽĽĽÂÂÂĂĂĂÍÍÍĚĚĚżżż···ĽĽĽľľľµµµşşş´´´łłłµµµ»»»ĽĽĽ¸¸¸łłł­­­¨¨¨ŞŞŞ¬¬¬¨¨¨¬¬¬µµµ···­­­­­­ŞŞŞ©©©¬¬¬µµµŔŔŔĆĆĆ»»»ĽĽĽŔŔŔĂĂĂľľľ¸¸¸µµµµµµ´´´µµµ¸¸¸»»»żżżĹĹĹÍÍÍŐŐŐŮŮŮÇÇÇĐĐĐÜÜÜëëëŐŐŐÎÎÎĘĘĘĹĹĹżżżĘĘĘŃŃŃ×××ŘŘŘŃŃŃÔÔÔŰŰŰŰŰŰÎÎÎľľľşşş¸¸¸żżżĚĚĚăăăŮŮŮÉÉÉĆĆĆÎÎλ»»×××ĹĹĹĹĹĹĹĹĹĆĆĆÇÇÇÉÉÉĚĚĚÎÎÎÍÍÍÍÍÍÎÎÎ×××ŮŮŮŐŐŐŮŮŮßßßŐŐŐľľľÔÔÔÉÉÉÇÇÇăăă××××××ÝÝÝŕŕŕŐŐŐŃŃŃŰŰŰŘŘŘŰŰŰÜÜÜćććčččâââćććÜÜÜĘĘĘÔÔÔÜÜÜŐŐŐŇŇŇĚĚĚ···´´´¸¸¸żżżÂÂÂÉÉÉÇÇÇŔŔŔĽĽĽľľľÂÂÂżżżÂÂÂĆĆĆĘĘĘÍÍÍÍÍÍÎÎÎŃŃŃŇŇŇÍÍÍÎÎÎĚĚĚĆĆĆÉÉÉĐĐĐŃŃŃÍÍÍÍÍÍĘĘĘĆĆĆĹĹĹÇÇÇÉÉÉÉÉÉĘĘĘĐĐĐŃŃŃŃŃŃĐĐĐÎÎÎÎÎÎŃŃŃÔÔÔÎÎÎÎÎÎÇÇÇĘĘĘÎÎÎŔŔŔ´´´şşşşşşµµµłłłµµµ¸¸¸¸¸¸µµµ¸¸¸şşş¸¸¸···łłł°°°±±±···»»»ĽĽĽ´´´±±±ÉÉÉĘĘĘŐŐŐŇŇŇŃŃŃÎÎÎŇŇŇŮŮŮßßßŕŕŕßßßÜÜÜŰŰŰŕŕŕŕŕŕŕŕŕßßßÜÜÜŘŘŘŇŇŇŃŃŃŇŇŇŃŃŃÎÎÎĐĐĐŃŃŃŃŃŃĐĐĐÎÎÎĘĘĘÂÂÂĆĆĆĂĂĂżżżµµµ»»»ăăăëëëňňňńńńďďďçççęęęúúúöööńńńňňňňňňňňňîîîçççăăăâââ»»»´´´´´´ĽĽĽŔŔŔĽĽĽľľľĹĹĹÂÂÂĆĆĆÇÇÇĹĹĹżżżşşş···¸¸¸´´´µµµ¸¸¸şşş»»»şşş´´´ŻŻŻłłłŻŻŻ¬¬¬©©©ŻŻŻÂÂÂĚĚ̬¬¬­­­¨¨¨ĄĄĄ±±±ÂÂÂĂĂø¸¸¸¸¸ŔŔŔĹĹĹÂÂÂĽĽĽ¸¸¸´´´´´´´´´···şşşĽĽĽżżżÇÇÇĐĐĐŇŇŇŃŃŃÇÇÇÔÔÔßßßęęęÔÔÔÍÍÍÉÉÉÂÂÂÂÂÂĚĚĚÍÍÍÍÍÍÍÍÍĘĘĘŐŐŐÜÜÜÜÜÜŐŐŐĐĐĐĚĚĚżżż»»»ĹĹĹŃŃŃŮŮŮŃŃŃĂĂĂŃŃŃĚĚĚşşşŘŘŘĹĹĹĹĹĹĆĆĆĆĆĆÇÇÇĘĘĘÍÍÍÎÎÎÔÔÔĐĐĐŃŃŃŃŃŃÎÎÎĐĐĐŮŮŮčččŃŃŃżżżŰŰŰ×××ÜÜÜöööęęęîîî××××××ÎÎÎßßßăăăŐŐŐŘŘŘßßßííííííćććăăăŘŘŘŇŇŇÜÜÜŕŕŕŘŘŘŮŮŮŐŐŐÉÉÉĽĽĽ¸¸¸ĽĽĽĂĂĂÇÇÇĂĂĂżżż···ĽĽĽĘĘĘÎÎÎÎÎÎÇÇÇÉÉÉĘĘĘĚĚĚĘĘĘĚĚĚĐĐĐŃŃŃŃŃŃŇŇŇŇŇŇŃŃŃŇŇŇÔÔÔŇŇŇĐĐĐĆĆĆĚĚĚÍÍÍŃŃŃŘŘŘŘŘŘÔÔÔŐŐŐŇŇŇŇŇŇŇŇŇŇŇŇĐĐĐÎÎÎÎÎÎĐĐĐĐĐĐŃŃŃŇŇŇĐĐĐÉÉÉ»»»µµµ»»»»»»şşşµµµµµµĽĽĽĽĽĽ¸¸¸»»»şşş»»»şşş···´´´µµµşşşżżżĆĆĆľľľ¸¸¸×××ŘŘŘŮŮŮŇŇŇĘĘĘĐĐĐŃŃŃŃŃŃŇŇŇŐŐŐŮŮŮÝÝÝßßßŕŕŕŕŕŕßßßÝÝÝŮŮŮŐŐŐŇŇŇĐĐĐŃŃŃÎÎÎÎÎÎĐĐĐŃŃŃĐĐĐĚĚĚÇÇÇľľľĽĽĽÂ»»»ĽĽĽ¸¸¸¸¸¸ćććîîîřřřöööńńńčččďďď˙˙˙őőőőőőóóóňňňňňňíííćććââââââłłłµµµĽĽĽÂÂÂÂÂÂżżżŔŔŔĹĹĹŔŔŔĂĂĂĆĆĆĚĚĚĘĘĘ»»»µµµĽĽĽşşş»»»»»»»»»ĽĽĽÂÂÂĂĂĂÂÂÂĽĽĽ»»»¸¸¸łłłşşşÍÍÍÎÎÎşşş©©©¨¨¨˘˘˘ĄĄĄµµµĆĆĆŔŔŔŻŻŻµµµĂĂĂÉÉÉÂÂÂĽĽĽ¸¸¸´´´´´´······»»»żżżÂÂÂĚĚĚŇŇŇĐĐĐÉÉÉÉÉÉŘŘŘŘŘŘÝÝÝĘĘĘÇÇÇĂĂĂľľľĂĂĂĐĐĐÎÎÎĚĚĚÉÉÉÇÇÇŮŮŮŮŮŮÝÝÝÜÜÜÜÜÜŰŰŰĚĚĚľľľĽĽĽÂÂÂŇŇŇŮŮŮĂĂĂÎÎÎĐĐĐ···ÔÔÔĆĆĆĹĹĹĆĆĆÇÇÇĘĘĘĚĚĚÍÍÍÍÍÍĆĆĆĆĆĆĐĐĐÎÎÎÍÍÍŇŇŇŘŘŘćććÎÎÎÂÂÂÍÍÍÉÉÉÝÝÝäääŇŇŇÎÎÎ×××ŐŐŐÇÇÇßßßßßßÔÔÔÝÝÝčččćććććććććäääßßßŕŕŕăăăÝÝÝŰŰŰŰŰŰŘŘŘŇŇŇĐĐĐĐĐĐĐĐĐÍÍ͸¸¸´´´şşşĽĽĽÉÉÉ×××ÔÔÔŇŇŇĆĆĆÉÉÉÍÍÍÍÍÍÍÍÍĚĚĚĚĚĚÍÍÍŇŇŇŃŃŃŇŇŇÔÔÔŃŃŃĚĚĚÉÉÉÉÉÉÉÉÉĐĐĐŃŃŃŐŐŐÝÝÝÜÜÜŐŐŐŐŐŐŐŐŐÔÔÔŇŇŇŃŃŃŃŃŃŃŃŃĐĐĐĐĐĐÔÔÔÔÔÔŐŐŐÎÎÎżżż···ĽĽĽŔŔŔşşş»»»´´´´´´ĽĽĽľľľşşş»»»şşş»»»ĽĽĽ»»»¸¸¸¸¸¸ĽĽĽÂÂÂĹĹĹżżż»»»ŰŰŰŘŘŘÔÔÔŃŃŃÍÍÍÎÎÎĐĐĐŇŇŇŐŐŐŮŮŮÜÜÜÝÝÝÝÝÝÝÝÝÜÜÜŰŰŰŘŘŘŐŐŐŃŃŃĐĐĐÎÎÎÎÎÎÍÍÍÍÍÍĐĐĐŃŃŃÎÎÎÇÇÇŔŔŔşşşľľľÂ´´´ĽĽĽÂÂÂÂÂÂńńńňňňřřřřřřřřřńńńňňňüüüňňňóóóńńńńńńóóóńńńęęęääääääşşşŔŔŔĹĹĹĹĹĹĹĹĹĹĹĹĂĂĂÂÂÂŔŔŔĆĆĆĘĘĘŃŃŃŃŃŃÂÂÂşşşÂÂÂĹĹĹŔŔŔ»»»şşşÂÂÂĐĐĐŐŐŐŇŇŇĐĐĐÍÍÍĘĘĘĹĹĹÂÂÂÉÉÉĂĂĂ°°°­­­ĄĄĄ˘˘˘¬¬¬ĽĽĽÂÂÂşşş°°°°°°ĹĹĹĘĘĘŔŔŔĽĽĽşşşµµµµµµ¸¸¸···ĽĽĽŔŔŔĹĹĹĐĐĐŐŐŐÍÍÍĚĚĚÔÔÔßßßŇŇŇÎÎÎŔŔŔĆĆĆĹĹĹÇÇÇĐĐĐŰŰŰ×××ŃŃŃÉÉÉÂÂÂŇŇŇŐŐŐâââŕŕŕŮŮŮŰŰŰ×××ĆĆƸ¸¸ŔŔŔÇÇÇÝÝÝÉÉÉĆĆĆĚĚ̸¸¸ĐĐĐĆĆĆĹĹĹĹĹĹÇÇÇĚĚĚÍÍÍĚĚĚĘĘĘÉÉÉĚĚĚ×××ŃŃŃĐĐĐÔÔÔĚĚĚÎÎÎŃŃŃÎÎÎĂĂĂ»»»ăăăŮŮŮŇŇŇŇŇŇŘŘŘŮŮŮĆĆĆŮŮŮŘŘŘŮŮŮęęęńńńëëëăăăäääćććŕŕŕÝÝÝ×××ĚĚĚŃŃŃŐŐŐŘŘŘ××××××ŮŮŮ×××ŃŃŃ´´´łłłĹĹĹÍÍÍŇŇŇĐĐĐżżżĽĽĽĹĹĹÇÇÇĚĚĚÍÍÍÍÍÍĚĚĚĚĚĚÍÍÍŃŃŃĐĐĐŇŇŇŐŐŐŇŇŇĘĘĘÉÉÉÎÎÎŃŃŃŐŐŐŃŃŃŃŃŃŘŘŘŐŐŐÎÎÎŃŃŃŰŰŰŐŐŐĐĐĐÎÎÎĐĐĐŇŇŇÔÔÔÔÔÔŰŰŰĘĘĘÂÂÂşşşłłłşşşŔŔŔ»»»¸¸¸»»»´´´łłłĽĽĽľľľ¸¸¸şşş¸¸¸ĽĽĽľľľĽĽĽşşşşşşżżżĂĂĂ»»»şşş···ŘŘŘŃŃŃĚĚĚĐĐĐŇŇŇĘĘĘĚĚĚÎÎÎŇŇŇ×××ŮŮŮŮŮŮŘŘŘŰŰŰŮŮŮ×××ÔÔÔĐĐĐÎÎÎÍÍÍĚĚĚÍÍÍĚĚĚĚĚĚÎÎÎŃŃŃÍÍÍĹĹĹĽĽĽßßßâââÜÜÜżżżÂÂÂĹĹĹľľľčččőőőöööööö˙˙˙řřřňňňůůůńńńíííëëëďďďřřřřřřďďďćććăăă···ľľľżżżľľľŔŔŔÇÇÇÇÇÇŔŔŔŔŔŔĘĘĘÎÎÎŇŇŇÔÔÔÇÇÇżżżĆĆĆĆĆĆÂÂÂĽĽĽľľľÉÉÉŇŇŇÎÎÎĂĂĂĆĆĆĂĂĂÇÇÇĚĚĚĚĚĚŃŃŃŇŇŇĘĘĘ´´´¦¦¦ĄĄĄ···ÂÂÂľľľ···¸¸¸¬¬¬ĂĂĂĘĘĘŔŔŔľľľ»»»¸¸¸¸¸¸şşş···ĽĽĽÂÂÂÇÇÇŇŇŇ×××ĚĚĚŐŐŐßßßçççĐĐĐĆĆĆĽĽĽÉÉÉÉÉÉ×××ÝÝÝçççŕŕŕ×××ÉÉÉşşşĆĆĆŇŇŇäääŕŕŕĐĐĐŐŐŐÝÝÝÎÎθ¸¸ľľľşşşÜÜÜÍÍÍľľľÉÉÉľľľÔÔÔĆĆĆĂĂĂĂĂĂĆĆĆĚĚĚÍÍÍĘĘĘĆĆĆĘĘĘÇÇÇĐĐĐÉÉÉĐĐĐÝÝÝ×××ŘŘŘßßßçççĘĘĘ···ăăăÎÎÎ×××âââĐĐĐÜÜÜĘĘĘÝÝÝŰŰŰăăăńńńëëëńńńÜÜÜŘŘŘŮŮŮ××××××ŇŇŇĚĚĚÂÂÂÎÎÎŘŘŘ×××ŃŃŃŃŃŃĐĐĐÎÎδ´´´´´ĘĘĘÔÔÔÔÔÔÎÎÎľľľŔŔŔĚĚĚĚĚĚĚĚĚĘĘĘÇÇÇÇÇÇÉÉÉĚĚĚĐĐĐĘĘĘŃŃŃŐŐŐĚĚĚÉÉÉŇŇŇŘŘŘŐŐŐŃŃŃĚĚĚÉÉÉĘĘĘÍÍÍĐĐĐŃŃŃŐŐŐŐŐŐÔÔÔÔÔÔÔÔÔŐŐŐŘŘŘŘŘŘĚĚĚ»»»···şşş¸¸¸»»»ĽĽĽµµµ´´´´´´µµµ¸¸¸»»»ĽĽĽ¸¸¸µµµ»»»ĽĽĽľľľżżżżżżżżżĂĂĂÇÇÇĽĽĽşşşÍÍÍăăăÔÔÔÔÔÔĘĘĘŇŇŇŐŐŐÎÎÎŃŃŃŘŘŘŮŮŮßßßăăăÜÜÜŐŐŐÔÔÔŃŃŃÍÍÍÍÍÍÍÍÍĘĘĘÇÇÇĚĚĚĘĘĘÉÉÉĚĚĚŃŃŃŇŇŇĘĘĘľľľâââäääâââćććçççíííóóóăăăóóóőőőîîîčččńńńóóóďďďďďďęęęďďďöööüüü˙˙˙ůůůńńńęęęäääľľľĹĹĹĂĂĂĂĂĂĐĐĐĆĆĆĹĹĹĆĆĆĚĚĚĚĚĚĘĘĘĐĐĐ···ĽĽĽÂÂÂĹĹĹĆĆĆżżżĂĂĂŐŐŐŰŰŰÉÉÉşşş»»»ŔŔŔĹĹĹÇÇÇĆĆĆĆĆĆĘĘĘÎÎÎłłłŻŻŻ­­­´´´ľľľŔŔŔşşş±±±­­­»»»ÇÇÇÉÉÉĹĹĹÂÂÂÂÂÂŔŔŔżżżľľľÂÂÂÉÉÉÔÔÔÜÜÜŇŇŇĹĹĹÔÔÔčččŇŇŇÉÉÉÇÇÇÂÂÂŘŘŘÝÝÝňňňęęęçççčččŕŕŕŇŇŇĚĚĚĐĐĐÝÝÝÝÝÝĐĐĐŇŇŇĘĘĘĚĚĚŘŘصµµľľľĽĽĽÍÍÍŃŃŃżżżÍÍÍĆĆĆÔÔÔÍÍÍĘĘĘÇÇÇÇÇÇĘĘĘĘĘĘÉÉÉĆĆĆÉÉÉÎÎÎÎÎÎĐĐĐĚĚĚŇŇŇäääÝÝÝŇŇŇßßßŔŔŔĽĽĽćććçççĐĐĐŐŐŐÎÎÎćććÇÇÇŰŰŰŘŘŘíííńńńăăăŰŰŰŘŘŘŐŐŐÔÔÔŇŇŇŃŃŃÍÍÍĘĘĘÉÉÉĂĂĂĆĆĆĆĆĆĹĹĹÔÔÔĐĐĐ°°°°°°żżżŔŔŔĚĚĚĘĘʸ¸¸»»»ŔŔŔÇÇÇÍÍÍÎÎÎĹĹĹÉÉÉĚĚĚĹĹĹĐĐĐÎÎÎĚĚĚÍÍÍĘĘĘŔŔŔĹĹĹŇŇŇŘŘŘĐĐĐÍÍÍĘĘĘĘĘĘĚĚĚÎÎÎĐĐĐĐĐĐŇŇŇÔÔÔÔÔÔÔÔÔŐŐŐŐŐŐŐŐŐŐŐŐĚĚĚşşş´´´······¸¸¸»»»µµµ´´´´´´µµµ¸¸¸»»»»»»¸¸¸µµµ···şşşĽĽĽĽĽĽľľľŔŔŔÂÂÂÂÂÂĽĽĽŔŔŔŃŃŃŕŕŕŐŐŐŐŐŐÉÉÉŇŇŇŐŐŐŇŇŇŮŮŮßßßŰŰŰŰŰŰÜÜÜŐŐŐ×××ÔÔÔĚĚĚżżż¸¸¸ĽĽĽĆĆĆÍÍÍÉÉÉĘĘĘÇÇÇÉÉÉÉÉÉÇÇÇĂĂĂĹĹĹííííííćććçççęęęíííčččĚĚĚŕŕŕíííîîîçççčččęęęęęęíííëëëíííîîîňňňööööööóóóďďďŕŕŕ»»»ĂĂĂÇÇÇÇÇÇŃŃŃÇÇÇÇÇÇÉÉÉÍÍÍĚĚĚÉÉÉÍÍ͵µµ»»»ÂÂÂŔŔŔĂĂĂĹĹĹÍÍÍŮŮŮÔÔÔĹĹĹľľľĽĽĽĂĂĂÇÇÇÉÉÉÉÉÉÉÉÉĘĘĘĘĘĘÉÉÉĂĂĂżżżÂÂÂĆĆĆĹĹĹşşş°°°­­­»»»ÇÇÇÉÉÉĹĹĹĹĹĹĹĹĹĹĹĹżżżĆĆĆĐĐĐŐŐŐŰŰŰÜÜÜÔÔÔĘĘĘŰŰŰâââĘĘĘĂĂĂżżżżżżÝÝÝčččŃŃŃŇŇŇßßßďďďňňňçççŕŕŕŕŕŕÝÝÝ×××ÇÇÇÎÎÎÍÍÍŃŃŃßßßÂÂÂĹĹĹÂÂÂĚĚĚÎÎÎĆĆĆĐĐĐĹĹĹÜÜÜĚĚĚĘĘĘÇÇÇÉÉÉĚĚĚÍÍÍĚĚĚĚĚĚĘĘĘÍÍÍĘĘĘĐĐĐĐĐĐŐŐŐâââŘŘŘÇÇÇĘĘĘÉÉÉŃŃŃŕŕŕăăăÜÜÜŮŮŮÍÍÍŰŰŰÉÉÉÜÜÜÔÔÔëëëîîîÝÝÝŰŰŰŘŘŘŐŐŐŇŇŇŇŇŇĐĐĐÍÍÍĘĘĘÇÇÇĂĂĂĆĆĆĆĆĆĆĆĆŐŐŐŇŇŇ···»»»ŔŔŔ···şşş»»»±±±»»»ĂĂĂĂĂĂÂÂÂÇÇÇĂĂĂĹĹĹÇÇÇÂÂÂĚĚĚÎÎÎÉÉÉÇÇÇĹĹĹĹĹĹÍÍÍŐŐŐŐŐŐÍÍÍĚĚĚĘĘĘĘĘĘÍÍÍÎÎÎÎÎÎÎÎÎĐĐĐŃŃŃŇŇŇÔÔÔÔÔÔŇŇŇŃŃŃĐĐĐĚĚĚ»»»±±±łłł´´´···¸¸¸µµµµµµµµµ···¸¸¸»»»»»»şşş¸¸¸···ĽĽĽŔŔŔÂÂÂĆĆĆĚĚĚĚĚĚÇÇÇżżżĚĚĚŰŰŰßßß××××××ĚĚĚŐŐŐ×××ŘŘŘÝÝÝŕŕŕŰŰŰŘŘŘŘŘŘÔÔÔŇŇŇÉÉÉÂÂÂľľľ¸¸¸´´´»»»ÇÇÇŔŔŔĂĂĂľľľŔŔŔżżżżżżĹĹĹÜÜÜíííîîîćććčččîîîńńńää似ĽÇÇÇăăăďďďčččçççčččęęęďďďňňňíííčččęęęďďďóóóőőőóóóăăăżżżÂÂÂÇÇÇÉÉÉÎÎÎÉÉÉÍÍÍÉÉÉÍÍÍÍÍÍÍÍÍĚĚĚ´´´¸¸¸ľľľĽĽĽĹĹĹÍÍÍŘŘŘŰŰŰĚĚĚżżżÂÂÂĆĆĆÍÍÍĐĐĐÍÍÍĘĘĘĚĚĚÇÇÇÂÂÂĆĆĆÂÂÂżżżÂÂÂĆĆĆĂĂĂşşş±±±¬¬¬»»»ÇÇÇĘĘĘÇÇÇÉÉÉĚĚĚĚĚĚľľľĘĘĘŃŃŃÔÔÔŇŇŇĐĐĐÎÎÎÍÍÍÜÜÜ×××ĆĆĆÉÉÉŔŔŔľľľÜÜÜçççÔÔÔŐŐŐßßßëëëîîîćććŕŕŕâââăăă×××ĆĆĆÍÍÍÎÎÎĐĐĐÝÝÝĘĘĘľľľÇÇÇŃŃŃĘĘĘĚĚĚ×××ĘĘĘßßßĐĐĐÍÍÍĚĚĚĘĘĘĚĚĚÍÍÍÍÍÍÍÍÍĘĘĘĘĘĘÇÇÇÎÎÎŇŇŇ×××ÝÝÝŃŃŃĘĘĘĚĚĚÎÎÎÔÔÔÜÜÜÜÜÜ×××ŐŐŐÔÔÔŐŐŐÔÔÔăăăÔÔÔňňňóóóŕŕŕŰŰŰŘŘŘŐŐŐŇŇŇŃŃŃÎÎÎĚĚĚÉÉÉĆĆĆÂÂÂĹĹĹĆĆĆÇÇÇ×××ŘŘŘÂÂÂĚĚĚÉÉÉ···łłł······ŔŔŔÇÇÇÂÂÂşşşĂĂĂÇÇÇĆĆĆÇÇÇĆĆĆÎÎÎĚĚĚĹĹĹĆĆĆĐĐĐŮŮŮÜÜÜ×××ŃŃŃĐĐĐÎÎÎĚĚĚĚĚĚÍÍÍÎÎÎĐĐĐÎÎÎĐĐĐĐĐĐŃŃŃŃŃŃĐĐĐÎÎÎÎÎÎÍÍÍĐĐĐŔŔŔµµµ´´´´´´´´´´´´´´´µµµµµµ···şşş»»»»»»»»»»»»ÂÂÂÇÇÇĘĘĘÉÉÉĘĘĘÎÎÎÉÉÉżżżĂĂĂ×××âââŰŰŰŘŘŘŮŮŮĐĐĐŰŰŰŮŮŮŮŮŮŰŰŰŰŰŰŮŮŮŘŘŘ×××ŐŐŐĆĆĆ»»»żżżŃŃŃŐŐŐĂĂø¸¸»»»ŔŔŔµµµ»»»¸¸¸¸¸¸ÂÂÂćććčččíííčččęęęîîîňňňäääľľľżżżÝÝÝďďďîîîîîîńńńňňňöööůůůńńńčččçççíííňňňóóóňňňčččĆĆĆÂÂÂĆĆĆĆĆĆÉÉÉĆĆĆÎÎÎÇÇÇÍÍÍÍÍÍŇŇŇĘĘĘ´´´µµµ¸¸¸ľľľĚĚĚŐŐŐŘŘŘ×××ÉÉÉĽĽĽľľľÂÂÂÇÇÇÉÉÉĂĂĂĂĂĂĆĆĆĂĂĂĽĽĽ¸¸¸······»»»żżżżżż¸¸¸łłł­­­»»»ÉÉÉÍÍÍÎÎÎĐĐĐŃŃŃŃŃŃÎÎÎ×××ĐĐĐĚĚĚÉÉÉĹĹĹÉÉÉÍÍÍâââÎÎÎĆĆĆÍÍÍżżż»»»ŘŘŘŕŕŕ×××ŮŮŮäääďďďňňňęęęăăăŕŕŕÔÔÔĘĘĘÂÂÂÎÎÎŃŃŃÔÔÔäääŕŕŕ´´´ĘĘĘÝÝÝĘĘĘÉÉÉÜÜÜŇŇŇ×××ŐŐŐŇŇŇĐĐĐÍÍÍĘĘĘÉÉÉÉÉÉÉÉÉÉÉÉĘĘĘĆĆĆÍÍÍĐĐĐĐĐĐ×××ĐĐĐÂÂÂÎÎÎŔŔŔ¸¸¸ŮŮŮăăăŇŇŇßßßŘŘŘÎÎÎŰŰŰăăăĐĐĐóóóőőőŕŕŕŰŰŰŘŘŘÔÔÔŇŇŇĐĐĐÎÎÎĘĘĘÇÇÇĆĆĆÂÂÂĹĹĹÇÇÇÉÉÉŐŐŐŮŮŮÍÍÍŃŃŃÎÎÎľľľµµµ»»»żżżÂÂÂĹĹĹŔŔŔ±±±żżżÉÉÉĹĹĹĆĆĆĆĆĆÍÍÍĂĂĂÂÂÂĚĚĚÜÜÜăăăŰŰŰÔÔÔ×××ŘŘŘÔÔÔÎÎÎĚĚĚÍÍÍÎÎÎĐĐĐĐĐĐŃŃŃĐĐĐÎÎÎÍÍÍĚĚĚĚĚĚĚĚĚĚĚĚŇŇŇÇÇÇĽĽĽ¸¸¸···łłł±±±´´´´´´µµµ···şşş»»»ĽĽĽľľľżżżľľľĂĂĂÇÇÇÉÉÉĚĚĚÎÎÎÉÉÉŔŔŔĹĹĹ×××âââŐŐŐŐŐŐ×××ŃŃŃŰŰŰÜÜÜŰŰŰŘŘŘŮŮŮÜÜÜŮŮŮŃŃŃÍÍÍľľľŔŔŔÎÎÎâââćććŘŘŘÇÇÇżżżłłł´´´­­­ľľľ¸¸¸»»»ÂÂÂäääęęęńńńďďďîîîęęęëëëćććÇÇÇĘĘĘâââîîîîîîóóóřřřóóóňňňöööďďďęęęëëëďďďóóóńńńíííßßßĹĹĹÂÂÂÇÇÇÉÉÉÇÇÇĹĹĹĚĚĚÍÍÍÎÎÎĚĚĚĐĐĐ°°°µµµ»»»ÂÂÂÔÔÔŘŘŘĐĐĐÎÎÎÉÉÉľľľ···µµµ¸¸¸¸¸¸µµµ···ĽĽĽľľľşşşĽĽĽ»»»»»»ĽĽĽľľľ»»»···łłł°°°ĽĽĽÉÉÉÎÎÎŇŇŇ×××ŐŐŐŇŇŇÔÔÔŮŮŮĘĘĘÍÍÍ×××ŐŐŐÝÝÝâââćććĚĚĚÂÂÂĆĆƸ¸¸ĽĽĽŰŰŰăăăçççććććććęęęęęęččččččëëëÍÍÍÉÉÉÉÉÉÔÔÔŇŇŇŃŃŃÝÝÝăăăľľľĘĘĘăăăÍÍÍŔŔŔŃŃŃĐĐĐĐĐĐÔÔÔŇŇŇĐĐĐĚĚĚÉÉÉÇÇÇĆĆĆĆĆĆĹĹĹĚĚĚĆĆĆĘĘĘĘĘĘĆĆĆĐĐĐŃŃŃżżżĚĚĚľľľ¬¬¬ĚĚĚâââŇŇŇŮŮŮŃŃŃÇÇÇŘŘŘŮŮŮĘĘĘëëëíííÝÝÝŰŰŰŘŘŘŐŐŐŇŇŇĐĐĐÍÍÍĘĘĘÇÇÇĆĆĆĂĂĂĹĹĹÇÇÇĘĘĘŇŇŇŘŘŘŐŐŐĐĐĐÍÍÍŔŔŔ´´´şşşŔŔŔľľľĽĽĽľľľ­­­»»»ĹĹĹÂÂÂÂÂÂÂÂÂÇÇÇ»»»ÇÇÇÔÔÔŰŰŰ×××ĚĚĚÎÎÎÝÝÝŰŰŰ×××ĐĐĐÍÍÍÍÍÍÎÎÎŃŃŃŃŃŃŃŃŃĐĐĐÍÍÍĘĘĘÉÉÉÉÉÉÉÉÉÉÉÉĐĐĐĚĚĚĹĹĹľľľşşş±±±ŻŻŻµµµ±±±´´´···şşş»»»ľľľŔŔŔĂĂĂÉÉÉĘĘĘĐĐĐÔÔÔŐŐŐŇŇŇÍÍÍÉÉÉĂĂĂÎÎÎßßßÔÔÔŐŐŐÔÔÔŇŇŇŘŘŘŰŰŰÝÝÝŮŮŮŮŮŮÜÜÜŐŐŐÇÇÇÂÂÂÂÂÂŘŘŘćććăăăßßßâââÝÝÝŃŃŃłłł······ĚĚĚşşş»»»ľľľŘŘŘćććîîîďďďńńńęęęčččîîîßßßÜÜÜćććçççęęęóóóóóóëëëčččíííęęęęęęîîîńńńďďďčččăăăÉÉÉżżżŔŔŔÉÉÉÍÍÍĘĘĘĆĆĆÇÇÇŃŃŃŃŃŃÉÉÉÍÍ͸¸¸­­­···żżżÂÂÂ×××ŘŘŘÉÉÉĆĆĆÇÇÇżżż···ÂÂÂŔŔŔżżż»»»şşş¸¸¸¸¸¸şşşĽĽĽ»»»şşşşşşşşş¸¸¸µµµ´´´µµµľľľĹĹĹĘĘĘŃŃŃŘŘŘ×××ŃŃŃÍÍÍŐŐŐĹĹĹŇŇŇćććăăăćććäääŘŘŘÇÇÇĹĹĹĆĆĆľľľÇÇÇÜÜÜÝÝÝÝÝÝŕŕŕćććęęęçççÝÝÝŇŇŇÍÍÍŃŃŃŃŃŃÔÔÔ×××ŃŃŃĘĘĘÎÎÎÔÔÔ×××ÇÇÇŰŰŰÍÍÍÂÂÂĂĂĂĆĆĆÎÎÎÉÉÉĘĘĘĘĘĘĘĘĘÇÇÇĆĆĆĆĆĆĆĆĆÂÂÂĘĘĘĹĹĹÇÇÇĆĆĆżżżÇÇÇÎÎÎÉÉÉÂÂÂÇÇÇşşşżżżŮŮŮÔÔÔĚĚĚÍÍÍÍÍÍŮŮŮŐŐŐŇŇŇëëëčččŕŕŕÜÜÜŮŮŮŐŐŐŇŇŇŃŃŃÎÎÎĘĘĘÇÇÇÇÇÇĹĹĹĆĆĆÉÉÉĘĘĘÎÎÎÔÔÔ×××ŇŇŇŇŇŇÇÇÇ´´´¸¸¸ĹĹĹżżżŔŔŔĂĂĂ···żżżĂĂĂĹĹĹĆĆĆÂÂÂÇÇÇĽĽĽŃŃŃŘŘŘŃŃŃĚĚĚĘĘĘÍÍÍ×××ŘŘŘÔÔÔĐĐĐÍÍÍÎÎÎĐĐĐĐĐĐĐĐĐĐĐĐÎÎÎÍÍÍĚĚĚÉÉÉÇÇÇĆĆĆĆĆĆÇÇÇĚĚĚÇÇÇÂÂÂĽĽĽ±±±­­­···°°°łłł···şşş»»»żżżĂĂĂÇÇÇäääââââââäääÝÝÝÎÎÎĆĆĆÇÇÇĆĆĆÉÉÉâââÜÜÜÝÝÝŮŮŮŰŰŰŮŮŮŮŮŮßßßŰŰŰŐŐŐŇŇŇĚĚĚĹĹĹÇÇÇŇŇŇçççďďďäääÜÜÜâââăăăÝÝÝŇŇŇŐŐŐŐŐŐßßß´´´µµµĽĽĽÔÔÔćććëëëîîîóóóíííëëëőőőďďďęęęčččâââćććńńńîîîççççççćććçççëëëîîîíííäääŘŘŘÎÎÎżżżľľľľľľĹĹĹÉÉÉÉÉÉĆĆĆĹĹĹĚĚĚÍÍÍÉÉÉÔÔÔşşş°°°µµµ»»»ľľľŃŃŃŐŐŐÉÉÉÂÂÂŔŔŔľľľľľľŃŃŃÍÍÍĘĘĘÉÉɸ¸¸···ĽĽĽ·········µµµµµµµµµ¸¸¸şşşĽĽĽĽĽĽĽĽĽŔŔŔĘĘĘÔÔÔÔÔÔÎÎÎŐŐŐÝÝÝÇÇÇÔÔÔăăăÔÔÔĐĐĐĘĘĘÉÉÉÇÇÇĚĚĚÇÇÇĹĹĹŇŇŇŰŰŰŃŃŃŃŃŃÔÔÔ×××ŘŘŘ×××ÔÔÔĐĐĐÍÍÍÉÉÉĘĘĘÎÎÎŇŇŇŇŇŇŇŇŇŃŃŃŇŇŇŕŕŕĂĂĂÍÍÍĘĘĘŃŃŃÉÉÉżżżĘĘĘÂÂÂĹĹĹÇÇÇÇÇÇĹĹĹÂÂÂÂÂÂÂÂÂŔŔŔÇÇÇżżżĂĂĂÇÇÇżżżÂÂÂĆĆĆÎÎÎşşşÂÂÂľľľÇÇÇŕŕŕŘŘŘÔÔÔÉÉÉŘŘŘÜÜÜ×××âââďďďçççăăăÝÝÝŰŰŰ×××ÔÔÔŃŃŃÎÎÎĘĘĘÇÇÇÉÉÉÇÇÇÇÇÇĘĘĘĘĘĘÉÉÉÍÍÍŐŐŐŇŇŇŐŐŐÍÍÍ´´´µµµĹĹĹÂÂÂĹĹĹĂĂĂżżżŔŔŔĽĽĽÂÂÂĂĂĂ»»»ÂÂÂĹĹĹŰŰŰŮŮŮĘĘĘĚĚĚÔÔÔĐĐĐĘĘĘŇŇŇŃŃŃÎÎÎÎÎÎĐĐĐĐĐĐĐĐĐÎÎÎÎÎÎÎÎÎÎÎÎÍÍÍĘĘĘÇÇÇĹĹĹĂĂĂŔŔŔÉÉÉÉÉÉĹĹĹľľľ°°°¬¬¬¸¸¸ŻŻŻ±±±µµµşşşĽĽĽŔŔŔĆĆĆĘĘĘßßßŰŰŰÝÝÝćććŕŕŕŃŃŃĚĚĚŇŇŇĚĚĚĘĘĘčččččččččâââăăăÝÝÝŘŘŘßßßŮŮŮÍÍÍÇÇÇĂĂĂÇÇÇ×××ăăăçççëëëíííçççŕŕŕÜÜÜŰŰŰßßßŕŕŕŕŕŕçççłłłľľľŐŐŐóóóńńńńńńńńńřřřďďďčččňňňîîîďďďçççßßßäääďďďíííčččîîîćććčččííííííçççŘŘŘÇÇÇĽĽĽÂÂÂĂĂĂĽĽĽĽĽĽżżżĂĂĂĆĆĆĂĂĂÂÂÂÉÉÉÍÍÍÝÝÝ´´´±±±łłł¸¸¸ĚĚĚŇŇŇĚĚĚÂÂÂşşş»»»ĆĆĆÉÉÉĂĂĂĹĹĹĘĘĘĹĹĹ······ÂÂÂľľľĽĽĽ»»»¸¸¸µµµ···şşş»»»ŔŔŔĽĽĽ······ĂĂĂĐĐĐŇŇŇÍÍÍŇŇŇÜÜÜĆĆĆŇŇŇâââĐĐĐÍÍÍÉÉÉĚĚĚĐĐĐĐĐĐŔŔŔŔŔŔŐŐŐŮŮŮÎÎÎŃŃŃÔÔÔ×××ŘŘŘ×××ŐŐŐŇŇŇĐĐĐÍÍÍĚĚĚĚĚĚÍÍÍÔÔÔŐŐŐÎÎÎĘĘĘ××׿żżĆĆĆĆĆĆŕŕŕŘŘŘÂÂÂĹĹĹÂÂÂĹĹĹÇÇÇĆĆĆÂÂÂľľľ»»»»»»ŔŔŔĹĹĹşşşÂÂÂĚĚĚÂÂÂľľľżżżăăăÉÉÉşşş···ŮŮŮäääÉÉÉŘŘŘżżżŰŰŰŮŮŮÔÔÔçççíííßßßŕŕŕßßßÜÜÜŘŘŘÔÔÔŇŇŇÎÎÎĘĘĘÇÇÇÉÉÉÉÉÉÉÉÉĚĚĚĘĘĘĹĹĹÉÉÉŇŇŇÉÉÉÎÎÎĚĚ̱±±±±±ŔŔŔ»»»ľľľşşşşşş···­­­µµµ¸¸¸­­­łłł \ No newline at end of file diff --git a/libraries/ode-0.9/include/Makefile.am b/libraries/ode-0.9/include/Makefile.am new file mode 100644 index 0000000000..2f77d2edfa --- /dev/null +++ b/libraries/ode-0.9/include/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = ode \ No newline at end of file diff --git a/libraries/ode-0.9/include/Makefile.in b/libraries/ode-0.9/include/Makefile.in new file mode 100644 index 0000000000..a930324ce2 --- /dev/null +++ b/libraries/ode-0.9/include/Makefile.in @@ -0,0 +1,488 @@ +# Makefile.in generated by automake 1.10 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 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@ +target_triplet = @target@ +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)/include/ode/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@ +ARCHFLAGS = @ARCHFLAGS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DRAWSTUFF = @DRAWSTUFF@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +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@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +ODE_AGE = @ODE_AGE@ +ODE_CURRENT = @ODE_CURRENT@ +ODE_RELEASE = @ODE_RELEASE@ +ODE_REVISION = @ODE_REVISION@ +ODE_SONAME = @ODE_SONAME@ +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@ +SET_MAKE = @SET_MAKE@ +SHARED_LDFLAGS = @SHARED_LDFLAGS@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TOPDIR = @TOPDIR@ +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_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +so_ext = @so_ext@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = ode +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 \ + && exit 0; \ + 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 + +# 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; } \ + END { 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; } \ + END { 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=; \ + 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; } \ + END { 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 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 + +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 ctags \ + ctags-recursive distclean distclean-generic 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 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: diff --git a/libraries/ode-0.9/include/drawstuff/drawstuff.h b/libraries/ode-0.9/include/drawstuff/drawstuff.h new file mode 100644 index 0000000000..ffaae81ef2 --- /dev/null +++ b/libraries/ode-0.9/include/drawstuff/drawstuff.h @@ -0,0 +1,294 @@ +/************************************************************************* + * * + * 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 */ +#define DS_NONE 0 /* uses the current color instead of a texture */ +#define DS_WOOD 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 */ + 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 (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 (char *msg, ...); + +/** + * @brief print log message + * @ingroup drawstuff + * @param msg format string, like printf, without the \n. + */ +DS_API void dsPrint (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 */ + +// Backwards compatible API +#define dsDrawCappedCylinder dsDrawCapsule +#define dsDrawCappedCylinderD dsDrawCapsuleD +#define dsSetCappedCylinderQuality dsSetCapsuleQuality + +/* closing bracket for extern "C" */ +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/libraries/ode-0.9/include/drawstuff/version.h b/libraries/ode-0.9/include/drawstuff/version.h new file mode 100644 index 0000000000..71d95f461d --- /dev/null +++ b/libraries/ode-0.9/include/drawstuff/version.h @@ -0,0 +1,29 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __VERSION_H +#define __VERSION_H + +/* high byte is major version, low byte is minor version */ +#define DS_VERSION 0x0002 + +#endif diff --git a/libraries/ode-0.9/include/ode/Makefile.am b/libraries/ode-0.9/include/ode/Makefile.am new file mode 100644 index 0000000000..1cc6caac6f --- /dev/null +++ b/libraries/ode-0.9/include/ode/Makefile.am @@ -0,0 +1,23 @@ +libglitch_includedir = $(includedir)/ode +libglitch_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 \ + collision.h \ + error.h \ + objects.h \ + rotation.h \ + collision_space.h \ + export-dif.h \ + ode.h \ + timer.h \ + config.h + +EXTRA_DIST = config.h.in diff --git a/libraries/ode-0.9/include/ode/Makefile.in b/libraries/ode-0.9/include/ode/Makefile.in new file mode 100644 index 0000000000..8458adbeea --- /dev/null +++ b/libraries/ode-0.9/include/ode/Makefile.in @@ -0,0 +1,448 @@ +# Makefile.in generated by automake 1.10 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 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@ +target_triplet = @target@ +subdir = include/ode +DIST_COMMON = README $(libglitch_include_HEADERS) \ + $(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 = +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)$(libglitch_includedir)" +libglitch_includeHEADERS_INSTALL = $(INSTALL_HEADER) +HEADERS = $(libglitch_include_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +ARCHFLAGS = @ARCHFLAGS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DRAWSTUFF = @DRAWSTUFF@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +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@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +ODE_AGE = @ODE_AGE@ +ODE_CURRENT = @ODE_CURRENT@ +ODE_RELEASE = @ODE_RELEASE@ +ODE_REVISION = @ODE_REVISION@ +ODE_SONAME = @ODE_SONAME@ +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@ +SET_MAKE = @SET_MAKE@ +SHARED_LDFLAGS = @SHARED_LDFLAGS@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TOPDIR = @TOPDIR@ +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_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +so_ext = @so_ext@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +libglitch_includedir = $(includedir)/ode +libglitch_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 \ + collision.h \ + error.h \ + objects.h \ + rotation.h \ + collision_space.h \ + export-dif.h \ + ode.h \ + timer.h \ + config.h + +EXTRA_DIST = config.h.in +all: config.h + $(MAKE) $(AM_MAKEFLAGS) 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 \ + && exit 0; \ + 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 + +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 include/ode/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-libglitch_includeHEADERS: $(libglitch_include_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(libglitch_includedir)" || $(MKDIR_P) "$(DESTDIR)$(libglitch_includedir)" + @list='$(libglitch_include_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(libglitch_includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(libglitch_includedir)/$$f'"; \ + $(libglitch_includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(libglitch_includedir)/$$f"; \ + done + +uninstall-libglitch_includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(libglitch_include_HEADERS)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(libglitch_includedir)/$$f'"; \ + rm -f "$(DESTDIR)$(libglitch_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; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + 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; } \ + END { 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) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + 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; } \ + END { 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) config.h +installdirs: + for dir in "$(DESTDIR)$(libglitch_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 mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: install-libglitch_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 + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libglitch_includeHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + ctags distclean distclean-generic distclean-hdr 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-libglitch_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 pdf \ + pdf-am ps ps-am tags uninstall uninstall-am \ + uninstall-libglitch_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: diff --git a/libraries/ode-0.9/include/ode/README b/libraries/ode-0.9/include/ode/README new file mode 100644 index 0000000000..9d7e99a8f8 --- /dev/null +++ b/libraries/ode-0.9/include/ode/README @@ -0,0 +1,18 @@ + +this is the public C interface to the ODE library. + +all these files should be includable from C, i.e. they should not use any +C++ features. everything should be protected with + + #ifdef __cplusplus + extern "C" { + #endif + + ... + + #ifdef __cplusplus + } + #endif + +the only exceptions are the odecpp.h and odecpp_collisioh.h files, which define a C++ wrapper for +the C interface. remember to keep this in sync! diff --git a/libraries/ode-0.9/include/ode/collision.h b/libraries/ode-0.9/include/ode/collision.h new file mode 100644 index 0000000000..c40bc4a149 --- /dev/null +++ b/libraries/ode-0.9/include/ode/collision.h @@ -0,0 +1,1386 @@ +/************************************************************************* + * * + * 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 + +#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 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 + * @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, + 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(); + + +/** + * @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]); +ODE_API void dInitODE(void); +ODE_API void dCloseODE(void); + +/* ************************************************************************ */ +/* 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); + +/* ************************************************************************ */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/ode-0.9/include/ode/collision_space.h b/libraries/ode-0.9/include/ode/collision_space.h new file mode 100644 index 0000000000..fb1f83f6dd --- /dev/null +++ b/libraries/ode-0.9/include/ode/collision_space.h @@ -0,0 +1,76 @@ +/************************************************************************* + * * + * 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, dVector3 Center, dVector3 Extents, int Depth); + +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); + +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); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/ode-0.9/include/ode/collision_trimesh.h b/libraries/ode-0.9/include/ode/collision_trimesh.h new file mode 100755 index 0000000000..ad85a6eb61 --- /dev/null +++ b/libraries/ode-0.9/include/ode/collision_trimesh.h @@ -0,0 +1,205 @@ +/************************************************************************* + * * + * 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 TriMesh data with single precision used in 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 TriMesh data with double pricision used in 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 int* 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 int* 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); + +/* + * Trimesh class + * Construction. Callbacks are optional. + */ +ODE_API dGeomID dCreateTriMesh(dSpaceID space, dTriMeshDataID Data, dTriCallback* Callback, dTriArrayCallback* ArrayCallback, dTriRayCallback* RayCallback); + +ODE_API void dGeomTriMeshSetData(dGeomID g, dTriMeshDataID Data); +ODE_API dTriMeshDataID dGeomTriMeshGetData(dGeomID g); + + +// enable/disable/check temporal coherence +ODE_API void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable); +ODE_API int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass); + +/* + * Clears the internal temporal coherence caches. When a geom has its + * collision checked with a trimesh once, data is stored inside the trimesh. + * With large worlds with lots of seperate objects this list could get huge. + * We should be able to do this automagically. + */ +ODE_API void dGeomTriMeshClearTCCache(dGeomID g); + + +/* + * returns the TriMeshDataID + */ +ODE_API dTriMeshDataID dGeomTriMeshGetTriMeshDataID(dGeomID g); + +/* + * Gets a triangle. + */ +ODE_API void dGeomTriMeshGetTriangle(dGeomID g, int Index, dVector3* v0, dVector3* v1, dVector3* v2); + +/* + * Gets the point on the requested triangle and the given barycentric + * coordinates. + */ +ODE_API void dGeomTriMeshGetPoint(dGeomID g, int Index, dReal u, dReal v, dVector3 Out); + +/* + +This is how the strided data works: + +struct StridedVertex{ + dVector3 Vertex; + // Userdata +}; +int VertexStride = sizeof(StridedVertex); + +struct StridedTri{ + int Indices[3]; + // Userdata +}; +int TriStride = sizeof(StridedTri); + +*/ + + +ODE_API int dGeomTriMeshGetTriangleCount (dGeomID g); + +ODE_API void dGeomTriMeshDataUpdate(dTriMeshDataID g); + +#ifdef __cplusplus +} +#endif + +#endif /* _ODE_COLLISION_TRIMESH_H_ */ + diff --git a/libraries/ode-0.9/include/ode/common.h b/libraries/ode-0.9/include/ode/common.h new file mode 100644 index 0000000000..7f0a12d3b2 --- /dev/null +++ b/libraries/ode-0.9/include/ode/common.h @@ -0,0 +1,388 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without 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 */ + +/* 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. + */ +#define EFFICIENT_ALIGNMENT 16 + + +/* 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 +#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 +#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 + +/* 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 + + +/* 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)))))) + + +// 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 + +// #define dUSE_MALLOC_FOR_ALLOCA + +#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 + + + +/* 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 */ + +enum { + dJointTypeNone = 0, /* or "unknown" */ + dJointTypeBall, + dJointTypeHinge, + dJointTypeSlider, + dJointTypeContact, + dJointTypeUniversal, + dJointTypeHinge2, + dJointTypeFixed, + dJointTypeNull, + dJointTypeAMotor, + dJointTypeLMotor, + dJointTypePlane2D, + dJointTypePR +}; + + +/* 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, \ + +#define D_ALL_PARAM_NAMES_X(start,x) \ + /* 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) + 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); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/ode-0.9/include/ode/compatibility.h b/libraries/ode-0.9/include/ode/compatibility.h new file mode 100644 index 0000000000..b3709866bc --- /dev/null +++ b/libraries/ode-0.9/include/ode/compatibility.h @@ -0,0 +1,40 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_COMPATIBILITY_H_ +#define _ODE_COMPATIBILITY_H_ + +/* + * ODE's backward compatibility system ensures that as ODE's API + * evolves, user code will not break. + */ + +/* + * These new rotation function names are more consistent with the + * rest of the API. + */ +#define dQtoR(q,R) dRfromQ((R),(q)) +#define dRtoQ(R,q) dQfromR((q),(R)) +#define dWtoDQ(w,q,dq) dDQfromW((dq),(w),(q)) + + +#endif diff --git a/libraries/ode-0.9/include/ode/config.h b/libraries/ode-0.9/include/ode/config.h new file mode 100644 index 0000000000..7d64006b2c --- /dev/null +++ b/libraries/ode-0.9/include/ode/config.h @@ -0,0 +1,176 @@ +/* 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. + * + * dSINGLE/dDOUBLE - force ODE to use single-precision (float) + * or double-precision (double) for numbers. + * Only one should be defined. + * + * 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. + * + * 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. + * + ******************************************************************/ + +#define dSINGLE +/* #define dDOUBLE */ + +#define dTRIMESH_ENABLED 1 +#define dTRIMESH_OPCODE 1 + +#define dTRIMESH_OPCODE_USE_NEW_TRIMESH_TRIMESH_COLLIDER 0 + +/* #define dUSE_MALLOC_FOR_ALLOCA */ + + +/****************************************************************** + * 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 + + +/* Define a DLL export symbol for those platforms that need it */ +#if defined(ODE_PLATFORM_WINDOWS) + #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 + + +/* Pull in the standard headers */ +#include +#include +#include +#include +#include +#include + +#if !defined(ODE_PLATFORM_PS3) + #include +#endif + +#if !defined(ODE_PLATFORM_WINDOWS) + #include +#endif + + +/* Visual C does not define these functions */ +#if defined(_MSC_VER) + #define copysignf _copysign + #define copysign _copysign +#endif + + +/* Define a value for infinity */ +#if defined(HUGE_VALF) + #define ODE_INFINITY4 HUGE_VALF + #define ODE_INFINITY8 HUGE_VAL +#elif defined(FLT_MAX) + #define ODE_INFINITY4 FLT_MAX + #define ODE_INFINITY8 DBL_MAX +#else + static union { unsigned char __c[4]; float __f; } __ode_huge_valf = {{0,0,0x80,0x7f}}; + static union { unsigned char __c[8]; double __d; } __ode_huge_val = {{0,0,0,0,0,0,0xf0,0x7f}}; + #define ODE_INFINITY4 (__ode_huge_valf.__f) + #define ODE_INFINITY8 (__ode_huge_val.__d) +#endif + +#ifdef dSINGLE + #define dInfinity ODE_INFINITY4 + #define dEpsilon FLT_EPSILON +#else + #define dInfinity ODE_INFINITY8 + #define dEpsilon DBL_EPSILON +#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 + +/* 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 + + +/* Define this if your system supports anonymous memory maps (linux does) */ +#define MMAP_ANONYMOUS + +#endif diff --git a/libraries/ode-0.9/include/ode/config.h.in b/libraries/ode-0.9/include/ode/config.h.in new file mode 100644 index 0000000000..1b05c7d5ca --- /dev/null +++ b/libraries/ode-0.9/include/ode/config.h.in @@ -0,0 +1,377 @@ +/* include/ode/config.h.in. Generated from configure.in by autoheader. */ + + +#ifndef ODE_CONFIG_H +#define ODE_CONFIG_H + + +/* 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 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_IEEEFP_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 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 + +/* Use SSE Optimizations */ +#undef HAVE_SSE + +/* 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 header file. */ +#undef HAVE_VALUES_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 + +/* 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 + +/* is this 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 + +/* The size of `char', as computed by sizeof. */ +#undef SIZEOF_CHAR + +/* The size of `int', as computed by sizeof. */ +#undef SIZEOF_INT + +/* The size of `long int', as computed by sizeof. */ +#undef SIZEOF_LONG_INT + +/* The size of `short', as computed by sizeof. */ +#undef SIZEOF_SHORT + +/* The size of `void*', as computed by sizeof. */ +#undef SIZEOF_VOIDP + +/* The extension for shared libraries. */ +#undef SO_EXT + +/* 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 to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN + +/* is this 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 + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Use double precision */ +#undef dDOUBLE + +/* dEpsilon Constant */ +#undef dEpsilon + +/* Use gyroscopic terms */ +#undef dGYROSCOPIC + +/* dInfinity Constant */ +#undef dInfinity + +/* Disable debug output */ +#undef dNODEBUG + +/* Use single precision */ +#undef dSINGLE + +/* 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 +#if defined(HAVE_IEEEFP_H) && !defined(__CYGWIN__) +// This header creates conflicts with math.h in Cygwin. +#include +#endif +#ifdef HAVE_STDIO_H +#include +#endif +#ifdef HAVE_STDLIB_H +#include +#endif +#ifdef HAVE_MATH_H +#include +#endif +#ifdef HAVE_STRING_H +#include +#endif +#ifdef HAVE_STDARG_H +#include +#endif +#ifdef HAVE_MALLOC_H +#include +#endif +#ifdef HAVE_VALUES_H +#include +#endif +#ifdef HAVE_FLOAT_H +#include +#endif +#if SIZEOF_CHAR == 1 +typedef char int8; +typedef unsigned char uint8; +#else +#error "expecting sizeof(char) == 1" +#endif +#if SIZEOF_SHORT == 2 +typedef short int16; +typedef unsigned short uint16; +#else +#error "can not find 2 byte integer type" +#endif +/* integer types (we assume int >= 32 bits) */ +#if SIZEOF_INT == 4 +typedef short int32; +typedef unsigned short uint32; +#else +#error "can not find 4 byte integer type" +#endif +/* an integer type that we can safely cast a pointer to and + * from without loss of bits. + */ +#if SIZEOF_SHORT == SIZEOF_VOIDP +typedef unsigned short intP; +#elif SIZEOF_INT == SIZEOF_VOIDP +typedef unsigned int intP; +#elif SIZEOF_LONG_INT == SIZEOF_VOIDP +typedef unsigned long int intP; +#endif + +/* +Handle Windows DLL odities +Its easier to export all symbols using the -shared flag +for MinGW than differentiating with declspec, +so only do it for MSVC +*/ +#if defined(ODE_DLL) && defined(WIN32) && defined(_MSC_VER) +#define ODE_API __declspec( dllexport ) +#elif !defined(ODE_DLL) && defined(WIN32) && defined(MSC_VER) +#define ODE_API __declspec( dllimport ) +#else +#define ODE_API +#endif + +#endif /* #define ODE_CONFIG_H */ + diff --git a/libraries/ode-0.9/include/ode/contact.h b/libraries/ode-0.9/include/ode/contact.h new file mode 100644 index 0000000000..fc634e7e0e --- /dev/null +++ b/libraries/ode-0.9/include/ode/contact.h @@ -0,0 +1,103 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without 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, + dContactSlip1 = 0x080, + dContactSlip2 = 0x100, + + 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; + dReal slip1,slip2; +} dSurfaceParameters; + + +/** + * @brief Describe the contact point between two geoms. + * + * If two bodies touch, or if a body touches a static feature in its + * environment, the contact is represented by one or more "contact + * points", described by dContactGeom. + * + * The convention is that if body 1 is moved along the normal vector by + * a distance depth (or equivalently if body 2 is moved the same distance + * in the opposite direction) then the contact depth will be reduced to + * zero. This means that the normal vector points "in" to body 1. + * + * @ingroup collide + */ +typedef struct dContactGeom { + dVector3 pos; ///< contact position + dVector3 normal; ///< normal vector + dReal depth; ///< penetration depth + dGeomID g1,g2; ///< the colliding geoms + int side1,side2; ///< (to be documented) +} dContactGeom; + + +/* contact info used by contact joint */ + +typedef struct dContact { + dSurfaceParameters surface; + dContactGeom geom; + dVector3 fdir1; +} dContact; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/ode-0.9/include/ode/error.h b/libraries/ode-0.9/include/ode/error.h new file mode 100644 index 0000000000..bdeec377f0 --- /dev/null +++ b/libraries/ode-0.9/include/ode/error.h @@ -0,0 +1,63 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* this comes from the `reuse' library. copy any changes back to the source */ + +#ifndef _ODE_ERROR_H_ +#define _ODE_ERROR_H_ + +#include + +#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 diff --git a/libraries/ode-0.9/include/ode/export-dif.h b/libraries/ode-0.9/include/ode/export-dif.h new file mode 100644 index 0000000000..ca479adc71 --- /dev/null +++ b/libraries/ode-0.9/include/ode/export-dif.h @@ -0,0 +1,32 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without 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 diff --git a/libraries/ode-0.9/include/ode/mass.h b/libraries/ode-0.9/include/ode/mass.h new file mode 100644 index 0000000000..19740fcbbd --- /dev/null +++ b/libraries/ode-0.9/include/ode/mass.h @@ -0,0 +1,125 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#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 +#define dMassSetCappedCylinder dMassSetCapsule +#define dMassSetCappedCylinderTotal dMassSetCapsuleTotal + + +struct dMass { + dReal mass; + dVector4 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 setCapsule (dReal density, int direction, dReal a, dReal b) + { dMassSetCappedCylinder (this,density,direction,a,b); } + void setCappedCylinder (dReal density, int direction, dReal a, dReal b) + { setCapsule(density, direction, a, b); } + void setBox (dReal density, dReal lx, dReal ly, dReal lz) + { dMassSetBox (this,density,lx,ly,lz); } + void adjust (dReal newmass) + { dMassAdjust (this,newmass); } + void translate (dReal x, dReal y, dReal z) + { dMassTranslate (this,x,y,z); } + void rotate (const dMatrix3 R) + { dMassRotate (this,R); } + void add (const dMass *b) + { dMassAdd (this,b); } +#endif +}; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/ode-0.9/include/ode/matrix.h b/libraries/ode-0.9/include/ode/matrix.h new file mode 100644 index 0000000000..eeb004d8eb --- /dev/null +++ b/libraries/ode-0.9/include/ode/matrix.h @@ -0,0 +1,194 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* 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 diff --git a/libraries/ode-0.9/include/ode/memory.h b/libraries/ode-0.9/include/ode/memory.h new file mode 100644 index 0000000000..c1af051a98 --- /dev/null +++ b/libraries/ode-0.9/include/ode/memory.h @@ -0,0 +1,59 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* this comes from the `reuse' library. copy any changes back to the source */ + +#ifndef _ODE_MEMORY_H_ +#define _ODE_MEMORY_H_ + +#include "ode/config.h" + +#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 diff --git a/libraries/ode-0.9/include/ode/misc.h b/libraries/ode-0.9/include/ode/misc.h new file mode 100644 index 0000000000..0c55fc5ba0 --- /dev/null +++ b/libraries/ode-0.9/include/ode/misc.h @@ -0,0 +1,85 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without 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 diff --git a/libraries/ode-0.9/include/ode/objects.h b/libraries/ode-0.9/include/ode/objects.h new file mode 100644 index 0000000000..3e24036098 --- /dev/null +++ b/libraries/ode-0.9/include/ode/objects.h @@ -0,0 +1,1966 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without 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 + * + * 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 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 + * @return the threshold + */ +ODE_API dReal dBodyGetAutoDisableLinearThreshold (dBodyID); + +/** + * @brief Set auto disable linear average threshold. + * @ingroup bodies + * @return the threshold + */ +ODE_API void dBodySetAutoDisableLinearThreshold (dBodyID, dReal linear_average_threshold); + +/** + * @brief Get auto disable angular average threshold. + * @ingroup bodies + * @return the threshold + */ +ODE_API dReal dBodyGetAutoDisableAngularThreshold (dBodyID); + +/** + * @brief Set auto disable angular average threshold. + * @ingroup bodies + * @return the threshold + */ +ODE_API void dBodySetAutoDisableAngularThreshold (dBodyID, dReal angular_average_threshold); + +/** + * @brief Get auto disable average size (samples count). + * @ingroup bodies + * @return the nr of steps/size. + */ +ODE_API int dBodyGetAutoDisableAverageSamplesCount (dBodyID); + +/** + * @brief Set auto disable average buffer size (average steps). + * @ingroup bodies + * @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 + * @return the nr of steps + */ +ODE_API int dBodyGetAutoDisableSteps (dBodyID); + +/** + * @brief Set auto disable steps. + * @ingroup bodies + * @param steps the nr of steps. + */ +ODE_API void dBodySetAutoDisableSteps (dBodyID, int steps); + +/** + * @brief Get auto disable time. + * @ingroup bodies + * @return nr of seconds + */ +ODE_API dReal dBodyGetAutoDisableTime (dBodyID); + +/** + * @brief Set auto disable time. + * @ingroup bodies + * @param time nr of seconds. + */ +ODE_API void dBodySetAutoDisableTime (dBodyID, dReal time); + +/** + * @brief Get auto disable flag. + * @ingroup bodies + * @return 0 or 1 + */ +ODE_API int dBodyGetAutoDisableFlag (dBodyID); + +/** + * @brief Set auto disable flag. + * @ingroup bodies + * @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 + */ +ODE_API void dBodySetAutoDisableDefaults (dBodyID); + + +/** + * @brief Retrives 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 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); + + + +/** + * @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 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 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 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 JointTypeBall + * \li JointTypeHinge + * \li JointTypeSlider + * \li JointTypeContact + * \li JointTypeUniversal + * \li JointTypeHinge2 + * \li JointTypeFixed + * \li JointTypeAMotor + * \li JointTypeLMotor + */ +ODE_API int 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 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 axis + * @ingroup joints + */ +ODE_API void dJointSetUniversalAxis2 (dJointID, dReal x, dReal y, dReal z); + +/** + * @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 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. + * 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. + * @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 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 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 diff --git a/libraries/ode-0.9/include/ode/ode.h b/libraries/ode-0.9/include/ode/ode.h new file mode 100644 index 0000000000..00cd500b3a --- /dev/null +++ b/libraries/ode-0.9/include/ode/ode.h @@ -0,0 +1,47 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without 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 + +#endif diff --git a/libraries/ode-0.9/include/ode/odecpp.h b/libraries/ode-0.9/include/ode/odecpp.h new file mode 100644 index 0000000000..62161fd57d --- /dev/null +++ b/libraries/ode-0.9/include/ode/odecpp.h @@ -0,0 +1,712 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without 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 + +#include + + +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 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(dWorldID, int depth) + { dWorldSetAutoEnableDepthSF1 (_id, depth); } + int getAutoEnableDepthSF1(dWorldID) + { return dWorldGetAutoEnableDepthSF1 (_id); } + + void setAutoDisableLinearThreshold (dReal threshold) + { dWorldSetAutoDisableLinearThreshold (_id,threshold); } + dReal getAutoDisableLinearThreshold() + { return dWorldGetAutoDisableLinearThreshold (_id); } + void setAutoDisableAngularThreshold (dReal threshold) + { dWorldSetAutoDisableAngularThreshold (_id,threshold); } + dReal getAutoDisableAngularThreshold() + { return dWorldGetAutoDisableAngularThreshold (_id); } + void setAutoDisableSteps (int steps) + { dWorldSetAutoDisableSteps (_id,steps); } + int getAutoDisableSteps() + { return dWorldGetAutoDisableSteps (_id); } + void setAutoDisableTime (dReal time) + { dWorldSetAutoDisableTime (_id,time); } + dReal getAutoDisableTime() + { return dWorldGetAutoDisableTime (_id); } + void setAutoDisableFlag (int do_auto_disable) + { dWorldSetAutoDisableFlag (_id,do_auto_disable); } + int getAutoDisableFlag() + { return dWorldGetAutoDisableFlag (_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() + { if (_id) dBodyDestroy (_id); } + + void create (dWorldID world) { + if (_id) dBodyDestroy (_id); + _id = dBodyCreate (world); + } + + 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 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 setAngularVel (dReal x, dReal y, dReal z) + { dBodySetAngularVel (_id,x,y,z); } + + 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 getMass (dMass *mass) const + { dBodyGetMass (_id,mass); } + + void addForce (dReal fx, dReal fy, dReal fz) + { dBodyAddForce (_id, fx, fy, fz); } + void addTorque (dReal fx, dReal fy, dReal fz) + { dBodyAddTorque (_id, fx, fy, fz); } + void addRelForce (dReal fx, dReal fy, dReal fz) + { dBodyAddRelForce (_id, fx, fy, fz); } + void addRelTorque (dReal fx, dReal fy, dReal fz) + { dBodyAddRelTorque (_id, fx, fy, fz); } + void addForceAtPos (dReal fx, dReal fy, dReal fz, + dReal px, dReal py, dReal pz) + { dBodyAddForceAtPos (_id, fx, fy, fz, px, py, pz); } + void addForceAtRelPos (dReal fx, dReal fy, dReal fz, + dReal px, dReal py, dReal pz) + { dBodyAddForceAtRelPos (_id, fx, fy, fz, px, py, pz); } + void addRelForceAtPos (dReal fx, dReal fy, dReal fz, + dReal px, dReal py, dReal pz) + { dBodyAddRelForceAtPos (_id, fx, fy, fz, px, py, pz); } + void addRelForceAtRelPos (dReal fx, dReal fy, dReal fz, + dReal px, dReal py, dReal pz) + { dBodyAddRelForceAtRelPos (_id, fx, fy, fz, px, py, pz); } + + 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 setTorque (dReal x, dReal y, dReal z) + { dBodySetTorque (_id,x,y,z); } + + void enable() + { dBodyEnable (_id); } + void disable() + { dBodyDisable (_id); } + int isEnabled() const + { return dBodyIsEnabled (_id); } + + void getRelPointPos (dReal px, dReal py, dReal pz, dVector3 result) const + { dBodyGetRelPointPos (_id, px, py, pz, result); } + void getRelPointVel (dReal px, dReal py, dReal pz, dVector3 result) const + { dBodyGetRelPointVel (_id, px, py, pz, result); } + void getPointVel (dReal px, dReal py, dReal pz, dVector3 result) const + { dBodyGetPointVel (_id,px,py,pz,result); } + void getPosRelPoint (dReal px, dReal py, dReal pz, dVector3 result) const + { dBodyGetPosRelPoint (_id,px,py,pz,result); } + void vectorToWorld (dReal px, dReal py, dReal pz, dVector3 result) const + { dBodyVectorToWorld (_id,px,py,pz,result); } + void vectorFromWorld (dReal px, dReal py, dReal pz, dVector3 result) const + { dBodyVectorFromWorld (_id,px,py,pz,result); } + + void setFiniteRotationMode (int mode) + { dBodySetFiniteRotationMode (_id, mode); } + void setFiniteRotationAxis (dReal x, dReal y, dReal z) + { dBodySetFiniteRotationAxis (_id, x, y, z); } + + int getFiniteRotationMode() const + { return dBodyGetFiniteRotationMode (_id); } + 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 (int mode) + { dBodySetGravityMode (_id,mode); } + int getGravityMode() const + { return dBodyGetGravityMode (_id); } + + int isConnectedTo (dBodyID body) const + { return dAreConnected (_id, body); } + + void setAutoDisableLinearThreshold (dReal threshold) + { dBodySetAutoDisableLinearThreshold (_id,threshold); } + dReal getAutoDisableLinearThreshold() + { return dBodyGetAutoDisableLinearThreshold (_id); } + void setAutoDisableAngularThreshold (dReal threshold) + { dBodySetAutoDisableAngularThreshold (_id,threshold); } + dReal getAutoDisableAngularThreshold() + { return dBodyGetAutoDisableAngularThreshold (_id); } + void setAutoDisableSteps (int steps) + { dBodySetAutoDisableSteps (_id,steps); } + int getAutoDisableSteps() + { return dBodyGetAutoDisableSteps (_id); } + void setAutoDisableTime (dReal time) + { dBodySetAutoDisableTime (_id,time); } + dReal getAutoDisableTime() + { return dBodyGetAutoDisableTime (_id); } + void setAutoDisableFlag (int do_auto_disable) + { dBodySetAutoDisableFlag (_id,do_auto_disable); } + int getAutoDisableFlag() + { return dBodyGetAutoDisableFlag (_id); } +}; + + +class dJointGroup { + dJointGroupID _id; + + // intentionally undefined, don't use these + dJointGroup (const dJointGroup &); + void operator= (const dJointGroup &); + +public: + dJointGroup (int dummy_arg=0) + { _id = dJointGroupCreate (0); } + ~dJointGroup() + { dJointGroupDestroy (_id); } + void create (int dummy_arg=0) { + if (_id) dJointGroupDestroy (_id); + _id = dJointGroupCreate (0); + } + + dJointGroupID id() const + { return _id; } + operator dJointGroupID() const + { return _id; } + + void empty() + { dJointGroupEmpty (_id); } +}; + + +class dJoint { +private: + // intentionally undefined, don't use these + dJoint (const dJoint &) ; + void operator= (const dJoint &); + +protected: + dJointID _id; + +public: + dJoint() + { _id = 0; } + ~dJoint() + { if (_id) dJointDestroy (_id); } + + dJointID id() const + { return _id; } + operator dJointID() const + { return _id; } + + void attach (dBodyID body1, dBodyID body2) + { dJointAttach (_id, body1, body2); } + + void setData (void *data) + { dJointSetData (_id, data); } + void *getData() const + { return dJointGetData (_id); } + + int 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); } +}; + + +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); } + + void create (dWorldID world, dJointGroupID group=0) { + if (_id) dJointDestroy (_id); + _id = dJointCreateBall (world, group); + } + + void setAnchor (dReal x, dReal y, dReal z) + { dJointSetBallAnchor (_id, x, y, z); } + void getAnchor (dVector3 result) const + { dJointGetBallAnchor (_id, result); } + void getAnchor2 (dVector3 result) const + { dJointGetBallAnchor2 (_id, result); } + void setParam (int parameter, dReal value) + { dJointSetBallParam (_id, parameter, value); } + dReal getParam (int parameter) const + { return dJointGetBallParam (_id, parameter); } +} ; + + +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); } + + void create (dWorldID world, dJointGroupID group=0) { + if (_id) dJointDestroy (_id); + _id = dJointCreateHinge (world, group); + } + + void setAnchor (dReal x, dReal y, dReal z) + { dJointSetHingeAnchor (_id, x, y, z); } + 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 getAxis (dVector3 result) const + { dJointGetHingeAxis (_id, result); } + + dReal getAngle() const + { return dJointGetHingeAngle (_id); } + dReal getAngleRate() const + { return dJointGetHingeAngleRate (_id); } + + void setParam (int parameter, dReal value) + { dJointSetHingeParam (_id, parameter, value); } + dReal getParam (int parameter) const + { return dJointGetHingeParam (_id, parameter); } + + 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); } + + void create (dWorldID world, dJointGroupID group=0) { + if (_id) dJointDestroy (_id); + _id = dJointCreateSlider (world, group); + } + + void setAxis (dReal x, dReal y, dReal z) + { dJointSetSliderAxis (_id, x, y, z); } + void getAxis (dVector3 result) const + { dJointGetSliderAxis (_id, result); } + + dReal getPosition() const + { return dJointGetSliderPosition (_id); } + dReal getPositionRate() const + { return dJointGetSliderPositionRate (_id); } + + void setParam (int parameter, dReal value) + { dJointSetSliderParam (_id, parameter, value); } + dReal getParam (int parameter) const + { return dJointGetSliderParam (_id, parameter); } + + 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); } + + void create (dWorldID world, dJointGroupID group=0) { + if (_id) dJointDestroy (_id); + _id = dJointCreateUniversal (world, group); + } + + void setAnchor (dReal x, dReal y, dReal z) + { dJointSetUniversalAnchor (_id, x, y, z); } + void setAxis1 (dReal x, dReal y, dReal z) + { dJointSetUniversalAxis1 (_id, x, y, z); } + void setAxis2 (dReal x, dReal y, dReal z) + { dJointSetUniversalAxis2 (_id, x, y, z); } + void setParam (int parameter, dReal value) + { dJointSetUniversalParam (_id, parameter, value); } + + 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); } + dReal getParam (int parameter) const + { return dJointGetUniversalParam (_id, parameter); } + 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); } + + void create (dWorldID world, dJointGroupID group=0) { + if (_id) dJointDestroy (_id); + _id = dJointCreateHinge2 (world, group); + } + + void setAnchor (dReal x, dReal y, dReal z) + { dJointSetHinge2Anchor (_id, x, y, z); } + void setAxis1 (dReal x, dReal y, dReal z) + { dJointSetHinge2Axis1 (_id, x, y, z); } + void setAxis2 (dReal x, dReal y, dReal z) + { dJointSetHinge2Axis2 (_id, x, y, z); } + + 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); } + + void setParam (int parameter, dReal value) + { dJointSetHinge2Param (_id, parameter, value); } + dReal getParam (int parameter) const + { return dJointGetHinge2Param (_id, parameter); } + + 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); } + + void create (dWorldID world, dJointGroupID group=0) { + if (_id) dJointDestroy (_id); + _id = dJointCreatePR (world, group); + } + + void setAnchor (dReal x, dReal y, dReal z) + { dJointSetPRAnchor (_id, x, y, z); } + void setAxis1 (dReal x, dReal y, dReal z) + { dJointSetPRAxis1 (_id, x, y, z); } + void setAxis2 (dReal x, dReal y, dReal z) + { dJointSetPRAxis2 (_id, x, y, z); } + + 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); } + + void setParam (int parameter, dReal value) + { dJointSetPRParam (_id, parameter, value); } + dReal getParam (int parameter) const + { return dJointGetPRParam (_id, parameter); } +}; + + +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); } + + void create (dWorldID world, dJointGroupID group=0) { + if (_id) dJointDestroy (_id); + _id = dJointCreateFixed (world, group); + } + + void set() + { dJointSetFixed (_id); } + + void setParam (int parameter, dReal value) + { dJointSetFixedParam (_id, parameter, value); } + + dReal getParam (int parameter) const + { return dJointGetFixedParam (_id, parameter); } +}; + + +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); } + + void create (dWorldID world, dJointGroupID group, dContact *contact) { + if (_id) dJointDestroy (_id); + _id = dJointCreateContact (world, 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); } + + void create (dWorldID world, dJointGroupID group=0) { + if (_id) dJointDestroy (_id); + _id = dJointCreateNull (world, 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); } + + void create (dWorldID world, dJointGroupID group=0) { + if (_id) dJointDestroy (_id); + _id = dJointCreateAMotor (world, 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 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); } + + 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); } + + void create (dWorldID world, dJointGroupID group=0) { + if (_id) dJointDestroy (_id); + _id = dJointCreateLMotor (world, 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 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); } +}; + + + +#endif +#endif diff --git a/libraries/ode-0.9/include/ode/odecpp_collision.h b/libraries/ode-0.9/include/ode/odecpp_collision.h new file mode 100644 index 0000000000..16ca78f7fb --- /dev/null +++ b/libraries/ode-0.9/include/ode/odecpp_collision.h @@ -0,0 +1,346 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without 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 + + +class dGeom { + // intentionally undefined, don't use these + dGeom (dGeom &); + void operator= (dGeom &); + +protected: + dGeomID _id; + +public: + dGeom() + { _id = 0; } + ~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 (dSpaceID space) + { _id = (dGeomID) dSimpleSpaceCreate (space); } +}; + + +class dHashSpace : public dSpace { + // intentionally undefined, don't use these + dHashSpace (dHashSpace &); + void operator= (dHashSpace &); + +public: + 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 (dSpaceID space, dVector3 center, 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 (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 (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 (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 (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 dRay : public dGeom { + // intentionally undefined, don't use these + dRay (dRay &); + void operator= (dRay &); + +public: + dRay() { } + 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 (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 diff --git a/libraries/ode-0.9/include/ode/odemath.h b/libraries/ode-0.9/include/ode/odemath.h new file mode 100644 index 0000000000..f8fa3c7c4e --- /dev/null +++ b/libraries/ode-0.9/include/ode/odemath.h @@ -0,0 +1,330 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without 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) \ + (a)[0] = ((b)[0]) op ((c)[0]); \ + (a)[1] = ((b)[1]) op ((c)[1]); \ + (a)[2] = ((b)[2]) op ((c)[2]); +#define dOPC(a,op,b,c) \ + (a)[0] = ((b)[0]) op (c); \ + (a)[1] = ((b)[1]) op (c); \ + (a)[2] = ((b)[2]) op (c); +#define dOPE(a,op,b) \ + (a)[0] op ((b)[0]); \ + (a)[1] op ((b)[1]); \ + (a)[2] op ((b)[2]); +#define dOPEC(a,op,c) \ + (a)[0] op (c); \ + (a)[1] op (c); \ + (a)[2] op (c); + + +/* + * 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 + +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) + */ +ODE_API int dSafeNormalize3 (dVector3 a); +ODE_API int dSafeNormalize4 (dVector4 a); + +// For some reason demo_chain1.c does not understand "inline" keyword. +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); +} + +// For DLL export +ODE_API void dNormalize3 (dVector3 a); // Potentially asserts on zero vec +ODE_API void dNormalize4 (dVector4 a); // Potentially asserts on zero vec + +// For internal use +#define dNormalize3(a) _dNormalize3(a) +#define dNormalize4(a) _dNormalize4(a) + +/* + * 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); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/ode-0.9/include/ode/rotation.h b/libraries/ode-0.9/include/ode/rotation.h new file mode 100644 index 0000000000..a72be27f1d --- /dev/null +++ b/libraries/ode-0.9/include/ode/rotation.h @@ -0,0 +1,70 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_ROTATION_H_ +#define _ODE_ROTATION_H_ + +#include +#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 diff --git a/libraries/ode-0.9/include/ode/timer.h b/libraries/ode-0.9/include/ode/timer.h new file mode 100644 index 0000000000..c3f42a7ada --- /dev/null +++ b/libraries/ode-0.9/include/ode/timer.h @@ -0,0 +1,76 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _ODE_TIMER_H_ +#define _ODE_TIMER_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* stop watch objects */ + +typedef struct dStopwatch { + double time; /* total clock count */ + unsigned long cc[2]; /* clock count since last `start' */ +} dStopwatch; + +ODE_API void dStopwatchReset (dStopwatch *); +ODE_API void dStopwatchStart (dStopwatch *); +ODE_API void dStopwatchStop (dStopwatch *); +ODE_API double dStopwatchTime (dStopwatch *); /* returns total time in secs */ + + +/* code timers */ + +ODE_API void dTimerStart (const char *description); /* pass a static string here */ +ODE_API void dTimerNow (const char *description); /* pass a static string here */ +ODE_API void dTimerEnd(void); + +/* print out a timer report. if `average' is nonzero, print out the average + * time for each slot (this is only meaningful if the same start-now-end + * calls are being made repeatedly. + */ +ODE_API void dTimerReport (FILE *fout, int average); + + +/* resolution */ + +/* returns the timer ticks per second implied by the timing hardware or API. + * the actual timer resolution may not be this great. + */ +ODE_API double dTimerTicksPerSecond(void); + +/* returns an estimate of the actual timer resolution, in seconds. this may + * be greater than 1/ticks_per_second. + */ +ODE_API double dTimerResolution(void); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/ode-0.9/install-sh b/libraries/ode-0.9/install-sh new file mode 100755 index 0000000000..4fbbae7b7f --- /dev/null +++ b/libraries/ode-0.9/install-sh @@ -0,0 +1,507 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2006-10-14.15 + +# 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. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +posix_glob= +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chmodcmd=$chmodprog +chowncmd= +chgrpcmd= +stripcmd= +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src= +dst= +dir_arg= +dstarg= +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: +-c (ignored) +-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. +--help display this help and exit. +--version display version info and exit. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + shift + shift + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t) dstarg=$2 + shift + shift + continue;; + + -T) no_target_directory=true + shift + continue;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac +done + +if test $# -ne 0 && test -z "$dir_arg$dstarg"; 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 "$dstarg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dstarg" + shift # fnord + fi + shift # arg + dstarg=$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 "$dstarg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dstarg + # 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: $dstarg: 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 + + case $posix_glob in + '') + if (set -f) 2>/dev/null; then + posix_glob=true + else + posix_glob=false + fi ;; + esac + + 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"; } && + + # Now 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. + { + if test -f "$dst"; then + $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 + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + } || 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: diff --git a/libraries/ode-0.9/missing b/libraries/ode-0.9/missing new file mode 100755 index 0000000000..1c8ff7049d --- /dev/null +++ b/libraries/ode-0.9/missing @@ -0,0 +1,367 @@ +#! /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: diff --git a/libraries/ode-0.9/ode-config.in b/libraries/ode-0.9/ode-config.in new file mode 100644 index 0000000000..d04bd01f52 --- /dev/null +++ b/libraries/ode-0.9/ode-config.in @@ -0,0 +1,56 @@ +#!/bin/sh + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +exec_prefix_set=no + +usage="\ +Usage: ode-config [--prefix[=DIR]] [--exec-prefix[=DIR]] [--version] [--cflags] [--libs] [--shared-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@ + ;; + --libs) + echo -L@libdir@ -lode + ;; + --shared-libs) + echo -L@prefix@/lib -lode@so_ext@ + ;; + *) + echo "${usage}" 1>&2 + exit 1 + ;; + esac + shift +done diff --git a/libraries/ode-0.9/ode/Makefile.am b/libraries/ode-0.9/ode/Makefile.am new file mode 100644 index 0000000000..5c9708e313 --- /dev/null +++ b/libraries/ode-0.9/ode/Makefile.am @@ -0,0 +1,4 @@ +SUBDIRS = src +if ENABLE_DEMOS + SUBDIRS += demo +endif diff --git a/libraries/ode-0.9/ode/Makefile.in b/libraries/ode-0.9/ode/Makefile.in new file mode 100644 index 0000000000..d89db18513 --- /dev/null +++ b/libraries/ode-0.9/ode/Makefile.in @@ -0,0 +1,489 @@ +# Makefile.in generated by automake 1.10 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 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@ +target_triplet = @target@ +@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)/include/ode/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@ +ARCHFLAGS = @ARCHFLAGS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DRAWSTUFF = @DRAWSTUFF@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +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@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +ODE_AGE = @ODE_AGE@ +ODE_CURRENT = @ODE_CURRENT@ +ODE_RELEASE = @ODE_RELEASE@ +ODE_REVISION = @ODE_REVISION@ +ODE_SONAME = @ODE_SONAME@ +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@ +SET_MAKE = @SET_MAKE@ +SHARED_LDFLAGS = @SHARED_LDFLAGS@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TOPDIR = @TOPDIR@ +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_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +so_ext = @so_ext@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = src $(am__append_1) +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + 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 + +# 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; } \ + END { 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; } \ + END { 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=; \ + 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; } \ + END { 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 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 + +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 ctags \ + ctags-recursive distclean distclean-generic 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 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: diff --git a/libraries/ode-0.9/ode/README b/libraries/ode-0.9/ode/README new file mode 100644 index 0000000000..dd4596f993 --- /dev/null +++ b/libraries/ode-0.9/ode/README @@ -0,0 +1,158 @@ +Dynamics Library. +================= + +CONVENTIONS +----------- + +matrix storage +-------------- + +matrix operations like factorization are expensive, so we must store the data +in a way that is most useful to the matrix code. we want the ability to update +the dynamics library without recompiling applications, e.g. so users can take +advantage of new floating point hardware. so we must settle on a single +format. because of the prevalence of 4-way SIMD, the format is this: store +the matrix by rows or columns, and each column is rounded up to a multiple of +4 elements. the extra "padding" elements at the end of each row/column are set +to 0. this is called the "standard format". to indicate if the data is stored +by rows or columns, we will say "standard row format" or "standard column +format". hopefully this decision will remain good in the future, as more and +more processors have 4-way SIMD, and 3D graphics always needs fast 4x4 +matrices. + +exception: matrices that have only one column or row (vectors), are always +stored as consecutive elements in standard row format, i.e. there is no +interior padding, only padding at the end. + +thus: all 3x1 floating point vectors are stored as 4x1 vectors: (x,x,x,0). +also: all 6x1 spatial velocities and accelerations are split into 3x1 position + and angular components, which are stored as contiguous 4x1 vectors. + +ALL matrices are stored by in standard row format. + + +arguments +--------- + +3x1 vector arguments to set() functions are supplied as x,y,z. +3x1 vector result arguments to get() function are pointers to arrays. +larger vectors are always supplied and returned as pointers. +all coordinates are in the global frame except where otherwise specified. +output-only arguments are usually supplied at the end. + + +memory allocation +----------------- + +with many C/C++ libraries memory allocation is a difficult problem to solve. +who allocates the memory? who frees it? must objects go on the heap or can +they go on the stack or in static storage? to provide the maximum flexibility, +the dynamics and collision libraries do not do their own memory allocation. +you must pass in pointers to externally allocated chunks of the right sizes. +the body, joint and colllision object structures are all exported, so you +can make instances of those structure and pass pointers to them. + +there are helper functions which allocate objects out of areans, in case you +need loots of dynamic creation and deletion. + +BUT!!! this ties us down to the body/joint/collision representation. + +a better approach is to supply custom memory allocation functions +(e.g. dlAlloc() etc). + + +C versus C++ ... ? +------------------ + +everything should be C linkable, and there should be C header files for +everything. but we want to develop in C++. so do this: + * all comments are "//". automatically convert to /**/ for distribution. + * structures derived from other structures --> automatically convert? + + +WORLDS +------ + +might want better terminology here. + +the dynamics world (DWorld) is a list of systems. each system corresponds to +one or more bodies, or perhaps some other kinds of physical object. +each system corresponds to one or more objects in the collision world +(there does not have to be a one-to-one correspondence between bodies and +collision objects). + +systems are simulated separately, perhaps using completely different +techniques. we must do something special when systems collide. +systems collide when collision objects belonging to system A touch +collision objects belonging to system B. + +for each collision point, the system must provide matrix equation data +that is used to compute collision forces. once those forces are computed, +the system must incorporate the forces into its timestep. +PROBLEM: what if we intertwine the LCP problems of the two systems - then +this simple approach wont work. + +the dynamics world contains two kinds of objects: bodies and joints. +joints connect two bodies together. + +the world contains one of more partitions. each partition is a collection of +bodies and joints such that each body is attached (through one or more joints) +to every other body. + +Joints +------ + +a joint can be connected to one or two bodies. +if the joint is only connected to one body, joint.node[1].body == 0. +joint.node[0].body is always valid. + + +Linkage +------- + +this library will always be statically linked with the app, for these reasons: + * collision space is selected at compile time, it adds data to the geom + objects. + + +Optimization +------------ + +doubles must be aligned on 8 byte boundaries! + + +MinGW on Windows issues +----------------------- + +* the .rc file for drawstuff needs a different include, try winresrc.h. + +* it seems we can't have both main() and WinMain() without the entry point + defaulting to main() and having resource loading problems. this screws up + what i was trying to do in the drawstuff library. perhaps main2() ? + +* remember to compile resources to COFF format RES files. + + + +Collision +--------- + +to plug in your own collision handling, replace (some of?) these functions +with your own. collision should be a separate library that you can link in +or not. your own library can call components in this collision library, e.g. +if you want polymorphic spaces instead of a single statically called space. + +creating an object will automatically register the appropriate +class (if necessary). how can we ensure that the minimum amount of code is +linked in? e.g. only one space handler, and sphere-sphere and sphere-box and +box-box collision code (if spheres and boxes instanced). + +the user creates a collision space, and for each dynamics object that is +created a collision object is inserted into the space. the collision +object's pos and R pointers are set to the corresponding dynamics +variables. + +there should be utility functions which create the dynamics and collision +objects at the same time, e.g. dMakeSphere(). + +collision objects and dynamics objects keep pointers to each other. diff --git a/libraries/ode-0.9/ode/TODO b/libraries/ode-0.9/ode/TODO new file mode 100644 index 0000000000..cf6cdaac5a --- /dev/null +++ b/libraries/ode-0.9/ode/TODO @@ -0,0 +1,698 @@ + +@@@'s + + +TODO for COLLISION +------------------ + +box-box collision: adjust generated face-face contact points by depth/2 to +be more fair. + +what happens when a GeomTransform's encapsulated object is manipulated, +e.g. position changed. should this be disallowed? should a GeomTransform +behave like a space and propagate dirtyness upwards? + +make sure that when we are using a large space for static environmental geoms, +that there is not excessive AABB computation when geoms are added/removed from +the space. the space AABB is pretty much guaranteed to cover everything, so +there's no need to compute/test the AABB in this case. + +hash space: implement collide2() efficiently instead of the current +simple-space-like brute-force approach. + +hash space: incremental scheme, so we dont have to rebuild the data structures +for geoms that don't move. + +disabled geoms (remove from all collision considerations) ... isn't this the +same as just taking it out of its enclosing group/space? + +integrate: + dRay + triangle collider - get latest tri collider code from erwin + erwin's quadtree space + +tests: + all aspects of collision API + + dGeomSetBody(0) maintains body-geom linked list properly. + + simple space: instantiate lots of non-moving geoms (i.e. environmental + geoms and make sure that we're still able to collide efficiently. + make sure AABB computation is efficient, or can be made efficient + through proper use of the API. + + test C interface support for making new classes. + make sure the dxGeom::aabbTest() function behaves as advertised. + + testing for contact point consistency: test for things that + would cause the dynamics to fail or become unstable + + test for: small adjustment in geom position causes a big jump in the + contact point set (bad for dynamics). + + test for: if contact constraints observed then it's impossible + (or hard) to move the objects so that the penetration is + increased. relax this when only a subset of the contact points are + returned. + + test for consistency, e.g. the boundary of geoms X and Y can + be defined by intersecting with a point, so test the intersection of X + and Y by comparing with the point tests. + + check that contact points are in the collision volume + + all existing space tests, and more. + +demos: + test_buggy: make a terrain out of non-moving geoms. use heirarchical + groups to get efficient collision, even with the simple space. + +go though the new collision docs and make sure the behavior that is described +there is actually implemented. + +multi-resolution hash table: + the current implementation rebuilds a new hash table each time + collide() is called. we don't keep any state between calls. this is + wasteful if there are unmoving objects in the space. + + make sure we prevent multiple collision callbacks for the same pair + + better virtual address function. + + the collision search can perhaps be optimized - as we search + chains we can come across other candidate intersections at + other levels, perhaps we should do the intersection check + straight away? --> save on list searching time only, which is + not too significant. + +collision docs: + optimization guide: whenever a single geom changes in a simple space, + the space AABB has to be recomputed by examining EVERY geom. + document this, or find a better behavior. + + + +TODO BEFORE NEXT RELEASE +------------------------ + +g++ needed for compiling tests using gcc 3.2 ? what is the problem? + +add joint feedback info from lambda, so that we can get motor forces etc. +need a way to map constraint indexes to what they mean. + +track down and fix the occasional popping/jumping problem in test_boxstack, +especially when boxes are piled on top of each other. find out if this is +caused by a configuration singularity or whether there is a bug in LCP. +i need to add some kind of diagnostic tool to help resolve these kinds of +problems. + +fixup ground plane jitter and shadow jumping in drawstuff. + +the inertias/COMs don't appear to be totally correct for the boxstack demo. +fix up, and add a mode that shows the effective mass box (for a given density). + +Improve box-box collision, especially for face-face contact (3 contact points). +Improve cylinder-box collision (2 contact points). + +windows DLL building and unix shared libs. libtool? +also MSVC project files. + +dBodyGetPointVel() + +contrib directory - all stuff in ~/3/ode + +functions to allow systems to be copied/cloned + dBodyTransplant (b, world) + dTransplantIsland (b, world) + dBodyCopy (bdest, bsrc) + dJointCopy (jdest, jsrc) -- what about body connections? + dCloneBody() + dCloneJoint() + dCloseBodyAndJointList() + dCloneIsland() + +this collision rule: + // no contacts if both geoms on the same body, and the body is not 0 + if (g1->body == g2->body && g1->body) return 0; +needs to be replaced. sometimes we want no collision when both bodies are 0, +but this wont work for geomgroup-to-environment. avoid stupid stuff like + dGeomSetBody (geom_group, (dBodyID) 1); +this also causes "failed-to-report" errors in the space test. + +Expose type-specific collision functions? + +Automatic code optimization process. + +joint limit spongyness: interacts with powered joints badly, because when the +limit is reached full power is applied. fix or doc. + +various hinge2 functions may not function correctly if axis1 and axis2 are not +perpendicular. in particular the getAngle() and getAngleRate() functions +probably will give bogus answers. + +slow step function will not respect the joint getinfo2 functions calling +addTorque() because it reads the force/torque accumulators before the +getinfo2 functions are called. + +spaces need multiple lists of objects that can never overlap. objects in these +lists are never tested against each other. + +deleting a body a joint is attached to should adjust the joint to only have +one body attached. currently the connected joints have *both* their body +attachments removed. BUT, dont do this if the dJOINT_TWOBODIES flag is set +on the joint. + +document error, mem and math functions. + +Web pages + credits section + projects using ODE + +update C++ interface? use SWIG? + +collision exclusion groups - exclude if obj1.n == obj2.n ? + +make sure the amotor joint can be used with just one body. at the moment it +only allows two-body attachments. + +implement dJointGetAMotorAngleRate() + +erwin says: Should the GeomGroup have a cleanupmode as the GeomTransform has? + +erwin says: http://q12.org/pipermail/ode/2002-January/000766.html + and http://q12.org/pipermail/ode/2001-December/000753.html + +rename duplicate filenames (object.h?) - some environments can't handle this. + +naming inconsistency: dCreateSphere() should be dSphereCreate() (etc...) to +match the rest of the API. + + +TODO +---- + +joint allocation in joint groups. allocation size should be rounded up using +dEFFICIENT_SIZE, to properly align all the data members. + +all dAlloc() allocations should be aligned using dEFFICIENT_SIZE() ??? + +automatic body & joint disabling / enabling. + +sometimes getting LCP infinite loops. + +function to get the entire island of bodies/joints + +joints: + hinge2 joint - implement trail, i.e. non-convergent steering and wheel + axes. + + erp individually settable for each joint? + + more joints: + angular3 (constrian full angle not position) + fixed path 1 (point must follow fixed path, etc etc) + - other fixed path joints. + linear a (point in 1 body fixed to plane of other) + linear b (point in 1 body fixed to line on other) + linear c (line in 1 body fixed to plane on other) + linear d (line in 1 body fixed to line on other) - like + prismatic but orientation along line can change + Relative-Path-Relative-Oriention Joint (set all dofs of 2 + bodies relative to each other) + spring (with natural length) + universal (2 kinds) + various angular relationships + + when attaching joints to static env, provision to move attachment + point (e.g. give it a linear/angular velocity). this can be used + instead of a FPFO joint on a body in many cases. + also do this with contacts to static env, to allow for contacts to + *moving* objects in the static env. + + interpretation of erp: is it (1) the error reduction per timestep, + (2) or a time constant independent of timestep?? if it's (2) then + perhaps this should be universal - this is already the meaning for + the suspension. + + hinge2 suspension: + suspension limits + suspension limit restitution and spongyness?? + +use autoconf? set paths in makefile? + +no-arg init functions, for andy + +explore: do joint parameters need to be set for the joint to be setup +correctly, or should set some proper body-dependent params when it is +attached? this is only really an issue for joints that have no parameters to +set, such as the fixed joint. + +dAlloc() should take an arena parameters which is stored in dWorld. + +debugging mode should use dASSERT2 that prints a descriptive error message +on error, not just the file:line or function. use dASSERT for internal +consistency checking. + +when vectors and matrices are initialized, we must ensure that the padding +elements are set to 0. this is going to be a problem everywhere! + +don't use 3-vectors anywhere. use SIMD friendly 4-vectors. + +make sure all data in body/joint etc objects is aligned well for single +precision SIMD (i.e. all vectors start on a 16 byte boundary). + +think about more complicated uses of collision, e.g. a single geom representing +an articulated structure. + +bodyGroup? (like joint group but for bodies). systemGroup? + +check the overhead of resizing Array<>s as elements are pushed on to them. + +replace alloca() with dPushFrame(), dPopFrame(), and dAlloca() ? allow for +the possibility of allocating in non-stack memory ? + +make sure that we can set mass parameters with non-zero center of mass. +if this is done after the body position is set, the position is adjusted. +if this is done before the body position is set, what do we do when the +pos is set? does the pos always refer to the center of mass from the user's +point of view? + +consider splitting solver into functions, which can be optimized separately. +might make things go faster. + +faster code for islands with a single body? faster code for dynamically +symmetric bodies? + +rotation.cpp functions that set matrices should also set padding elements. + +lcp solver must return (L,d) and some other information, so we can re-solve +for other right hand sides later on, but using the same complimentarity +solution so there are no integrator discontinuities. + +dSetZero() - make fast inline functions for fixed n e.g. (1-4). + +need proper `sticky' friction, i.e. compensation for numerical slip. + +on windows, make sure gcc-compiles libs can be linked with VC++ apps. need +to make sure some C++ runtime bits are present? + +kill all references to dArray<> (in geom.cpp). + +need testing code to test all joints with body-to-static-env + +copy stack.cpp, memory.cpp stuff to reuse + +dFactorLDLT() is not so efficient for matrix sizes < block size, e.g. +redundant calls, zero loads, adds etc + +contacts: cheaper friction: viscous friction? one step delay friction force. + +in geom.cpp, for objects that are never meant to collide, dCollide() will +always try to find the collider functions, which wastes a bit of time. + +geom.cpp:dCollideG() - handle special case of colliding 2 groups more +efficiently. + +timer reporting function: + void timerReport (void (*printFunction)(char *, ...)); + +disabled bodies stored in a separate list, so they are never traversed at all, +for speed when there are many disabled bodies. + + +MAYBE +----- + +new implementation for joint groups that is not so system dependent. +maybe individual contacts are reusable? in this case contact information +should be settable in the contact joints. max_size arg is really annoying. + +consider making anchor,axis, (everything) into a joint parameter and setting +them with a consistent interface. also consider overload the joint functions +so they are not distinguished by joint type?? + +collision memory optimizations? + +collision: support for persistent contact information? + +multiply reference tri list data so that it can be cloned + if the tri-list geoms could support rot/pos + transformations then we could have several tri-lists pointing to the + same vertex information. + +height fields + +pre-converted collision data -- Creating a hash space and associated +opcode tree structures may take significant amounts of time for a +large world with many 10s of thousands of triangles. Any chance of +pre-building that off-line and passing a memory block pointer to the +collision system? + +putting objects in multiple spaces -- If it was possible to add +objects to more than one space, you could do collision queries other +than 1vsN and NvsN. That flexibility might be useful when you want to +only collide against a subset of the space. For example, a camera +system may want to collide some rays with occlusion walls but the +occlusion walls may also need to be in the game-level space to bounce +against. + + +ALWAYS +------ + +make sure functions check their arguments in debug mode (e.g. using dASSERT). +make sure joint/geom functions check for the specific object type. + +vectors alloca()ed on the stack must have the correct alignment, use ALLOCA16. + +library should have no global constructors, as it might be used with C linkage. + +use `const' in function arguments. blah. + + + +DON'T BOTHER +------------ + +warning if user tries to set mass params with nonzero center of mass. + + + +DONE +---- + +check: when contact attached with (body1,0) and (0,body1), check that polarity +on depth and error info is okay for the two cases. + +set a better convention for which is the 1st and 2nd body in a joint, because +sometimes we get things swapped (because of the way the joint nodes are used). + +hinge and prismatic, attachment to static environment. + +turn macros into C++ inline functions? what about C users? + +remove `space' argument to geom creation functions? make user add it? +or just remove it from dCreateGeom() ? <-- did this one. + +test_chain should be in C, not C++. but first must remove global constructors. + +add more functionality to C++ interface - dMass, dSpace, dGeom + +there should be functions to delete groups of bodies/joints in one go - this +will be more efficient than deleting them one at a time, because less +partitioning tests will be needed. + +should we expose body and joint object structures so that the user can +explicitly allocate them locally, or e.g. on the stack? makes allocating +temporary contact constraints easier. NO --> helps data hiding and therefore +library binary compatability. + +joints: + hinge & slider - DONE + measure angle, rate - DONE + power - DONE + joint limits - DONE + mixed powered+limited joints, powering away from limit - DONE + + hinge2 - DONE + steering angle and rate measurement - DONE + steering limits - DONE + steering motor - DONE + wheel motor - DONE + wheel angle rate measurement - DONE + + optional hinge2 suspension: - DONE + alignment of B&S part to given axis - DONE + global framework for giving epsilon and gamma - DONE + + toss away r-motor, make power & stuff specific to joint - DONE + it's just easier that way + + joint code reuse: - DONE + use standard functions to set velocity (c), limits (lo,hi), + spongyness (epsilon) etc, this prevents these functions from + proliferating + + implicit spring framework - actually allow joints to return a value `k' + such that J*vnew = c + k*f, where f = force needed to achieve + vnew - DONE + + contact slip - DONE + contact erp & cfm parameters (not just "softness") - DONE + + hinge2: when we lock back wheels along the steering axis, there is no + error correction if they get out of alignment - DONE, just use high + and low limits. + + joint limit spongyness: erp and cfm for joint set from world (global) + values when joint created. - DONE + + joint limit restitution - DONE + +check inertia transformations, e.g. by applying steering torque to a thin +wheel --> actually, i made test_I + +more comprehensive random number comparisons between slow and fast methods. + - random PD inertia (not just diagonal). + - random velocity + - random joint error (make joints then move bodies a bit) + +check that J*vnew=c (slow step already does this, but it doesn't equal zero +for some reason! - actually, when LCP constraint limits are reached, it wont!) + +tons of things in lcp.cpp (@@@), especially speed optimizations. also, we +wanted to do index block switching and index block updates to take advantage +of the outer product trick ... but this is not worth the effort i think. + +lcp.cpp: if lo=hi=0, check operation. can we switch from NL <-> NH without +going through C? --> done. + +andy says: still having trouble with those resource files.. +drawstuff.res doesn't seem to build or be found under cygwin gcc. + +DOC how bodies and geoms associated then resolved in contact callback ... not +really necessary. + +fix the "memory leak" in geom.cpp + +library should have no global constructors, as it might be used with C linkage. + --> as long as test_chain1 works, there are none. + +DOC cfm, the derivation and what it means. + --> partially done, could be better + +joint "get type" function + +andy says: in ode/src/error.cpp _snprintf() and _vsnprintf() are missing +in testode: finite and isnan are missing. copysign is missing + russ: okay here's the problem: i have Makefile.platform files for + VC++, MinGW, but not Cygwin. Cygwin uses the unix-like functions + for everything, but the VC++/MinGW configs assumes the MS C-runtime + functions. this is easy to fix, except i need to install Cygwin + which is a pain to do over MinGW. argh. + +build on linux - assumptions made about location of X11 lib, opengl etc. + +implement: dBodyAddForceAtPos,dBodyAddRelForceAtPos,dBodyAddRelForceAtRelPos, + dBodyGetPointPos,dBodyGetPointVel,dBodyGetPointRelVel + +dJointAttach(), allow both bodies to be 0 to put the joint into limbo. + +space near-callback should be given potentially intersecting objects 100 at a +time instead of 1 at a time, to save on calling costs ... which are trivial, +so we don't bother to do this. + +doccer: @func{} also refs second etc function in function *list*. + +make sure joints can return 0 from GetInfo1, i.e. no constraints or "inactive" +joint, and the step functions will handle it. + +when attaching contact with (0,body), instead of setting the reverse flag +on the joint and checking it in getInfo2(), we should just reverse the normal +straight away ... ? + --> trouble is, dJointAttach() knows nothing about what kind of joint + it is attaching. + +hinge2 needs to be attached to two bodies for it to work, make sure this is +always the case. --> assertion added in dJointAttach(). + +if two joints connect to the same two bodies, check that the fast solver +works! -> it should. + +functions to get all the joints/bodies a body/joint is connected to. + +If I don't have the GCC libraries installed, HUGE_VALF is undefined. + +fix capped cylinder - capped cylinder collision so that two contacts can +be generated. + +transformation geometry object. + +joint groups should also be destroyed by destroying the world --> naaahhh. + +DONT DO THIS: body/joint creators with world = 0 --> not inserted into any +world. allow bodies/joints to be detached from a world (this is what happens +to grouped joints when a world is destroyed). + can bodies and joints be linked together when not attached to world?? + what happens when we have an island of b/j, some of which are not in + world? soln: dont keep lists of b/j in the world, just infer it from + the islands? + +body & joint disabling / enabling + +start a change log. + +collision flags - 0xffff mask. + +dBodyGetFiniteRotationMode() / ...Axis() + +dBodyAddForceAtRelPos() + +ball & socket joint limits and motors. + +auto-build env on windows: 3 compilers, debug/release, short/double = +12 combinations --> auto logs. + +handle infinities better: HUGE_VALF is not commanly defined, it seems. +get rid of the __USE_ISOC9X macro in common.h +perhaps just use a "big" number instead of the actual IEEE infinity, it's +more portable anyway. + --> new config system + +dCloseODE() - tidy up *all* allocated memory, esp in geom.cpp. used to keep +leak detectors happy. + +extra API to get lambda and J'*lambda from last timestep. + +better stack implementation that is not so system dependent. but how will +we do dynamic page allocation? do we even need to? + + +all collision files will now be collision_*, not geom_* + +check exported global symbols - no C++ mangling. + +rename dSphere etc to dxSphere etc. + +C interface support for making new classes. + +make sure DLL-ized stuff preserved ... but class numbers should no longer be +exported. + +point geom ( = sphere of radius 0 ) + +geoms stored in doubly linked lists in space (fast removal). + +bodies need to keep geoms pointers and call dGeomMoved() in dBodySetPosition() +etc and world step. PROBLEM: links dynamics and collision together too much, +makes it hard to extract ODE collision ... unless we say: dGeomMoved() and +dGeomID must be supplied by the new collision library! + +dCollide() should take spaces as arguments - it should call dSpaceCollide2() +with its own callback that puts all found contacts in the array, stopping +when there is no more space left in the array. + +dxSpace::getGeom() - the geom numbers will change as geoms are dirtied - find +some other numbering scheme, or document this behavior. + +the 'placeable' property - objects that should not ever be attached to bodies +should flag an error when setBody etc are called. + +dGeomSetBody(0) - DOC: the position and orientation of the body will be +preserved. in this case the geom should NOT be dirtied (dGeomMoved() should +not be called). + +DOC: dGeomGetBodyNext() as part of dynamics/collision interface + +groups/spaces are subclasses of geom. + +groups/spaces can contain other groups/spaces. geom can be owned by a +group/space. collision handling: + geom-geom : standard collision function + geom-group : special space code + group-group : n^2 tests (or n space tests) - hard to optimize because + of disjoint space representations. + group internal : normal space internal-collision code + +groups/spaces can be told that some objects never move, i.e. that the objects +are locked. should we lock the whole space? + locking: the AABB for the object is not recalculated + +groups/spaces can be told that the internal contents self-intersect or not. +actually an old ODE group is the equivalent of an old ODE simple space. + - just call dCollide() or not. + +the group doesn't get passed to the space callback any more ... only the +intersecting geoms get passed? maybe the callback can initiate the extra +intersection tests itself? (because we want programmable flexibility to +determine what gets intersected and what doesn't) + - NO + +infrastructure to indicate when an object has moved (and thus its AABB needs +to be recalculated) + +space enumeration functions. make sure that there are no additions or deletions +while enumeration is taking place. + - documented the behavior, didn't disallow it + +cache the AABB in the dxGeom? (for non-moving objects) - perhaps keep a +pointer to separately allocated space? ... no + +DOC: dGeomGetClass() is a first-class geom function, not in the "User +defined classes" section. it returns a constant that can be checked +against dSphereClass etc. + +remove dxGeom dependence on dBodyID? ... not yet + +dBase -> dxBase + +allow a geom to be inserted into multiple spaces? need this to optimize some +kinds of tests ... no + +update docs. + +make CHECK_NOT_LOCKED an assert. + +DOC: "Calling these functions on a non-placeable geom results in a +runtime error." ...in the debug build only? + +non-placeable geoms should not allocate dxPosR. perhaps pass a dGeom +constructor arg that says 'placeable' or not - this also sets the +GEOM_PLACEABLE flag. + +GeomTransform: + final_pos and final_R valid if no GEOM_AABB_BAD flag!!! + fix up this code, esp use of ComputeTX(). + +Space incompatibilities: no dSpaceDestroy(), dGeomDestroy() does not +take a dSpaceID ... dSpaceDestroy() added. + +GeomGroup incompatibilities: + dCollide() used to take a GeomGroup and would return all the contact + points for all the intersecting objects. now you have to call + dSpaceCollide2() and get a callback for each one. + need to provide old behavior. + +simple space optimization: we should keep the precomputed AABB for the +non-moving geoms around, so that when the other geoms move we can just +compute the AABBs for those geoms and then combine it with the non-moving AABB. + --> too hard! + +collision build options: old and new + +tidyups for collision: + * rationalize what stuff goes in what source files, and file names + * minimize set of header files that all collision* sources use - after + all changes. + * update ode-cpp stuff (C++ interface header files). + +porting guide: + ODE list email + + dGeomGetSpaceAABB() deleted + + dGeomGetClass (geom_group); used to return a unique type for + GeomGroups, but now it returns dSimpleSpaceID. + +tidyups: update DLL declarations. + diff --git a/libraries/ode-0.9/ode/demo/Makefile.am b/libraries/ode-0.9/ode/demo/Makefile.am new file mode 100644 index 0000000000..361ad53f9c --- /dev/null +++ b/libraries/ode-0.9/ode/demo/Makefile.am @@ -0,0 +1,254 @@ +AM_CXXFLAGS = @ARCHFLAGS@ @CXXFLAGS@ -I$(top_srcdir)/include -I$(top_builddir)/include +AM_CFLAGS = @ARCHFLAGS@ @CXXFLAGS@ -I$(top_srcdir)/include -I$(top_builddir)/include + +noinst_PROGRAMS=demo_collision \ + demo_slider \ + demo_feedback \ + demo_crash \ + demo_space \ + demo_I \ + demo_friction \ + demo_space_stress \ + demo_boxstack demo_hinge \ + demo_step \ + demo_buggy \ + demo_joints \ + demo_motor \ + demo_chain1 \ + demo_chain2 \ + demo_cylvssphere \ + demo_ode \ + demo_plane2d \ + demo_heightfield \ + demo_convex_cd \ + demo_jointPR +if TRIMESH +noinst_PROGRAMS+= demo_trimesh demo_moving_trimesh demo_basket demo_cyl +endif +demo_collision_SOURCES= demo_collision.cpp +demo_slider_SOURCES= demo_slider.cpp +demo_feedback_SOURCES= demo_feedback.cpp +demo_crash_SOURCES= demo_crash.cpp +demo_space_SOURCES= demo_space.cpp +demo_I_SOURCES= demo_I.cpp +demo_friction_SOURCES= demo_friction.cpp +demo_space_stress_SOURCES= demo_space_stress.cpp +demo_boxstack_SOURCES= demo_boxstack.cpp +demo_hinge_SOURCES= demo_hinge.cpp +demo_step_SOURCES= demo_step.cpp +demo_buggy_SOURCES= demo_buggy.cpp +demo_cyl_SOURCES= demo_cyl.cpp world_geom3.h +demo_cylvssphere_SOURCES= demo_cylvssphere.cpp +demo_joints_SOURCES= demo_joints.cpp +demo_jointPR_SOURCES= demo_jointPR.cpp +demo_motor_SOURCES= demo_motor.cpp +demo_chain1_SOURCES= demo_chain1.c +demo_chain2_SOURCES= demo_chain2.cpp +demo_ode_SOURCES= demo_ode.cpp +demo_plane2d_SOURCES= demo_plane2d.cpp +demo_heightfield_SOURCES= demo_heightfield.cpp +demo_convex_cd_SOURCES= demo_convex_cd.cpp +demo_collision_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ +demo_slider_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ +demo_feedback_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ +demo_crash_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ +demo_space_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ +demo_I_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ +demo_friction_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ +demo_space_stress_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ +demo_boxstack_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ +demo_hinge_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ +demo_step_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ +demo_buggy_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ +demo_cyl_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ +demo_cylvssphere_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ +demo_joints_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ +demo_jointPR_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ +demo_motor_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ +demo_chain1_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ +demo_chain2_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ +demo_ode_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ +demo_plane2d_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ +demo_heightfield_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ +demo_convex_cd_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ + +demo_collision_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a +demo_slider_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a +demo_feedback_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a +demo_crash_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a +demo_space_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a +demo_I_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a +demo_friction_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a +demo_space_stress_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a +demo_boxstack_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a +demo_hinge_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a +demo_step_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a +demo_buggy_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a +demo_cyl_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a +demo_cylvssphere_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a +demo_joints_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a +demo_jointPR_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a +demo_motor_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a +demo_chain1_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a +demo_chain2_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a +demo_ode_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a +demo_plane2d_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a +demo_heightfield_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a +demo_convex_cd_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a + +if TRIMESH +demo_trimesh_SOURCES= demo_trimesh.cpp +demo_moving_trimesh_SOURCES= demo_moving_trimesh.cpp +demo_basket_SOURCES= demo_basket.cpp +demo_trimesh_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ \ + @GL_LIBS@ @LIBS@ +demo_moving_trimesh_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ \ + @GL_LIBS@ @LIBS@ +demo_basket_LDFLAGS= -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ \ + @GL_LIBS@ @LIBS@ +demo_trimesh_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a +demo_moving_trimesh_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a + +demo_basket_DEPENDENCIES= $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a + +endif + +demo_ode_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_plane2d_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_heightfield_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_chain2_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_chain1_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_joints_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_jointPR_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_motor_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_buggy_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_cyl_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_cylvssphere_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_step_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_hinge_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_boxstack_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_space_stress_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_friction_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_I_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_space_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_crash_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_slider_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_feedback_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_collision_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_convex_cd_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ + + +if TRIMESH +demo_trimesh_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_moving_trimesh_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_basket_LDADD= -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +endif + + +if WIN32 +resources.o: ../../drawstuff/src/resources.rc ../../drawstuff/src/resource.h + @WINDRES@ ../../drawstuff/src/resources.rc -o resources.o +demo_ode_LDADD+= resources.o +demo_heightfield_LDADD+= resources.o +demo_chain2_LDADD+= resources.o +demo_chain1_LDADD+= resources.o +demo_joints_LDADD+= resources.o +demo_jointPR_LDADD+= resources.o +demo_motor_LDADD+= resources.o +demo_buggy_LDADD+= resources.o +demo_cyl_LDADD+= resources.o +demo_cylvssphere_LDADD+= resources.o +demo_step_LDADD+= resources.o +demo_hinge_LDADD+= resources.o +demo_boxstack_LDADD+= resources.o +demo_space_stress_LDADD+= resources.o +demo_friction_LDADD+= resources.o +demo_I_LDADD+= resources.o +demo_space_LDADD+= resources.o +demo_crash_LDADD+= resources.o +demo_slider_LDADD+= resources.o +demo_feedback_LDADD+= resources.o +demo_collision_LDADD+= resources.o +demo_convex_cd_LDADD+= resources.o +demo_ode_DEPENDENCIES+= resources.o +demo_chain2_DEPENDENCIES+= resources.o +demo_chain1_DEPENDENCIES+= resources.o +demo_joints_DEPENDENCIES+= resources.o +demo_jointPR_DEPENDENCIES+= resources.o +demo_motor_DEPENDENCIES+= resources.o +demo_buggy_DEPENDENCIES+= resources.o +demo_cyl_DEPENDENCIES+= resources.o +demo_cylvssphere_DEPENDENCIES+= resources.o +demo_step_DEPENDENCIES+= resources.o +demo_hinge_DEPENDENCIES+= resources.o +demo_boxstack_DEPENDENCIES+= resources.o +demo_space_stress_DEPENDENCIES+= resources.o +demo_friction_DEPENDENCIES+= resources.o +demo_I_DEPENDENCIES+= resources.o +demo_space_DEPENDENCIES+= resources.o +demo_crash_DEPENDENCIES+= resources.o +demo_slider_DEPENDENCIES+= resources.o +demo_feedback_DEPENDENCIES+= resources.o +demo_collision_DEPENDENCIES+= resources.o +demo_convex_cd_DEPENDENCIES+= resources.o + +if TRIMESH +demo_trimesh_LDADD+= resources.o +demo_moving_trimesh_LDADD+= resources.o +demo_trimesh_DEPENDENCIES+= resources.o +demo_moving_trimesh_DEPENDENCIES+= resources.o +demo_basket_DEPENDENCIES+= resources.o +endif +endif diff --git a/libraries/ode-0.9/ode/demo/Makefile.in b/libraries/ode-0.9/ode/demo/Makefile.in new file mode 100644 index 0000000000..8e73f18424 --- /dev/null +++ b/libraries/ode-0.9/ode/demo/Makefile.in @@ -0,0 +1,953 @@ +# Makefile.in generated by automake 1.10 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006 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@ +target_triplet = @target@ +noinst_PROGRAMS = demo_collision$(EXEEXT) demo_slider$(EXEEXT) \ + demo_feedback$(EXEEXT) demo_crash$(EXEEXT) demo_space$(EXEEXT) \ + demo_I$(EXEEXT) demo_friction$(EXEEXT) \ + demo_space_stress$(EXEEXT) demo_boxstack$(EXEEXT) \ + demo_hinge$(EXEEXT) demo_step$(EXEEXT) demo_buggy$(EXEEXT) \ + demo_joints$(EXEEXT) demo_motor$(EXEEXT) demo_chain1$(EXEEXT) \ + demo_chain2$(EXEEXT) demo_cylvssphere$(EXEEXT) \ + demo_ode$(EXEEXT) demo_plane2d$(EXEEXT) \ + demo_heightfield$(EXEEXT) demo_convex_cd$(EXEEXT) \ + demo_jointPR$(EXEEXT) $(am__EXEEXT_1) +@TRIMESH_TRUE@am__append_1 = demo_trimesh demo_moving_trimesh demo_basket demo_cyl +@WIN32_TRUE@am__append_2 = resources.o +@WIN32_TRUE@am__append_3 = resources.o +@WIN32_TRUE@am__append_4 = resources.o +@WIN32_TRUE@am__append_5 = resources.o +@WIN32_TRUE@am__append_6 = resources.o +@WIN32_TRUE@am__append_7 = resources.o +@WIN32_TRUE@am__append_8 = resources.o +@WIN32_TRUE@am__append_9 = resources.o +@WIN32_TRUE@am__append_10 = resources.o +@WIN32_TRUE@am__append_11 = resources.o +@WIN32_TRUE@am__append_12 = resources.o +@WIN32_TRUE@am__append_13 = resources.o +@WIN32_TRUE@am__append_14 = resources.o +@WIN32_TRUE@am__append_15 = resources.o +@WIN32_TRUE@am__append_16 = resources.o +@WIN32_TRUE@am__append_17 = resources.o +@WIN32_TRUE@am__append_18 = resources.o +@WIN32_TRUE@am__append_19 = resources.o +@WIN32_TRUE@am__append_20 = resources.o +@WIN32_TRUE@am__append_21 = resources.o +@WIN32_TRUE@am__append_22 = resources.o +@WIN32_TRUE@am__append_23 = resources.o +@WIN32_TRUE@am__append_24 = resources.o +@WIN32_TRUE@am__append_25 = resources.o +@WIN32_TRUE@am__append_26 = resources.o +@WIN32_TRUE@am__append_27 = resources.o +@WIN32_TRUE@am__append_28 = resources.o +@WIN32_TRUE@am__append_29 = resources.o +@WIN32_TRUE@am__append_30 = resources.o +@WIN32_TRUE@am__append_31 = resources.o +@WIN32_TRUE@am__append_32 = resources.o +@WIN32_TRUE@am__append_33 = resources.o +@WIN32_TRUE@am__append_34 = resources.o +@WIN32_TRUE@am__append_35 = resources.o +@WIN32_TRUE@am__append_36 = resources.o +@WIN32_TRUE@am__append_37 = resources.o +@WIN32_TRUE@am__append_38 = resources.o +@WIN32_TRUE@am__append_39 = resources.o +@WIN32_TRUE@am__append_40 = resources.o +@WIN32_TRUE@am__append_41 = resources.o +@WIN32_TRUE@am__append_42 = resources.o +@WIN32_TRUE@am__append_43 = resources.o +@WIN32_TRUE@am__append_44 = resources.o +@TRIMESH_TRUE@@WIN32_TRUE@am__append_45 = resources.o +@TRIMESH_TRUE@@WIN32_TRUE@am__append_46 = resources.o +@TRIMESH_TRUE@@WIN32_TRUE@am__append_47 = resources.o +@TRIMESH_TRUE@@WIN32_TRUE@am__append_48 = resources.o +@TRIMESH_TRUE@@WIN32_TRUE@am__append_49 = resources.o +subdir = ode/demo +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)/include/ode/config.h +CONFIG_CLEAN_FILES = +@TRIMESH_TRUE@am__EXEEXT_1 = demo_trimesh$(EXEEXT) \ +@TRIMESH_TRUE@ demo_moving_trimesh$(EXEEXT) \ +@TRIMESH_TRUE@ demo_basket$(EXEEXT) demo_cyl$(EXEEXT) +PROGRAMS = $(noinst_PROGRAMS) +am_demo_I_OBJECTS = demo_I.$(OBJEXT) +demo_I_OBJECTS = $(am_demo_I_OBJECTS) +demo_I_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(demo_I_LDFLAGS) \ + $(LDFLAGS) -o $@ +am__demo_basket_SOURCES_DIST = demo_basket.cpp +@TRIMESH_TRUE@am_demo_basket_OBJECTS = demo_basket.$(OBJEXT) +demo_basket_OBJECTS = $(am_demo_basket_OBJECTS) +demo_basket_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(demo_basket_LDFLAGS) $(LDFLAGS) -o $@ +am_demo_boxstack_OBJECTS = demo_boxstack.$(OBJEXT) +demo_boxstack_OBJECTS = $(am_demo_boxstack_OBJECTS) +demo_boxstack_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(demo_boxstack_LDFLAGS) $(LDFLAGS) -o $@ +am_demo_buggy_OBJECTS = demo_buggy.$(OBJEXT) +demo_buggy_OBJECTS = $(am_demo_buggy_OBJECTS) +demo_buggy_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(demo_buggy_LDFLAGS) $(LDFLAGS) -o $@ +am_demo_chain1_OBJECTS = demo_chain1.$(OBJEXT) +demo_chain1_OBJECTS = $(am_demo_chain1_OBJECTS) +demo_chain1_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(demo_chain1_LDFLAGS) $(LDFLAGS) -o $@ +am_demo_chain2_OBJECTS = demo_chain2.$(OBJEXT) +demo_chain2_OBJECTS = $(am_demo_chain2_OBJECTS) +demo_chain2_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(demo_chain2_LDFLAGS) $(LDFLAGS) -o $@ +am_demo_collision_OBJECTS = demo_collision.$(OBJEXT) +demo_collision_OBJECTS = $(am_demo_collision_OBJECTS) +demo_collision_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(demo_collision_LDFLAGS) $(LDFLAGS) -o $@ +am_demo_convex_cd_OBJECTS = demo_convex_cd.$(OBJEXT) +demo_convex_cd_OBJECTS = $(am_demo_convex_cd_OBJECTS) +demo_convex_cd_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(demo_convex_cd_LDFLAGS) $(LDFLAGS) -o $@ +am_demo_crash_OBJECTS = demo_crash.$(OBJEXT) +demo_crash_OBJECTS = $(am_demo_crash_OBJECTS) +demo_crash_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(demo_crash_LDFLAGS) $(LDFLAGS) -o $@ +am_demo_cyl_OBJECTS = demo_cyl.$(OBJEXT) +demo_cyl_OBJECTS = $(am_demo_cyl_OBJECTS) +demo_cyl_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(demo_cyl_LDFLAGS) $(LDFLAGS) -o $@ +am_demo_cylvssphere_OBJECTS = demo_cylvssphere.$(OBJEXT) +demo_cylvssphere_OBJECTS = $(am_demo_cylvssphere_OBJECTS) +demo_cylvssphere_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(demo_cylvssphere_LDFLAGS) $(LDFLAGS) -o $@ +am_demo_feedback_OBJECTS = demo_feedback.$(OBJEXT) +demo_feedback_OBJECTS = $(am_demo_feedback_OBJECTS) +demo_feedback_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(demo_feedback_LDFLAGS) $(LDFLAGS) -o $@ +am_demo_friction_OBJECTS = demo_friction.$(OBJEXT) +demo_friction_OBJECTS = $(am_demo_friction_OBJECTS) +demo_friction_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(demo_friction_LDFLAGS) $(LDFLAGS) -o $@ +am_demo_heightfield_OBJECTS = demo_heightfield.$(OBJEXT) +demo_heightfield_OBJECTS = $(am_demo_heightfield_OBJECTS) +demo_heightfield_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(demo_heightfield_LDFLAGS) $(LDFLAGS) -o $@ +am_demo_hinge_OBJECTS = demo_hinge.$(OBJEXT) +demo_hinge_OBJECTS = $(am_demo_hinge_OBJECTS) +demo_hinge_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(demo_hinge_LDFLAGS) $(LDFLAGS) -o $@ +am_demo_jointPR_OBJECTS = demo_jointPR.$(OBJEXT) +demo_jointPR_OBJECTS = $(am_demo_jointPR_OBJECTS) +demo_jointPR_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(demo_jointPR_LDFLAGS) $(LDFLAGS) -o $@ +am_demo_joints_OBJECTS = demo_joints.$(OBJEXT) +demo_joints_OBJECTS = $(am_demo_joints_OBJECTS) +demo_joints_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(demo_joints_LDFLAGS) $(LDFLAGS) -o $@ +am_demo_motor_OBJECTS = demo_motor.$(OBJEXT) +demo_motor_OBJECTS = $(am_demo_motor_OBJECTS) +demo_motor_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(demo_motor_LDFLAGS) $(LDFLAGS) -o $@ +am__demo_moving_trimesh_SOURCES_DIST = demo_moving_trimesh.cpp +@TRIMESH_TRUE@am_demo_moving_trimesh_OBJECTS = \ +@TRIMESH_TRUE@ demo_moving_trimesh.$(OBJEXT) +demo_moving_trimesh_OBJECTS = $(am_demo_moving_trimesh_OBJECTS) +demo_moving_trimesh_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(demo_moving_trimesh_LDFLAGS) $(LDFLAGS) -o $@ +am_demo_ode_OBJECTS = demo_ode.$(OBJEXT) +demo_ode_OBJECTS = $(am_demo_ode_OBJECTS) +demo_ode_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(demo_ode_LDFLAGS) $(LDFLAGS) -o $@ +am_demo_plane2d_OBJECTS = demo_plane2d.$(OBJEXT) +demo_plane2d_OBJECTS = $(am_demo_plane2d_OBJECTS) +demo_plane2d_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(demo_plane2d_LDFLAGS) $(LDFLAGS) -o $@ +am_demo_slider_OBJECTS = demo_slider.$(OBJEXT) +demo_slider_OBJECTS = $(am_demo_slider_OBJECTS) +demo_slider_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(demo_slider_LDFLAGS) $(LDFLAGS) -o $@ +am_demo_space_OBJECTS = demo_space.$(OBJEXT) +demo_space_OBJECTS = $(am_demo_space_OBJECTS) +demo_space_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(demo_space_LDFLAGS) $(LDFLAGS) -o $@ +am_demo_space_stress_OBJECTS = demo_space_stress.$(OBJEXT) +demo_space_stress_OBJECTS = $(am_demo_space_stress_OBJECTS) +demo_space_stress_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(demo_space_stress_LDFLAGS) $(LDFLAGS) -o $@ +am_demo_step_OBJECTS = demo_step.$(OBJEXT) +demo_step_OBJECTS = $(am_demo_step_OBJECTS) +demo_step_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(demo_step_LDFLAGS) $(LDFLAGS) -o $@ +am__demo_trimesh_SOURCES_DIST = demo_trimesh.cpp +@TRIMESH_TRUE@am_demo_trimesh_OBJECTS = demo_trimesh.$(OBJEXT) +demo_trimesh_OBJECTS = $(am_demo_trimesh_OBJECTS) +demo_trimesh_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(demo_trimesh_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I. -I$(top_builddir)/include/ode@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +SOURCES = $(demo_I_SOURCES) $(demo_basket_SOURCES) \ + $(demo_boxstack_SOURCES) $(demo_buggy_SOURCES) \ + $(demo_chain1_SOURCES) $(demo_chain2_SOURCES) \ + $(demo_collision_SOURCES) $(demo_convex_cd_SOURCES) \ + $(demo_crash_SOURCES) $(demo_cyl_SOURCES) \ + $(demo_cylvssphere_SOURCES) $(demo_feedback_SOURCES) \ + $(demo_friction_SOURCES) $(demo_heightfield_SOURCES) \ + $(demo_hinge_SOURCES) $(demo_jointPR_SOURCES) \ + $(demo_joints_SOURCES) $(demo_motor_SOURCES) \ + $(demo_moving_trimesh_SOURCES) $(demo_ode_SOURCES) \ + $(demo_plane2d_SOURCES) $(demo_slider_SOURCES) \ + $(demo_space_SOURCES) $(demo_space_stress_SOURCES) \ + $(demo_step_SOURCES) $(demo_trimesh_SOURCES) +DIST_SOURCES = $(demo_I_SOURCES) $(am__demo_basket_SOURCES_DIST) \ + $(demo_boxstack_SOURCES) $(demo_buggy_SOURCES) \ + $(demo_chain1_SOURCES) $(demo_chain2_SOURCES) \ + $(demo_collision_SOURCES) $(demo_convex_cd_SOURCES) \ + $(demo_crash_SOURCES) $(demo_cyl_SOURCES) \ + $(demo_cylvssphere_SOURCES) $(demo_feedback_SOURCES) \ + $(demo_friction_SOURCES) $(demo_heightfield_SOURCES) \ + $(demo_hinge_SOURCES) $(demo_jointPR_SOURCES) \ + $(demo_joints_SOURCES) $(demo_motor_SOURCES) \ + $(am__demo_moving_trimesh_SOURCES_DIST) $(demo_ode_SOURCES) \ + $(demo_plane2d_SOURCES) $(demo_slider_SOURCES) \ + $(demo_space_SOURCES) $(demo_space_stress_SOURCES) \ + $(demo_step_SOURCES) $(am__demo_trimesh_SOURCES_DIST) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +ARCHFLAGS = @ARCHFLAGS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DRAWSTUFF = @DRAWSTUFF@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +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@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +ODE_AGE = @ODE_AGE@ +ODE_CURRENT = @ODE_CURRENT@ +ODE_RELEASE = @ODE_RELEASE@ +ODE_REVISION = @ODE_REVISION@ +ODE_SONAME = @ODE_SONAME@ +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@ +SET_MAKE = @SET_MAKE@ +SHARED_LDFLAGS = @SHARED_LDFLAGS@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TOPDIR = @TOPDIR@ +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_WINDRES = @ac_ct_WINDRES@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +so_ext = @so_ext@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CXXFLAGS = @ARCHFLAGS@ @CXXFLAGS@ -I$(top_srcdir)/include -I$(top_builddir)/include +AM_CFLAGS = @ARCHFLAGS@ @CXXFLAGS@ -I$(top_srcdir)/include -I$(top_builddir)/include +demo_collision_SOURCES = demo_collision.cpp +demo_slider_SOURCES = demo_slider.cpp +demo_feedback_SOURCES = demo_feedback.cpp +demo_crash_SOURCES = demo_crash.cpp +demo_space_SOURCES = demo_space.cpp +demo_I_SOURCES = demo_I.cpp +demo_friction_SOURCES = demo_friction.cpp +demo_space_stress_SOURCES = demo_space_stress.cpp +demo_boxstack_SOURCES = demo_boxstack.cpp +demo_hinge_SOURCES = demo_hinge.cpp +demo_step_SOURCES = demo_step.cpp +demo_buggy_SOURCES = demo_buggy.cpp +demo_cyl_SOURCES = demo_cyl.cpp world_geom3.h +demo_cylvssphere_SOURCES = demo_cylvssphere.cpp +demo_joints_SOURCES = demo_joints.cpp +demo_jointPR_SOURCES = demo_jointPR.cpp +demo_motor_SOURCES = demo_motor.cpp +demo_chain1_SOURCES = demo_chain1.c +demo_chain2_SOURCES = demo_chain2.cpp +demo_ode_SOURCES = demo_ode.cpp +demo_plane2d_SOURCES = demo_plane2d.cpp +demo_heightfield_SOURCES = demo_heightfield.cpp +demo_convex_cd_SOURCES = demo_convex_cd.cpp +demo_collision_LDFLAGS = -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ + +demo_slider_LDFLAGS = -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ + +demo_feedback_LDFLAGS = -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ + +demo_crash_LDFLAGS = -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ + +demo_space_LDFLAGS = -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ + +demo_I_LDFLAGS = -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ + +demo_friction_LDFLAGS = -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ + +demo_space_stress_LDFLAGS = -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ + +demo_boxstack_LDFLAGS = -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ + +demo_hinge_LDFLAGS = -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ + +demo_step_LDFLAGS = -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ + +demo_buggy_LDFLAGS = -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ + +demo_cyl_LDFLAGS = -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ + +demo_cylvssphere_LDFLAGS = -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ + +demo_joints_LDFLAGS = -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ + +demo_jointPR_LDFLAGS = -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ + +demo_motor_LDFLAGS = -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ + +demo_chain1_LDFLAGS = -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ + +demo_chain2_LDFLAGS = -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ + +demo_ode_LDFLAGS = -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ + +demo_plane2d_LDFLAGS = -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ + +demo_heightfield_LDFLAGS = -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ + +demo_convex_cd_LDFLAGS = -L$(top_builddir)/drawstuff/src \ + -L$(top_builddir)/ode/src @LDFLAGS@ + +demo_collision_DEPENDENCIES = $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a $(am__append_43) +demo_slider_DEPENDENCIES = $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a $(am__append_41) +demo_feedback_DEPENDENCIES = $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a $(am__append_42) +demo_crash_DEPENDENCIES = $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a $(am__append_40) +demo_space_DEPENDENCIES = $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a $(am__append_39) +demo_I_DEPENDENCIES = $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a $(am__append_38) +demo_friction_DEPENDENCIES = $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a $(am__append_37) +demo_space_stress_DEPENDENCIES = $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a $(am__append_36) +demo_boxstack_DEPENDENCIES = $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a $(am__append_35) +demo_hinge_DEPENDENCIES = $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a $(am__append_34) +demo_step_DEPENDENCIES = $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a $(am__append_33) +demo_buggy_DEPENDENCIES = $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a $(am__append_30) +demo_cyl_DEPENDENCIES = $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a $(am__append_31) +demo_cylvssphere_DEPENDENCIES = $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a $(am__append_32) +demo_joints_DEPENDENCIES = $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a $(am__append_27) +demo_jointPR_DEPENDENCIES = $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a $(am__append_28) +demo_motor_DEPENDENCIES = $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a $(am__append_29) +demo_chain1_DEPENDENCIES = $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a $(am__append_26) +demo_chain2_DEPENDENCIES = $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a $(am__append_25) +demo_ode_DEPENDENCIES = $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a $(am__append_24) +demo_plane2d_DEPENDENCIES = $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a + +demo_heightfield_DEPENDENCIES = $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a + +demo_convex_cd_DEPENDENCIES = $(top_builddir)/ode/src/libode.a \ + $(top_builddir)/drawstuff/src/libdrawstuff.a $(am__append_44) +@TRIMESH_TRUE@demo_trimesh_SOURCES = demo_trimesh.cpp +@TRIMESH_TRUE@demo_moving_trimesh_SOURCES = demo_moving_trimesh.cpp +@TRIMESH_TRUE@demo_basket_SOURCES = demo_basket.cpp +@TRIMESH_TRUE@demo_trimesh_LDFLAGS = -L$(top_builddir)/drawstuff/src \ +@TRIMESH_TRUE@ -L$(top_builddir)/ode/src @LDFLAGS@ \ +@TRIMESH_TRUE@ @GL_LIBS@ @LIBS@ + +@TRIMESH_TRUE@demo_moving_trimesh_LDFLAGS = -L$(top_builddir)/drawstuff/src \ +@TRIMESH_TRUE@ -L$(top_builddir)/ode/src @LDFLAGS@ \ +@TRIMESH_TRUE@ @GL_LIBS@ @LIBS@ + +@TRIMESH_TRUE@demo_basket_LDFLAGS = -L$(top_builddir)/drawstuff/src \ +@TRIMESH_TRUE@ -L$(top_builddir)/ode/src @LDFLAGS@ \ +@TRIMESH_TRUE@ @GL_LIBS@ @LIBS@ + +@TRIMESH_TRUE@demo_trimesh_DEPENDENCIES = \ +@TRIMESH_TRUE@ $(top_builddir)/ode/src/libode.a \ +@TRIMESH_TRUE@ $(top_builddir)/drawstuff/src/libdrawstuff.a \ +@TRIMESH_TRUE@ $(am__append_47) +@TRIMESH_TRUE@demo_moving_trimesh_DEPENDENCIES = \ +@TRIMESH_TRUE@ $(top_builddir)/ode/src/libode.a \ +@TRIMESH_TRUE@ $(top_builddir)/drawstuff/src/libdrawstuff.a \ +@TRIMESH_TRUE@ $(am__append_48) +@TRIMESH_TRUE@demo_basket_DEPENDENCIES = \ +@TRIMESH_TRUE@ $(top_builddir)/ode/src/libode.a \ +@TRIMESH_TRUE@ $(top_builddir)/drawstuff/src/libdrawstuff.a \ +@TRIMESH_TRUE@ $(am__append_49) +demo_ode_LDADD = -ldrawstuff $(top_builddir)/ode/src/libode.a \ + @GL_LIBS@ @LIBS@ $(am__append_2) +demo_plane2d_LDADD = -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +demo_heightfield_LDADD = -ldrawstuff $(top_builddir)/ode/src/libode.a \ + @GL_LIBS@ @LIBS@ $(am__append_3) +demo_chain2_LDADD = -ldrawstuff $(top_builddir)/ode/src/libode.a \ + @GL_LIBS@ @LIBS@ $(am__append_4) +demo_chain1_LDADD = -ldrawstuff $(top_builddir)/ode/src/libode.a \ + @GL_LIBS@ @LIBS@ $(am__append_5) +demo_joints_LDADD = -ldrawstuff $(top_builddir)/ode/src/libode.a \ + @GL_LIBS@ @LIBS@ $(am__append_6) +demo_jointPR_LDADD = -ldrawstuff $(top_builddir)/ode/src/libode.a \ + @GL_LIBS@ @LIBS@ $(am__append_7) +demo_motor_LDADD = -ldrawstuff $(top_builddir)/ode/src/libode.a \ + @GL_LIBS@ @LIBS@ $(am__append_8) +demo_buggy_LDADD = -ldrawstuff $(top_builddir)/ode/src/libode.a \ + @GL_LIBS@ @LIBS@ $(am__append_9) +demo_cyl_LDADD = -ldrawstuff $(top_builddir)/ode/src/libode.a \ + @GL_LIBS@ @LIBS@ $(am__append_10) +demo_cylvssphere_LDADD = -ldrawstuff $(top_builddir)/ode/src/libode.a \ + @GL_LIBS@ @LIBS@ $(am__append_11) +demo_step_LDADD = -ldrawstuff $(top_builddir)/ode/src/libode.a \ + @GL_LIBS@ @LIBS@ $(am__append_12) +demo_hinge_LDADD = -ldrawstuff $(top_builddir)/ode/src/libode.a \ + @GL_LIBS@ @LIBS@ $(am__append_13) +demo_boxstack_LDADD = -ldrawstuff $(top_builddir)/ode/src/libode.a \ + @GL_LIBS@ @LIBS@ $(am__append_14) +demo_space_stress_LDADD = -ldrawstuff $(top_builddir)/ode/src/libode.a \ + @GL_LIBS@ @LIBS@ $(am__append_15) +demo_friction_LDADD = -ldrawstuff $(top_builddir)/ode/src/libode.a \ + @GL_LIBS@ @LIBS@ $(am__append_16) +demo_I_LDADD = -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ \ + @LIBS@ $(am__append_17) +demo_space_LDADD = -ldrawstuff $(top_builddir)/ode/src/libode.a \ + @GL_LIBS@ @LIBS@ $(am__append_18) +demo_crash_LDADD = -ldrawstuff $(top_builddir)/ode/src/libode.a \ + @GL_LIBS@ @LIBS@ $(am__append_19) +demo_slider_LDADD = -ldrawstuff $(top_builddir)/ode/src/libode.a \ + @GL_LIBS@ @LIBS@ $(am__append_20) +demo_feedback_LDADD = -ldrawstuff $(top_builddir)/ode/src/libode.a \ + @GL_LIBS@ @LIBS@ $(am__append_21) +demo_collision_LDADD = -ldrawstuff $(top_builddir)/ode/src/libode.a \ + @GL_LIBS@ @LIBS@ $(am__append_22) +demo_convex_cd_LDADD = -ldrawstuff $(top_builddir)/ode/src/libode.a \ + @GL_LIBS@ @LIBS@ $(am__append_23) +@TRIMESH_TRUE@demo_trimesh_LDADD = -ldrawstuff \ +@TRIMESH_TRUE@ $(top_builddir)/ode/src/libode.a @GL_LIBS@ \ +@TRIMESH_TRUE@ @LIBS@ $(am__append_45) +@TRIMESH_TRUE@demo_moving_trimesh_LDADD = -ldrawstuff \ +@TRIMESH_TRUE@ $(top_builddir)/ode/src/libode.a @GL_LIBS@ \ +@TRIMESH_TRUE@ @LIBS@ $(am__append_46) +@TRIMESH_TRUE@demo_basket_LDADD = -ldrawstuff $(top_builddir)/ode/src/libode.a @GL_LIBS@ @LIBS@ +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .cpp .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 \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign ode/demo/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign ode/demo/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: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) +demo_I$(EXEEXT): $(demo_I_OBJECTS) $(demo_I_DEPENDENCIES) + @rm -f demo_I$(EXEEXT) + $(demo_I_LINK) $(demo_I_OBJECTS) $(demo_I_LDADD) $(LIBS) +demo_basket$(EXEEXT): $(demo_basket_OBJECTS) $(demo_basket_DEPENDENCIES) + @rm -f demo_basket$(EXEEXT) + $(demo_basket_LINK) $(demo_basket_OBJECTS) $(demo_basket_LDADD) $(LIBS) +demo_boxstack$(EXEEXT): $(demo_boxstack_OBJECTS) $(demo_boxstack_DEPENDENCIES) + @rm -f demo_boxstack$(EXEEXT) + $(demo_boxstack_LINK) $(demo_boxstack_OBJECTS) $(demo_boxstack_LDADD) $(LIBS) +demo_buggy$(EXEEXT): $(demo_buggy_OBJECTS) $(demo_buggy_DEPENDENCIES) + @rm -f demo_buggy$(EXEEXT) + $(demo_buggy_LINK) $(demo_buggy_OBJECTS) $(demo_buggy_LDADD) $(LIBS) +demo_chain1$(EXEEXT): $(demo_chain1_OBJECTS) $(demo_chain1_DEPENDENCIES) + @rm -f demo_chain1$(EXEEXT) + $(demo_chain1_LINK) $(demo_chain1_OBJECTS) $(demo_chain1_LDADD) $(LIBS) +demo_chain2$(EXEEXT): $(demo_chain2_OBJECTS) $(demo_chain2_DEPENDENCIES) + @rm -f demo_chain2$(EXEEXT) + $(demo_chain2_LINK) $(demo_chain2_OBJECTS) $(demo_chain2_LDADD) $(LIBS) +demo_collision$(EXEEXT): $(demo_collision_OBJECTS) $(demo_collision_DEPENDENCIES) + @rm -f demo_collision$(EXEEXT) + $(demo_collision_LINK) $(demo_collision_OBJECTS) $(demo_collision_LDADD) $(LIBS) +demo_convex_cd$(EXEEXT): $(demo_convex_cd_OBJECTS) $(demo_convex_cd_DEPENDENCIES) + @rm -f demo_convex_cd$(EXEEXT) + $(demo_convex_cd_LINK) $(demo_convex_cd_OBJECTS) $(demo_convex_cd_LDADD) $(LIBS) +demo_crash$(EXEEXT): $(demo_crash_OBJECTS) $(demo_crash_DEPENDENCIES) + @rm -f demo_crash$(EXEEXT) + $(demo_crash_LINK) $(demo_crash_OBJECTS) $(demo_crash_LDADD) $(LIBS) +demo_cyl$(EXEEXT): $(demo_cyl_OBJECTS) $(demo_cyl_DEPENDENCIES) + @rm -f demo_cyl$(EXEEXT) + $(demo_cyl_LINK) $(demo_cyl_OBJECTS) $(demo_cyl_LDADD) $(LIBS) +demo_cylvssphere$(EXEEXT): $(demo_cylvssphere_OBJECTS) $(demo_cylvssphere_DEPENDENCIES) + @rm -f demo_cylvssphere$(EXEEXT) + $(demo_cylvssphere_LINK) $(demo_cylvssphere_OBJECTS) $(demo_cylvssphere_LDADD) $(LIBS) +demo_feedback$(EXEEXT): $(demo_feedback_OBJECTS) $(demo_feedback_DEPENDENCIES) + @rm -f demo_feedback$(EXEEXT) + $(demo_feedback_LINK) $(demo_feedback_OBJECTS) $(demo_feedback_LDADD) $(LIBS) +demo_friction$(EXEEXT): $(demo_friction_OBJECTS) $(demo_friction_DEPENDENCIES) + @rm -f demo_friction$(EXEEXT) + $(demo_friction_LINK) $(demo_friction_OBJECTS) $(demo_friction_LDADD) $(LIBS) +demo_heightfield$(EXEEXT): $(demo_heightfield_OBJECTS) $(demo_heightfield_DEPENDENCIES) + @rm -f demo_heightfield$(EXEEXT) + $(demo_heightfield_LINK) $(demo_heightfield_OBJECTS) $(demo_heightfield_LDADD) $(LIBS) +demo_hinge$(EXEEXT): $(demo_hinge_OBJECTS) $(demo_hinge_DEPENDENCIES) + @rm -f demo_hinge$(EXEEXT) + $(demo_hinge_LINK) $(demo_hinge_OBJECTS) $(demo_hinge_LDADD) $(LIBS) +demo_jointPR$(EXEEXT): $(demo_jointPR_OBJECTS) $(demo_jointPR_DEPENDENCIES) + @rm -f demo_jointPR$(EXEEXT) + $(demo_jointPR_LINK) $(demo_jointPR_OBJECTS) $(demo_jointPR_LDADD) $(LIBS) +demo_joints$(EXEEXT): $(demo_joints_OBJECTS) $(demo_joints_DEPENDENCIES) + @rm -f demo_joints$(EXEEXT) + $(demo_joints_LINK) $(demo_joints_OBJECTS) $(demo_joints_LDADD) $(LIBS) +demo_motor$(EXEEXT): $(demo_motor_OBJECTS) $(demo_motor_DEPENDENCIES) + @rm -f demo_motor$(EXEEXT) + $(demo_motor_LINK) $(demo_motor_OBJECTS) $(demo_motor_LDADD) $(LIBS) +demo_moving_trimesh$(EXEEXT): $(demo_moving_trimesh_OBJECTS) $(demo_moving_trimesh_DEPENDENCIES) + @rm -f demo_moving_trimesh$(EXEEXT) + $(demo_moving_trimesh_LINK) $(demo_moving_trimesh_OBJECTS) $(demo_moving_trimesh_LDADD) $(LIBS) +demo_ode$(EXEEXT): $(demo_ode_OBJECTS) $(demo_ode_DEPENDENCIES) + @rm -f demo_ode$(EXEEXT) + $(demo_ode_LINK) $(demo_ode_OBJECTS) $(demo_ode_LDADD) $(LIBS) +demo_plane2d$(EXEEXT): $(demo_plane2d_OBJECTS) $(demo_plane2d_DEPENDENCIES) + @rm -f demo_plane2d$(EXEEXT) + $(demo_plane2d_LINK) $(demo_plane2d_OBJECTS) $(demo_plane2d_LDADD) $(LIBS) +demo_slider$(EXEEXT): $(demo_slider_OBJECTS) $(demo_slider_DEPENDENCIES) + @rm -f demo_slider$(EXEEXT) + $(demo_slider_LINK) $(demo_slider_OBJECTS) $(demo_slider_LDADD) $(LIBS) +demo_space$(EXEEXT): $(demo_space_OBJECTS) $(demo_space_DEPENDENCIES) + @rm -f demo_space$(EXEEXT) + $(demo_space_LINK) $(demo_space_OBJECTS) $(demo_space_LDADD) $(LIBS) +demo_space_stress$(EXEEXT): $(demo_space_stress_OBJECTS) $(demo_space_stress_DEPENDENCIES) + @rm -f demo_space_stress$(EXEEXT) + $(demo_space_stress_LINK) $(demo_space_stress_OBJECTS) $(demo_space_stress_LDADD) $(LIBS) +demo_step$(EXEEXT): $(demo_step_OBJECTS) $(demo_step_DEPENDENCIES) + @rm -f demo_step$(EXEEXT) + $(demo_step_LINK) $(demo_step_OBJECTS) $(demo_step_LDADD) $(LIBS) +demo_trimesh$(EXEEXT): $(demo_trimesh_OBJECTS) $(demo_trimesh_DEPENDENCIES) + @rm -f demo_trimesh$(EXEEXT) + $(demo_trimesh_LINK) $(demo_trimesh_OBJECTS) $(demo_trimesh_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_I.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_basket.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_boxstack.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_buggy.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_chain1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_chain2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_collision.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_convex_cd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_crash.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_cyl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_cylvssphere.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_feedback.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_friction.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_heightfield.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_hinge.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_jointPR.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_joints.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_motor.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_moving_trimesh.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_ode.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_plane2d.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_slider.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_space.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_space_stress.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_step.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demo_trimesh.Po@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) '$<'` + +.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) '$<'` + +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; } \ + END { 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; } \ + END { 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=; \ + 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; } \ + END { 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-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 + +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-noinstPROGRAMS ctags distclean distclean-compile \ + distclean-generic 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 pdf pdf-am ps ps-am tags uninstall \ + uninstall-am + + +@WIN32_TRUE@resources.o: ../../drawstuff/src/resources.rc ../../drawstuff/src/resource.h +@WIN32_TRUE@ @WINDRES@ ../../drawstuff/src/resources.rc -o resources.o +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libraries/ode-0.9/ode/demo/basket_geom.h b/libraries/ode-0.9/ode/demo/basket_geom.h new file mode 100644 index 0000000000..7796ca8131 --- /dev/null +++ b/libraries/ode-0.9/ode/demo/basket_geom.h @@ -0,0 +1,13 @@ + +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 int 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, +}; + diff --git a/libraries/ode-0.9/ode/demo/demo_I.cpp b/libraries/ode-0.9/ode/demo/demo_I.cpp new file mode 100644 index 0000000000..b4f8d6e486 --- /dev/null +++ b/libraries/ode-0.9/ode/demo/demo_I.cpp @@ -0,0 +1,254 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* + +test that the rotational physics is correct. + +an "anchor body" has a number of other randomly positioned bodies +("particles") attached to it by ball-and-socket joints, giving it some +random effective inertia tensor. the effective inertia matrix is calculated, +and then this inertia is assigned to another "test" body. a random torque is +applied to both bodies and the difference in angular velocity and orientation +is observed after a number of iterations. + +typical errors for each test cycle are about 1e-5 ... 1e-4. + +*/ + + +#include +#include +#include + +#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() +{ + 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 +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include + +#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 + +#ifdef _MSC_VER +#pragma warning(disable:4244 4305) // for VC++, no precision loss complaints +#endif + + +//<---- 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 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 = 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) +{ + 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); + 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 == '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; + } +} + + +// 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_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; + } + + // 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 + +// 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/textures"; + if(argc==2) + { + fn.path_to_textures = argv[1]; + } + + // create world + dInitODE(); + 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; +} diff --git a/libraries/ode-0.9/ode/demo/demo_chain1.c b/libraries/ode-0.9/ode/demo/demo_chain1.c new file mode 100644 index 0000000000..e20c5dc892 --- /dev/null +++ b/libraries/ode-0.9/ode/demo/demo_chain1.c @@ -0,0 +1,171 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +/* exercise the C interface */ + +#include +#include "ode/ode.h" +#include "drawstuff/drawstuff.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}; + 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 + +#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 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() +{ + 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 + +#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) + + +// 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 + 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() +{ + 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/textures"; + + 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)); + dInitODE(); + + 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; +} diff --git a/libraries/ode-0.9/ode/demo/demo_convex_cd.cpp b/libraries/ode-0.9/ode/demo/demo_convex_cd.cpp new file mode 100644 index 0000000000..e1764f3f4e --- /dev/null +++ b/libraries/ode-0.9/ode/demo/demo_convex_cd.cpp @@ -0,0 +1,195 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * + * LICENSE.TXT and LICENSE-BSD.TXT for more details. * + * * + *************************************************************************/ + +#include +#include +#include +#include +#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 + 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 + +#ifdef dDOUBLE +#define dsDrawConvex dsDrawConvexD +#define dsDrawBox dsDrawBoxD +#endif + +dGeomID geoms[2]; +dSpaceID space; +dWorldID world; +dJointGroupID contactgroup; + +void start() +{ + // adjust the starting viewpoint a bit + float xyz[3],hpr[3]; + dsGetViewpoint (xyz,hpr); + hpr[0] += 7; + dsSetViewpoint (xyz,hpr); + geoms[0]=dCreateConvex (space, + planes, + planecount, + points, + pointcount, + polygons); + dGeomSetPosition (geoms[0],0,0,0.25); + geoms[1]=dCreateConvex (space, + planes, + planecount, + points, + pointcount, + polygons); + dGeomSetPosition (geoms[1],0.25,0.25,0.70); + +} + +int dCollideConvexConvex (dxGeom *o1, dxGeom *o2, int flags, + dContactGeom *contact, int skip); +void simLoop (int pause) +{ + static bool DumpInfo=true; + const dReal ss[3] = {0.02,0.02,0.02}; + dContactGeom contacts[8]; + int contactcount = dCollideConvexConvex(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); + dsDrawConvex(pos,R,planes, + planecount, + points, + pointcount, + polygons); + pos = dGeomGetPosition (geoms[1]); + R = dGeomGetRotation (geoms[1]); + dsSetColor (0.4f,1,1); + dsDrawConvex(pos,R,planes, + planecount, + points, + pointcount, + polygons); + /*if (show_contacts) */ + dMatrix3 RI; + dRSetIdentity (RI); + dsSetColor (1.0f,0,0); + for(int i=0;i +#include + +#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/textures"; + if(argc==2) + { + fn.path_to_textures = argv[1]; + } + + dInitODE(); + + 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; +} diff --git a/libraries/ode-0.9/ode/demo/demo_cyl.cpp b/libraries/ode-0.9/ode/demo/demo_cyl.cpp new file mode 100644 index 0000000000..3692234e7e --- /dev/null +++ b/libraries/ode-0.9/ode/demo/demo_cyl.cpp @@ -0,0 +1,318 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without 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 "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 +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include + +#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 dGeomID world_mesh; + +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 + + +#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.005; // 5ms 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; 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 + +#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 _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 + + +// 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 ) ) + +#ifdef dDOUBLE +#define dsDrawBox dsDrawBoxD +#define dsDrawSphere dsDrawSphereD +#define dsDrawCylinder dsDrawCylinderD +#define dsDrawCapsule dsDrawCapsuleD +#define dsDrawConvex dsDrawConvexD +#define dsDrawTriangle dsDrawTriangleD +#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, + 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 +#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; + + + + +//============================ + +// Bunny mesh ripped from Opcode +const int VertexCount = 453; +const int IndexCount = 902 * 3; + +typedef dReal dVector3R[3]; + +dGeomID TriMesh1; +dGeomID TriMesh2; +static dTriMeshDataID TriData1, TriData2; // reusable static trimesh data + +static float Vertices[VertexCount * 3] = { + REAL(-0.334392), REAL(0.133007), REAL(0.062259), + REAL(-0.350189), REAL(0.150354), REAL(-0.147769), + REAL(-0.234201), REAL(0.343811), REAL(-0.174307), + REAL(-0.200259), REAL(0.285207), REAL(0.093749), + REAL(0.003520), REAL(0.475208), REAL(-0.159365), + REAL(0.001856), REAL(0.419203), REAL(0.098582), + REAL(-0.252802), REAL(0.093666), REAL(0.237538), + REAL(-0.162901), REAL(0.237984), REAL(0.206905), + REAL(0.000865), REAL(0.318141), REAL(0.235370), + REAL(-0.414624), REAL(0.164083), REAL(-0.278254), + REAL(-0.262213), REAL(0.357334), REAL(-0.293246), + REAL(0.004628), REAL(0.482694), REAL(-0.338626), + REAL(-0.402162), REAL(0.133528), REAL(-0.443247), + REAL(-0.243781), REAL(0.324275), REAL(-0.436763), + REAL(0.005293), REAL(0.437592), REAL(-0.458332), + REAL(-0.339884), REAL(-0.041150), REAL(-0.668211), + REAL(-0.248382), REAL(0.255825), REAL(-0.627493), + REAL(0.006261), REAL(0.376103), REAL(-0.631506), + REAL(-0.216201), REAL(-0.126776), REAL(-0.886936), + REAL(-0.171075), REAL(0.011544), REAL(-0.881386), + REAL(-0.181074), REAL(0.098223), REAL(-0.814779), + REAL(-0.119891), REAL(0.218786), REAL(-0.760153), + REAL(-0.078895), REAL(0.276780), REAL(-0.739281), + REAL(0.006801), REAL(0.310959), REAL(-0.735661), + REAL(-0.168842), REAL(0.102387), REAL(-0.920381), + REAL(-0.104072), REAL(0.177278), REAL(-0.952530), + REAL(-0.129704), REAL(0.211848), REAL(-0.836678), + REAL(-0.099875), REAL(0.310931), REAL(-0.799381), + REAL(0.007237), REAL(0.361687), REAL(-0.794439), + REAL(-0.077913), REAL(0.258753), REAL(-0.921640), + REAL(0.007957), REAL(0.282241), REAL(-0.931680), + REAL(-0.252222), REAL(-0.550401), REAL(-0.557810), + REAL(-0.267633), REAL(-0.603419), REAL(-0.655209), + REAL(-0.446838), REAL(-0.118517), REAL(-0.466159), + REAL(-0.459488), REAL(-0.093017), REAL(-0.311341), + REAL(-0.370645), REAL(-0.100108), REAL(-0.159454), + REAL(-0.371984), REAL(-0.091991), REAL(-0.011044), + REAL(-0.328945), REAL(-0.098269), REAL(0.088659), + REAL(-0.282452), REAL(-0.018862), REAL(0.311501), + REAL(-0.352403), REAL(-0.131341), REAL(0.144902), + REAL(-0.364126), REAL(-0.200299), REAL(0.202388), + REAL(-0.283965), REAL(-0.231869), REAL(0.023668), + REAL(-0.298943), REAL(-0.155218), REAL(0.369716), + REAL(-0.293787), REAL(-0.121856), REAL(0.419097), + REAL(-0.290163), REAL(-0.290797), REAL(0.107824), + REAL(-0.264165), REAL(-0.272849), REAL(0.036347), + REAL(-0.228567), REAL(-0.372573), REAL(0.290309), + REAL(-0.190431), REAL(-0.286997), REAL(0.421917), + REAL(-0.191039), REAL(-0.240973), REAL(0.507118), + REAL(-0.287272), REAL(-0.276431), REAL(-0.065444), + REAL(-0.295675), REAL(-0.280818), REAL(-0.174200), + REAL(-0.399537), REAL(-0.313131), REAL(-0.376167), + REAL(-0.392666), REAL(-0.488581), REAL(-0.427494), + REAL(-0.331669), REAL(-0.570185), REAL(-0.466054), + REAL(-0.282290), REAL(-0.618140), REAL(-0.589220), + REAL(-0.374238), REAL(-0.594882), REAL(-0.323298), + REAL(-0.381071), REAL(-0.629723), REAL(-0.350777), + REAL(-0.382112), REAL(-0.624060), REAL(-0.221577), + REAL(-0.272701), REAL(-0.566522), REAL(0.259157), + REAL(-0.256702), REAL(-0.663406), REAL(0.286079), + REAL(-0.280948), REAL(-0.428359), REAL(0.055790), + REAL(-0.184974), REAL(-0.508894), REAL(0.326265), + REAL(-0.279971), REAL(-0.526918), REAL(0.395319), + REAL(-0.282599), REAL(-0.663393), REAL(0.412411), + REAL(-0.188329), REAL(-0.475093), REAL(0.417954), + REAL(-0.263384), REAL(-0.663396), REAL(0.466604), + REAL(-0.209063), REAL(-0.663393), REAL(0.509344), + REAL(-0.002044), REAL(-0.319624), REAL(0.553078), + REAL(-0.001266), REAL(-0.371260), REAL(0.413296), + REAL(-0.219753), REAL(-0.339762), REAL(-0.040921), + REAL(-0.256986), REAL(-0.282511), REAL(-0.006349), + REAL(-0.271706), REAL(-0.260881), REAL(0.001764), + REAL(-0.091191), REAL(-0.419184), REAL(-0.045912), + REAL(-0.114944), REAL(-0.429752), REAL(-0.124739), + REAL(-0.113970), REAL(-0.382987), REAL(-0.188540), + REAL(-0.243012), REAL(-0.464942), REAL(-0.242850), + REAL(-0.314815), REAL(-0.505402), REAL(-0.324768), + REAL(0.002774), REAL(-0.437526), REAL(-0.262766), + REAL(-0.072625), REAL(-0.417748), REAL(-0.221440), + REAL(-0.160112), REAL(-0.476932), REAL(-0.293450), + REAL(0.003859), REAL(-0.453425), REAL(-0.443916), + REAL(-0.120363), REAL(-0.581567), REAL(-0.438689), + REAL(-0.091499), REAL(-0.584191), REAL(-0.294511), + REAL(-0.116469), REAL(-0.599861), REAL(-0.188308), + REAL(-0.208032), REAL(-0.513640), REAL(-0.134649), + REAL(-0.235749), REAL(-0.610017), REAL(-0.040939), + REAL(-0.344916), REAL(-0.622487), REAL(-0.085380), + REAL(-0.336401), REAL(-0.531864), REAL(-0.212298), + REAL(0.001961), REAL(-0.459550), REAL(-0.135547), + REAL(-0.058296), REAL(-0.430536), REAL(-0.043440), + REAL(0.001378), REAL(-0.449511), REAL(-0.037762), + REAL(-0.130135), REAL(-0.510222), REAL(0.079144), + REAL(0.000142), REAL(-0.477549), REAL(0.157064), + REAL(-0.114284), REAL(-0.453206), REAL(0.304397), + REAL(-0.000592), REAL(-0.443558), REAL(0.285401), + REAL(-0.056215), REAL(-0.663402), REAL(0.326073), + REAL(-0.026248), REAL(-0.568010), REAL(0.273318), + REAL(-0.049261), REAL(-0.531064), REAL(0.389854), + REAL(-0.127096), REAL(-0.663398), REAL(0.479316), + REAL(-0.058384), REAL(-0.663401), REAL(0.372891), + REAL(-0.303961), REAL(0.054199), REAL(0.625921), + REAL(-0.268594), REAL(0.193403), REAL(0.502766), + REAL(-0.277159), REAL(0.126123), REAL(0.443289), + REAL(-0.287605), REAL(-0.005722), REAL(0.531844), + REAL(-0.231396), REAL(-0.121289), REAL(0.587387), + REAL(-0.253475), REAL(-0.081797), REAL(0.756541), + REAL(-0.195164), REAL(-0.137969), REAL(0.728011), + REAL(-0.167673), REAL(-0.156573), REAL(0.609388), + REAL(-0.145917), REAL(-0.169029), REAL(0.697600), + REAL(-0.077776), REAL(-0.214247), REAL(0.622586), + REAL(-0.076873), REAL(-0.214971), REAL(0.696301), + REAL(-0.002341), REAL(-0.233135), REAL(0.622859), + REAL(-0.002730), REAL(-0.213526), REAL(0.691267), + REAL(-0.003136), REAL(-0.192628), REAL(0.762731), + REAL(-0.056136), REAL(-0.201222), REAL(0.763806), + REAL(-0.114589), REAL(-0.166192), REAL(0.770723), + REAL(-0.155145), REAL(-0.129632), REAL(0.791738), + REAL(-0.183611), REAL(-0.058705), REAL(0.847012), + REAL(-0.165562), REAL(0.001980), REAL(0.833386), + REAL(-0.220084), REAL(0.019914), REAL(0.768935), + REAL(-0.255730), REAL(0.090306), REAL(0.670782), + REAL(-0.255594), REAL(0.113833), REAL(0.663389), + REAL(-0.226380), REAL(0.212655), REAL(0.617740), + REAL(-0.003367), REAL(-0.195342), REAL(0.799680), + REAL(-0.029743), REAL(-0.210508), REAL(0.827180), + REAL(-0.003818), REAL(-0.194783), REAL(0.873636), + REAL(-0.004116), REAL(-0.157907), REAL(0.931268), + REAL(-0.031280), REAL(-0.184555), REAL(0.889476), + REAL(-0.059885), REAL(-0.184448), REAL(0.841330), + REAL(-0.135333), REAL(-0.164332), REAL(0.878200), + REAL(-0.085574), REAL(-0.170948), REAL(0.925547), + REAL(-0.163833), REAL(-0.094170), REAL(0.897114), + REAL(-0.138444), REAL(-0.104250), REAL(0.945975), + REAL(-0.083497), REAL(-0.084934), REAL(0.979607), + REAL(-0.004433), REAL(-0.146642), REAL(0.985872), + REAL(-0.150715), REAL(0.032650), REAL(0.884111), + REAL(-0.135892), REAL(-0.035520), REAL(0.945455), + REAL(-0.070612), REAL(0.036849), REAL(0.975733), + REAL(-0.004458), REAL(-0.042526), REAL(1.015670), + REAL(-0.004249), REAL(0.046042), REAL(1.003240), + REAL(-0.086969), REAL(0.133224), REAL(0.947633), + REAL(-0.003873), REAL(0.161605), REAL(0.970499), + REAL(-0.125544), REAL(0.140012), REAL(0.917678), + REAL(-0.125651), REAL(0.250246), REAL(0.857602), + REAL(-0.003127), REAL(0.284070), REAL(0.878870), + REAL(-0.159174), REAL(0.125726), REAL(0.888878), + REAL(-0.183807), REAL(0.196970), REAL(0.844480), + REAL(-0.159890), REAL(0.291736), REAL(0.732480), + REAL(-0.199495), REAL(0.207230), REAL(0.779864), + REAL(-0.206182), REAL(0.164608), REAL(0.693257), + REAL(-0.186315), REAL(0.160689), REAL(0.817193), + REAL(-0.192827), REAL(0.166706), REAL(0.782271), + REAL(-0.175112), REAL(0.110008), REAL(0.860621), + REAL(-0.161022), REAL(0.057420), REAL(0.855111), + REAL(-0.172319), REAL(0.036155), REAL(0.816189), + REAL(-0.190318), REAL(0.064083), REAL(0.760605), + REAL(-0.195072), REAL(0.129179), REAL(0.731104), + REAL(-0.203126), REAL(0.410287), REAL(0.680536), + REAL(-0.216677), REAL(0.309274), REAL(0.642272), + REAL(-0.241515), REAL(0.311485), REAL(0.587832), + REAL(-0.002209), REAL(0.366663), REAL(0.749413), + REAL(-0.088230), REAL(0.396265), REAL(0.678635), + REAL(-0.170147), REAL(0.109517), REAL(0.840784), + REAL(-0.160521), REAL(0.067766), REAL(0.830650), + REAL(-0.181546), REAL(0.139805), REAL(0.812146), + REAL(-0.180495), REAL(0.148568), REAL(0.776087), + REAL(-0.180255), REAL(0.129125), REAL(0.744192), + REAL(-0.186298), REAL(0.078308), REAL(0.769352), + REAL(-0.167622), REAL(0.060539), REAL(0.806675), + REAL(-0.189876), REAL(0.102760), REAL(0.802582), + REAL(-0.108340), REAL(0.455446), REAL(0.657174), + REAL(-0.241585), REAL(0.527592), REAL(0.669296), + REAL(-0.265676), REAL(0.513366), REAL(0.634594), + REAL(-0.203073), REAL(0.478550), REAL(0.581526), + REAL(-0.266772), REAL(0.642330), REAL(0.602061), + REAL(-0.216961), REAL(0.564846), REAL(0.535435), + REAL(-0.202210), REAL(0.525495), REAL(0.475944), + REAL(-0.193888), REAL(0.467925), REAL(0.520606), + REAL(-0.265837), REAL(0.757267), REAL(0.500933), + REAL(-0.240306), REAL(0.653440), REAL(0.463215), + REAL(-0.309239), REAL(0.776868), REAL(0.304726), + REAL(-0.271009), REAL(0.683094), REAL(0.382018), + REAL(-0.312111), REAL(0.671099), REAL(0.286687), + REAL(-0.268791), REAL(0.624342), REAL(0.377231), + REAL(-0.302457), REAL(0.533996), REAL(0.360289), + REAL(-0.263656), REAL(0.529310), REAL(0.412564), + REAL(-0.282311), REAL(0.415167), REAL(0.447666), + REAL(-0.239201), REAL(0.442096), REAL(0.495604), + REAL(-0.220043), REAL(0.569026), REAL(0.445877), + REAL(-0.001263), REAL(0.395631), REAL(0.602029), + REAL(-0.057345), REAL(0.442535), REAL(0.572224), + REAL(-0.088927), REAL(0.506333), REAL(0.529106), + REAL(-0.125738), REAL(0.535076), REAL(0.612913), + REAL(-0.126251), REAL(0.577170), REAL(0.483159), + REAL(-0.149594), REAL(0.611520), REAL(0.557731), + REAL(-0.163188), REAL(0.660791), REAL(0.491080), + REAL(-0.172482), REAL(0.663387), REAL(0.415416), + REAL(-0.160464), REAL(0.591710), REAL(0.370659), + REAL(-0.156445), REAL(0.536396), REAL(0.378302), + REAL(-0.136496), REAL(0.444358), REAL(0.425226), + REAL(-0.095564), REAL(0.373768), REAL(0.473659), + REAL(-0.104146), REAL(0.315912), REAL(0.498104), + REAL(-0.000496), REAL(0.384194), REAL(0.473817), + REAL(-0.000183), REAL(0.297770), REAL(0.401486), + REAL(-0.129042), REAL(0.270145), REAL(0.434495), + REAL(0.000100), REAL(0.272963), REAL(0.349138), + REAL(-0.113060), REAL(0.236984), REAL(0.385554), + REAL(0.007260), REAL(0.016311), REAL(-0.883396), + REAL(0.007865), REAL(0.122104), REAL(-0.956137), + REAL(-0.032842), REAL(0.115282), REAL(-0.953252), + REAL(-0.089115), REAL(0.108449), REAL(-0.950317), + REAL(-0.047440), REAL(0.014729), REAL(-0.882756), + REAL(-0.104458), REAL(0.013137), REAL(-0.882070), + REAL(-0.086439), REAL(-0.584866), REAL(-0.608343), + REAL(-0.115026), REAL(-0.662605), REAL(-0.436732), + REAL(-0.071683), REAL(-0.665372), REAL(-0.606385), + REAL(-0.257884), REAL(-0.665381), REAL(-0.658052), + REAL(-0.272542), REAL(-0.665381), REAL(-0.592063), + REAL(-0.371322), REAL(-0.665382), REAL(-0.353620), + REAL(-0.372362), REAL(-0.665381), REAL(-0.224420), + REAL(-0.335166), REAL(-0.665380), REAL(-0.078623), + REAL(-0.225999), REAL(-0.665375), REAL(-0.038981), + REAL(-0.106719), REAL(-0.665374), REAL(-0.186351), + REAL(-0.081749), REAL(-0.665372), REAL(-0.292554), + REAL(0.006943), REAL(-0.091505), REAL(-0.858354), + REAL(0.006117), REAL(-0.280985), REAL(-0.769967), + REAL(0.004495), REAL(-0.502360), REAL(-0.559799), + REAL(-0.198638), REAL(-0.302135), REAL(-0.845816), + REAL(-0.237395), REAL(-0.542544), REAL(-0.587188), + REAL(-0.270001), REAL(-0.279489), REAL(-0.669861), + REAL(-0.134547), REAL(-0.119852), REAL(-0.959004), + REAL(-0.052088), REAL(-0.122463), REAL(-0.944549), + REAL(-0.124463), REAL(-0.293508), REAL(-0.899566), + REAL(-0.047616), REAL(-0.289643), REAL(-0.879292), + REAL(-0.168595), REAL(-0.529132), REAL(-0.654931), + REAL(-0.099793), REAL(-0.515719), REAL(-0.645873), + REAL(-0.186168), REAL(-0.605282), REAL(-0.724690), + REAL(-0.112970), REAL(-0.583097), REAL(-0.707469), + REAL(-0.108152), REAL(-0.665375), REAL(-0.700408), + REAL(-0.183019), REAL(-0.665378), REAL(-0.717630), + REAL(-0.349529), REAL(-0.334459), REAL(-0.511985), + REAL(-0.141182), REAL(-0.437705), REAL(-0.798194), + REAL(-0.212670), REAL(-0.448725), REAL(-0.737447), + REAL(-0.261111), REAL(-0.414945), REAL(-0.613835), + REAL(-0.077364), REAL(-0.431480), REAL(-0.778113), + REAL(0.005174), REAL(-0.425277), REAL(-0.651592), + REAL(0.089236), REAL(-0.431732), REAL(-0.777093), + REAL(0.271006), REAL(-0.415749), REAL(-0.610577), + REAL(0.223981), REAL(-0.449384), REAL(-0.734774), + REAL(0.153275), REAL(-0.438150), REAL(-0.796391), + REAL(0.358414), REAL(-0.335529), REAL(-0.507649), + REAL(0.193434), REAL(-0.665946), REAL(-0.715325), + REAL(0.118363), REAL(-0.665717), REAL(-0.699021), + REAL(0.123515), REAL(-0.583454), REAL(-0.706020), + REAL(0.196851), REAL(-0.605860), REAL(-0.722345), + REAL(0.109788), REAL(-0.516035), REAL(-0.644590), + REAL(0.178656), REAL(-0.529656), REAL(-0.652804), + REAL(0.061157), REAL(-0.289807), REAL(-0.878626), + REAL(0.138234), REAL(-0.293905), REAL(-0.897958), + REAL(0.066933), REAL(-0.122643), REAL(-0.943820), + REAL(0.149571), REAL(-0.120281), REAL(-0.957264), + REAL(0.280989), REAL(-0.280321), REAL(-0.666487), + REAL(0.246581), REAL(-0.543275), REAL(-0.584224), + REAL(0.211720), REAL(-0.302754), REAL(-0.843303), + REAL(0.086966), REAL(-0.665627), REAL(-0.291520), + REAL(0.110634), REAL(-0.665702), REAL(-0.185021), + REAL(0.228099), REAL(-0.666061), REAL(-0.036201), + REAL(0.337743), REAL(-0.666396), REAL(-0.074503), + REAL(0.376722), REAL(-0.666513), REAL(-0.219833), + REAL(0.377265), REAL(-0.666513), REAL(-0.349036), + REAL(0.281411), REAL(-0.666217), REAL(-0.588670), + REAL(0.267564), REAL(-0.666174), REAL(-0.654834), + REAL(0.080745), REAL(-0.665602), REAL(-0.605452), + REAL(0.122016), REAL(-0.662963), REAL(-0.435280), + REAL(0.095767), REAL(-0.585141), REAL(-0.607228), + REAL(0.118944), REAL(0.012799), REAL(-0.880702), + REAL(0.061944), REAL(0.014564), REAL(-0.882086), + REAL(0.104725), REAL(0.108156), REAL(-0.949130), + REAL(0.048513), REAL(0.115159), REAL(-0.952753), + REAL(0.112696), REAL(0.236643), REAL(0.386937), + REAL(0.128177), REAL(0.269757), REAL(0.436071), + REAL(0.102643), REAL(0.315600), REAL(0.499370), + REAL(0.094535), REAL(0.373481), REAL(0.474824), + REAL(0.136270), REAL(0.443946), REAL(0.426895), + REAL(0.157071), REAL(0.535923), REAL(0.380222), + REAL(0.161350), REAL(0.591224), REAL(0.372630), + REAL(0.173035), REAL(0.662865), REAL(0.417531), + REAL(0.162808), REAL(0.660299), REAL(0.493077), + REAL(0.148250), REAL(0.611070), REAL(0.559555), + REAL(0.125719), REAL(0.576790), REAL(0.484702), + REAL(0.123489), REAL(0.534699), REAL(0.614440), + REAL(0.087621), REAL(0.506066), REAL(0.530188), + REAL(0.055321), REAL(0.442365), REAL(0.572915), + REAL(0.219936), REAL(0.568361), REAL(0.448571), + REAL(0.238099), REAL(0.441375), REAL(0.498528), + REAL(0.281711), REAL(0.414315), REAL(0.451121), + REAL(0.263833), REAL(0.528513), REAL(0.415794), + REAL(0.303284), REAL(0.533081), REAL(0.363998), + REAL(0.269687), REAL(0.623528), REAL(0.380528), + REAL(0.314255), REAL(0.670153), REAL(0.290524), + REAL(0.272023), REAL(0.682273), REAL(0.385343), + REAL(0.311480), REAL(0.775931), REAL(0.308527), + REAL(0.240239), REAL(0.652714), REAL(0.466159), + REAL(0.265619), REAL(0.756464), REAL(0.504187), + REAL(0.192562), REAL(0.467341), REAL(0.522972), + REAL(0.201605), REAL(0.524885), REAL(0.478417), + REAL(0.215743), REAL(0.564193), REAL(0.538084), + REAL(0.264969), REAL(0.641527), REAL(0.605317), + REAL(0.201031), REAL(0.477940), REAL(0.584002), + REAL(0.263086), REAL(0.512567), REAL(0.637832), + REAL(0.238615), REAL(0.526867), REAL(0.672237), + REAL(0.105309), REAL(0.455123), REAL(0.658482), + REAL(0.183993), REAL(0.102195), REAL(0.804872), + REAL(0.161563), REAL(0.060042), REAL(0.808692), + REAL(0.180748), REAL(0.077754), REAL(0.771600), + REAL(0.175168), REAL(0.128588), REAL(0.746368), + REAL(0.175075), REAL(0.148030), REAL(0.778264), + REAL(0.175658), REAL(0.139265), REAL(0.814333), + REAL(0.154191), REAL(0.067291), REAL(0.832578), + REAL(0.163818), REAL(0.109013), REAL(0.842830), + REAL(0.084760), REAL(0.396004), REAL(0.679695), + REAL(0.238888), REAL(0.310760), REAL(0.590775), + REAL(0.213380), REAL(0.308625), REAL(0.644905), + REAL(0.199666), REAL(0.409678), REAL(0.683003), + REAL(0.190143), REAL(0.128597), REAL(0.733463), + REAL(0.184833), REAL(0.063516), REAL(0.762902), + REAL(0.166070), REAL(0.035644), REAL(0.818261), + REAL(0.154361), REAL(0.056943), REAL(0.857042), + REAL(0.168542), REAL(0.109489), REAL(0.862725), + REAL(0.187387), REAL(0.166131), REAL(0.784599), + REAL(0.180428), REAL(0.160135), REAL(0.819438), + REAL(0.201823), REAL(0.163991), REAL(0.695756), + REAL(0.194206), REAL(0.206635), REAL(0.782275), + REAL(0.155438), REAL(0.291260), REAL(0.734412), + REAL(0.177696), REAL(0.196424), REAL(0.846693), + REAL(0.152305), REAL(0.125256), REAL(0.890786), + REAL(0.119546), REAL(0.249876), REAL(0.859104), + REAL(0.118369), REAL(0.139643), REAL(0.919173), + REAL(0.079410), REAL(0.132973), REAL(0.948652), + REAL(0.062419), REAL(0.036648), REAL(0.976547), + REAL(0.127847), REAL(-0.035919), REAL(0.947070), + REAL(0.143624), REAL(0.032206), REAL(0.885913), + REAL(0.074888), REAL(-0.085173), REAL(0.980577), + REAL(0.130184), REAL(-0.104656), REAL(0.947620), + REAL(0.156201), REAL(-0.094653), REAL(0.899074), + REAL(0.077366), REAL(-0.171194), REAL(0.926545), + REAL(0.127722), REAL(-0.164729), REAL(0.879810), + REAL(0.052670), REAL(-0.184618), REAL(0.842019), + REAL(0.023477), REAL(-0.184638), REAL(0.889811), + REAL(0.022626), REAL(-0.210587), REAL(0.827500), + REAL(0.223089), REAL(0.211976), REAL(0.620493), + REAL(0.251444), REAL(0.113067), REAL(0.666494), + REAL(0.251419), REAL(0.089540), REAL(0.673887), + REAL(0.214360), REAL(0.019258), REAL(0.771595), + REAL(0.158999), REAL(0.001490), REAL(0.835374), + REAL(0.176696), REAL(-0.059249), REAL(0.849218), + REAL(0.148696), REAL(-0.130091), REAL(0.793599), + REAL(0.108290), REAL(-0.166528), REAL(0.772088), + REAL(0.049820), REAL(-0.201382), REAL(0.764454), + REAL(0.071341), REAL(-0.215195), REAL(0.697209), + REAL(0.073148), REAL(-0.214475), REAL(0.623510), + REAL(0.140502), REAL(-0.169461), REAL(0.699354), + REAL(0.163374), REAL(-0.157073), REAL(0.611416), + REAL(0.189466), REAL(-0.138550), REAL(0.730366), + REAL(0.247593), REAL(-0.082554), REAL(0.759610), + REAL(0.227468), REAL(-0.121982), REAL(0.590197), + REAL(0.284702), REAL(-0.006586), REAL(0.535347), + REAL(0.275741), REAL(0.125287), REAL(0.446676), + REAL(0.266650), REAL(0.192594), REAL(0.506044), + REAL(0.300086), REAL(0.053287), REAL(0.629620), + REAL(0.055450), REAL(-0.663935), REAL(0.375065), + REAL(0.122854), REAL(-0.664138), REAL(0.482323), + REAL(0.046520), REAL(-0.531571), REAL(0.391918), + REAL(0.024824), REAL(-0.568450), REAL(0.275106), + REAL(0.053855), REAL(-0.663931), REAL(0.328224), + REAL(0.112829), REAL(-0.453549), REAL(0.305788), + REAL(0.131265), REAL(-0.510617), REAL(0.080746), + REAL(0.061174), REAL(-0.430716), REAL(-0.042710), + REAL(0.341019), REAL(-0.532887), REAL(-0.208150), + REAL(0.347705), REAL(-0.623533), REAL(-0.081139), + REAL(0.238040), REAL(-0.610732), REAL(-0.038037), + REAL(0.211764), REAL(-0.514274), REAL(-0.132078), + REAL(0.120605), REAL(-0.600219), REAL(-0.186856), + REAL(0.096985), REAL(-0.584476), REAL(-0.293357), + REAL(0.127621), REAL(-0.581941), REAL(-0.437170), + REAL(0.165902), REAL(-0.477425), REAL(-0.291453), + REAL(0.077720), REAL(-0.417975), REAL(-0.220519), + REAL(0.320892), REAL(-0.506363), REAL(-0.320874), + REAL(0.248214), REAL(-0.465684), REAL(-0.239842), + REAL(0.118764), REAL(-0.383338), REAL(-0.187114), + REAL(0.118816), REAL(-0.430106), REAL(-0.123307), + REAL(0.094131), REAL(-0.419464), REAL(-0.044777), + REAL(0.274526), REAL(-0.261706), REAL(0.005110), + REAL(0.259842), REAL(-0.283292), REAL(-0.003185), + REAL(0.222861), REAL(-0.340431), REAL(-0.038210), + REAL(0.204445), REAL(-0.664380), REAL(0.513353), + REAL(0.259286), REAL(-0.664547), REAL(0.471281), + REAL(0.185402), REAL(-0.476020), REAL(0.421718), + REAL(0.279163), REAL(-0.664604), REAL(0.417328), + REAL(0.277157), REAL(-0.528122), REAL(0.400208), + REAL(0.183069), REAL(-0.509812), REAL(0.329995), + REAL(0.282599), REAL(-0.429210), REAL(0.059242), + REAL(0.254816), REAL(-0.664541), REAL(0.290687), + REAL(0.271436), REAL(-0.567707), REAL(0.263966), + REAL(0.386561), REAL(-0.625221), REAL(-0.216870), + REAL(0.387086), REAL(-0.630883), REAL(-0.346073), + REAL(0.380021), REAL(-0.596021), REAL(-0.318679), + REAL(0.291269), REAL(-0.619007), REAL(-0.585707), + REAL(0.339280), REAL(-0.571198), REAL(-0.461946), + REAL(0.400045), REAL(-0.489778), REAL(-0.422640), + REAL(0.406817), REAL(-0.314349), REAL(-0.371230), + REAL(0.300588), REAL(-0.281718), REAL(-0.170549), + REAL(0.290866), REAL(-0.277304), REAL(-0.061905), + REAL(0.187735), REAL(-0.241545), REAL(0.509437), + REAL(0.188032), REAL(-0.287569), REAL(0.424234), + REAL(0.227520), REAL(-0.373262), REAL(0.293102), + REAL(0.266526), REAL(-0.273650), REAL(0.039597), + REAL(0.291592), REAL(-0.291676), REAL(0.111386), + REAL(0.291914), REAL(-0.122741), REAL(0.422683), + REAL(0.297574), REAL(-0.156119), REAL(0.373368), + REAL(0.286603), REAL(-0.232731), REAL(0.027162), + REAL(0.364663), REAL(-0.201399), REAL(0.206850), + REAL(0.353855), REAL(-0.132408), REAL(0.149228), + REAL(0.282208), REAL(-0.019715), REAL(0.314960), + REAL(0.331187), REAL(-0.099266), REAL(0.092701), + REAL(0.375463), REAL(-0.093120), REAL(-0.006467), + REAL(0.375917), REAL(-0.101236), REAL(-0.154882), + REAL(0.466635), REAL(-0.094416), REAL(-0.305669), + REAL(0.455805), REAL(-0.119881), REAL(-0.460632), + REAL(0.277465), REAL(-0.604242), REAL(-0.651871), + REAL(0.261022), REAL(-0.551176), REAL(-0.554667), + REAL(0.093627), REAL(0.258494), REAL(-0.920589), + REAL(0.114248), REAL(0.310608), REAL(-0.798070), + REAL(0.144232), REAL(0.211434), REAL(-0.835001), + REAL(0.119916), REAL(0.176940), REAL(-0.951159), + REAL(0.184061), REAL(0.101854), REAL(-0.918220), + REAL(0.092431), REAL(0.276521), REAL(-0.738231), + REAL(0.133504), REAL(0.218403), REAL(-0.758602), + REAL(0.194987), REAL(0.097655), REAL(-0.812476), + REAL(0.185542), REAL(0.011005), REAL(-0.879202), + REAL(0.230315), REAL(-0.127450), REAL(-0.884202), + REAL(0.260471), REAL(0.255056), REAL(-0.624378), + REAL(0.351567), REAL(-0.042194), REAL(-0.663976), + REAL(0.253742), REAL(0.323524), REAL(-0.433716), + REAL(0.411612), REAL(0.132299), REAL(-0.438264), + REAL(0.270513), REAL(0.356530), REAL(-0.289984), + REAL(0.422146), REAL(0.162819), REAL(-0.273130), + REAL(0.164724), REAL(0.237490), REAL(0.208912), + REAL(0.253806), REAL(0.092900), REAL(0.240640), + REAL(0.203608), REAL(0.284597), REAL(0.096223), + REAL(0.241006), REAL(0.343093), REAL(-0.171396), + REAL(0.356076), REAL(0.149288), REAL(-0.143443), + REAL(0.337656), REAL(0.131992), REAL(0.066374) +}; + +int 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} +}; + +//============================ + + +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 == 'x' || cmd == 'y' || cmd == 'm' || 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]); + } +#ifdef dTRIMESH_ENABLED + else if (cmd == 'm') + { + dTriMeshDataID new_tmdata = dGeomTriMeshDataCreate(); + dGeomTriMeshDataBuildSingle(new_tmdata, &Vertices[0], 3 * sizeof(float), VertexCount, (int*)&Indices[0], IndexCount, 3 * sizeof(int)); + + 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] ); + } +#endif + 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 +#include + +#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() +{ + 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/textures"; + if(argc==2) + { + fn.path_to_textures = argv[1]; + } + + // create world + dInitODE(); + world = dWorldCreate(); + + dMass m; + dMassSetBox (&m,1,SIDE,SIDE,SIDE); + dMassAdjust (&m,MASS); + + dQuaternion q; + dQFromAxisAndAngle (q,1,1,0,0.25*M_PI); + + body[0] = dBodyCreate (world); + dBodySetMass (body[0],&m); + dBodySetPosition (body[0],0.5*SIDE,0.5*SIDE,1); + dBodySetQuaternion (body[0],q); + + body[1] = dBodyCreate (world); + dBodySetMass (body[1],&m); + dBodySetPosition (body[1],-0.5*SIDE,-0.5*SIDE,1); + dBodySetQuaternion (body[1],q); + + hinge = dJointCreateHinge (world,0); + dJointAttach (hinge,body[0],body[1]); + dJointSetHingeAnchor (hinge,0,0,1); + dJointSetHingeAxis (hinge,1,-1,1.41421356); + + // run simulation + dsSimulationLoop (argc,argv,352,288,&fn); + + dWorldDestroy (world); + dCloseODE(); + return 0; +} diff --git a/libraries/ode-0.9/ode/demo/demo_jointPR.cpp b/libraries/ode-0.9/ode/demo/demo_jointPR.cpp new file mode 100644 index 0000000000..e0d002d8cd --- /dev/null +++ b/libraries/ode-0.9/ode/demo/demo_jointPR.cpp @@ -0,0 +1,377 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without 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 + + +#define DRAWSTUFF_TEXTURE_PATH "../../drawstuff/textures" + + +#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 dSpaceID box2_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 + } + } + } + + // 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); + return 0; +} + diff --git a/libraries/ode-0.9/ode/demo/demo_joints.cpp b/libraries/ode-0.9/ode/demo/demo_joints.cpp new file mode 100644 index 0000000000..2a83c2f263 --- /dev/null +++ b/libraries/ode-0.9/ode/demo/demo_joints.cpp @@ -0,0 +1,1092 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without 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 + +#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 char loCase (char a) +{ + if (a >= 'A' && a <= 'Z') return a + ('a'-'A'); + else return a; +} + + +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; + return a; + } + 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() +{ + 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/textures"; + + // 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; + dInitODE(); + + // process the command line args. anything that starts with `-' is assumed + // to be a drawstuff argument. + for (i=1; i +#include + +#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() +{ + 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/textures"; + if(argc>=2) + { + fn.path_to_textures = argv[1]; + } + + // create world + dInitODE(); + contactgroup = dJointGroupCreate(0); + world = dWorldCreate(); + space = dSimpleSpaceCreate(0); + dMass m; + dMassSetBox (&m,1,SIDE,SIDE,SIDE); + dMassAdjust (&m,MASS); + + body[0] = dBodyCreate (world); + dBodySetMass (body[0],&m); + dBodySetPosition (body[0],0,0,1); + geom[0] = dCreateBox(space,SIDE,SIDE,SIDE); + body[1] = dBodyCreate (world); + dBodySetMass (body[1],&m); + dBodySetPosition (body[1],0,0,2); + geom[1] = dCreateBox(space,SIDE,SIDE,SIDE); + + dGeomSetBody(geom[0],body[0]); + dGeomSetBody(geom[1],body[1]); + + lmotor[0] = dJointCreateLMotor (world,0); + dJointAttach (lmotor[0],body[0],body[1]); + lmotor[1] = dJointCreateLMotor (world,0); + dJointAttach (lmotor[1],body[0],0); + amotor[0] = dJointCreateAMotor(world,0); + dJointAttach(amotor[0], body[0],body[1]); + amotor[1] = dJointCreateAMotor(world,0); + dJointAttach(amotor[1], body[0], 0); + + for (int i=0; i<2; i++) { + dJointSetAMotorNumAxes(amotor[i], 3); + dJointSetAMotorAxis(amotor[i],0,1,1,0,0); + dJointSetAMotorAxis(amotor[i],1,1,0,1,0); + dJointSetAMotorAxis(amotor[i],2,1,0,0,1); + dJointSetAMotorParam(amotor[i],dParamFMax,0.00001); + dJointSetAMotorParam(amotor[i],dParamFMax2,0.00001); + dJointSetAMotorParam(amotor[i],dParamFMax3,0.00001); + + dJointSetAMotorParam(amotor[i],dParamVel,0); + dJointSetAMotorParam(amotor[i],dParamVel2,0); + dJointSetAMotorParam(amotor[i],dParamVel3,0); + + dJointSetLMotorNumAxes(lmotor[i],3); + dJointSetLMotorAxis(lmotor[i],0,1,1,0,0); + dJointSetLMotorAxis(lmotor[i],1,1,0,1,0); + dJointSetLMotorAxis(lmotor[i],2,1,0,0,1); + + dJointSetLMotorParam(lmotor[i],dParamFMax,0.0001); + dJointSetLMotorParam(lmotor[i],dParamFMax2,0.0001); + dJointSetLMotorParam(lmotor[i],dParamFMax3,0.0001); + } + + // run simulation + dsSimulationLoop (argc,argv,352,288,&fn); + + dJointGroupDestroy(contactgroup); + dSpaceDestroy (space); + dWorldDestroy (world); + dCloseODE(); + return 0; +} diff --git a/libraries/ode-0.9/ode/demo/demo_moving_trimesh.cpp b/libraries/ode-0.9/ode/demo/demo_moving_trimesh.cpp new file mode 100644 index 0000000000..3d0302071a --- /dev/null +++ b/libraries/ode-0.9/ode/demo/demo_moving_trimesh.cpp @@ -0,0 +1,1944 @@ +/************************************************************************* + * * + * 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 + +#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? + +// Bunny mesh ripped from Opcode +const int VertexCount = 453; +const int IndexCount = 902 * 3; + +typedef dReal dVector3R[3]; + +dGeomID TriMesh1; +dGeomID TriMesh2; +static dTriMeshDataID TriData1, TriData2; // reusable static trimesh data + +float Vertices[VertexCount * 3] = { + REAL(-0.334392), REAL(0.133007), REAL(0.062259), + REAL(-0.350189), REAL(0.150354), REAL(-0.147769), + REAL(-0.234201), REAL(0.343811), REAL(-0.174307), + REAL(-0.200259), REAL(0.285207), REAL(0.093749), + REAL(0.003520), REAL(0.475208), REAL(-0.159365), + REAL(0.001856), REAL(0.419203), REAL(0.098582), + REAL(-0.252802), REAL(0.093666), REAL(0.237538), + REAL(-0.162901), REAL(0.237984), REAL(0.206905), + REAL(0.000865), REAL(0.318141), REAL(0.235370), + REAL(-0.414624), REAL(0.164083), REAL(-0.278254), + REAL(-0.262213), REAL(0.357334), REAL(-0.293246), + REAL(0.004628), REAL(0.482694), REAL(-0.338626), + REAL(-0.402162), REAL(0.133528), REAL(-0.443247), + REAL(-0.243781), REAL(0.324275), REAL(-0.436763), + REAL(0.005293), REAL(0.437592), REAL(-0.458332), + REAL(-0.339884), REAL(-0.041150), REAL(-0.668211), + REAL(-0.248382), REAL(0.255825), REAL(-0.627493), + REAL(0.006261), REAL(0.376103), REAL(-0.631506), + REAL(-0.216201), REAL(-0.126776), REAL(-0.886936), + REAL(-0.171075), REAL(0.011544), REAL(-0.881386), + REAL(-0.181074), REAL(0.098223), REAL(-0.814779), + REAL(-0.119891), REAL(0.218786), REAL(-0.760153), + REAL(-0.078895), REAL(0.276780), REAL(-0.739281), + REAL(0.006801), REAL(0.310959), REAL(-0.735661), + REAL(-0.168842), REAL(0.102387), REAL(-0.920381), + REAL(-0.104072), REAL(0.177278), REAL(-0.952530), + REAL(-0.129704), REAL(0.211848), REAL(-0.836678), + REAL(-0.099875), REAL(0.310931), REAL(-0.799381), + REAL(0.007237), REAL(0.361687), REAL(-0.794439), + REAL(-0.077913), REAL(0.258753), REAL(-0.921640), + REAL(0.007957), REAL(0.282241), REAL(-0.931680), + REAL(-0.252222), REAL(-0.550401), REAL(-0.557810), + REAL(-0.267633), REAL(-0.603419), REAL(-0.655209), + REAL(-0.446838), REAL(-0.118517), REAL(-0.466159), + REAL(-0.459488), REAL(-0.093017), REAL(-0.311341), + REAL(-0.370645), REAL(-0.100108), REAL(-0.159454), + REAL(-0.371984), REAL(-0.091991), REAL(-0.011044), + REAL(-0.328945), REAL(-0.098269), REAL(0.088659), + REAL(-0.282452), REAL(-0.018862), REAL(0.311501), + REAL(-0.352403), REAL(-0.131341), REAL(0.144902), + REAL(-0.364126), REAL(-0.200299), REAL(0.202388), + REAL(-0.283965), REAL(-0.231869), REAL(0.023668), + REAL(-0.298943), REAL(-0.155218), REAL(0.369716), + REAL(-0.293787), REAL(-0.121856), REAL(0.419097), + REAL(-0.290163), REAL(-0.290797), REAL(0.107824), + REAL(-0.264165), REAL(-0.272849), REAL(0.036347), + REAL(-0.228567), REAL(-0.372573), REAL(0.290309), + REAL(-0.190431), REAL(-0.286997), REAL(0.421917), + REAL(-0.191039), REAL(-0.240973), REAL(0.507118), + REAL(-0.287272), REAL(-0.276431), REAL(-0.065444), + REAL(-0.295675), REAL(-0.280818), REAL(-0.174200), + REAL(-0.399537), REAL(-0.313131), REAL(-0.376167), + REAL(-0.392666), REAL(-0.488581), REAL(-0.427494), + REAL(-0.331669), REAL(-0.570185), REAL(-0.466054), + REAL(-0.282290), REAL(-0.618140), REAL(-0.589220), + REAL(-0.374238), REAL(-0.594882), REAL(-0.323298), + REAL(-0.381071), REAL(-0.629723), REAL(-0.350777), + REAL(-0.382112), REAL(-0.624060), REAL(-0.221577), + REAL(-0.272701), REAL(-0.566522), REAL(0.259157), + REAL(-0.256702), REAL(-0.663406), REAL(0.286079), + REAL(-0.280948), REAL(-0.428359), REAL(0.055790), + REAL(-0.184974), REAL(-0.508894), REAL(0.326265), + REAL(-0.279971), REAL(-0.526918), REAL(0.395319), + REAL(-0.282599), REAL(-0.663393), REAL(0.412411), + REAL(-0.188329), REAL(-0.475093), REAL(0.417954), + REAL(-0.263384), REAL(-0.663396), REAL(0.466604), + REAL(-0.209063), REAL(-0.663393), REAL(0.509344), + REAL(-0.002044), REAL(-0.319624), REAL(0.553078), + REAL(-0.001266), REAL(-0.371260), REAL(0.413296), + REAL(-0.219753), REAL(-0.339762), REAL(-0.040921), + REAL(-0.256986), REAL(-0.282511), REAL(-0.006349), + REAL(-0.271706), REAL(-0.260881), REAL(0.001764), + REAL(-0.091191), REAL(-0.419184), REAL(-0.045912), + REAL(-0.114944), REAL(-0.429752), REAL(-0.124739), + REAL(-0.113970), REAL(-0.382987), REAL(-0.188540), + REAL(-0.243012), REAL(-0.464942), REAL(-0.242850), + REAL(-0.314815), REAL(-0.505402), REAL(-0.324768), + REAL(0.002774), REAL(-0.437526), REAL(-0.262766), + REAL(-0.072625), REAL(-0.417748), REAL(-0.221440), + REAL(-0.160112), REAL(-0.476932), REAL(-0.293450), + REAL(0.003859), REAL(-0.453425), REAL(-0.443916), + REAL(-0.120363), REAL(-0.581567), REAL(-0.438689), + REAL(-0.091499), REAL(-0.584191), REAL(-0.294511), + REAL(-0.116469), REAL(-0.599861), REAL(-0.188308), + REAL(-0.208032), REAL(-0.513640), REAL(-0.134649), + REAL(-0.235749), REAL(-0.610017), REAL(-0.040939), + REAL(-0.344916), REAL(-0.622487), REAL(-0.085380), + REAL(-0.336401), REAL(-0.531864), REAL(-0.212298), + REAL(0.001961), REAL(-0.459550), REAL(-0.135547), + REAL(-0.058296), REAL(-0.430536), REAL(-0.043440), + REAL(0.001378), REAL(-0.449511), REAL(-0.037762), + REAL(-0.130135), REAL(-0.510222), REAL(0.079144), + REAL(0.000142), REAL(-0.477549), REAL(0.157064), + REAL(-0.114284), REAL(-0.453206), REAL(0.304397), + REAL(-0.000592), REAL(-0.443558), REAL(0.285401), + REAL(-0.056215), REAL(-0.663402), REAL(0.326073), + REAL(-0.026248), REAL(-0.568010), REAL(0.273318), + REAL(-0.049261), REAL(-0.531064), REAL(0.389854), + REAL(-0.127096), REAL(-0.663398), REAL(0.479316), + REAL(-0.058384), REAL(-0.663401), REAL(0.372891), + REAL(-0.303961), REAL(0.054199), REAL(0.625921), + REAL(-0.268594), REAL(0.193403), REAL(0.502766), + REAL(-0.277159), REAL(0.126123), REAL(0.443289), + REAL(-0.287605), REAL(-0.005722), REAL(0.531844), + REAL(-0.231396), REAL(-0.121289), REAL(0.587387), + REAL(-0.253475), REAL(-0.081797), REAL(0.756541), + REAL(-0.195164), REAL(-0.137969), REAL(0.728011), + REAL(-0.167673), REAL(-0.156573), REAL(0.609388), + REAL(-0.145917), REAL(-0.169029), REAL(0.697600), + REAL(-0.077776), REAL(-0.214247), REAL(0.622586), + REAL(-0.076873), REAL(-0.214971), REAL(0.696301), + REAL(-0.002341), REAL(-0.233135), REAL(0.622859), + REAL(-0.002730), REAL(-0.213526), REAL(0.691267), + REAL(-0.003136), REAL(-0.192628), REAL(0.762731), + REAL(-0.056136), REAL(-0.201222), REAL(0.763806), + REAL(-0.114589), REAL(-0.166192), REAL(0.770723), + REAL(-0.155145), REAL(-0.129632), REAL(0.791738), + REAL(-0.183611), REAL(-0.058705), REAL(0.847012), + REAL(-0.165562), REAL(0.001980), REAL(0.833386), + REAL(-0.220084), REAL(0.019914), REAL(0.768935), + REAL(-0.255730), REAL(0.090306), REAL(0.670782), + REAL(-0.255594), REAL(0.113833), REAL(0.663389), + REAL(-0.226380), REAL(0.212655), REAL(0.617740), + REAL(-0.003367), REAL(-0.195342), REAL(0.799680), + REAL(-0.029743), REAL(-0.210508), REAL(0.827180), + REAL(-0.003818), REAL(-0.194783), REAL(0.873636), + REAL(-0.004116), REAL(-0.157907), REAL(0.931268), + REAL(-0.031280), REAL(-0.184555), REAL(0.889476), + REAL(-0.059885), REAL(-0.184448), REAL(0.841330), + REAL(-0.135333), REAL(-0.164332), REAL(0.878200), + REAL(-0.085574), REAL(-0.170948), REAL(0.925547), + REAL(-0.163833), REAL(-0.094170), REAL(0.897114), + REAL(-0.138444), REAL(-0.104250), REAL(0.945975), + REAL(-0.083497), REAL(-0.084934), REAL(0.979607), + REAL(-0.004433), REAL(-0.146642), REAL(0.985872), + REAL(-0.150715), REAL(0.032650), REAL(0.884111), + REAL(-0.135892), REAL(-0.035520), REAL(0.945455), + REAL(-0.070612), REAL(0.036849), REAL(0.975733), + REAL(-0.004458), REAL(-0.042526), REAL(1.015670), + REAL(-0.004249), REAL(0.046042), REAL(1.003240), + REAL(-0.086969), REAL(0.133224), REAL(0.947633), + REAL(-0.003873), REAL(0.161605), REAL(0.970499), + REAL(-0.125544), REAL(0.140012), REAL(0.917678), + REAL(-0.125651), REAL(0.250246), REAL(0.857602), + REAL(-0.003127), REAL(0.284070), REAL(0.878870), + REAL(-0.159174), REAL(0.125726), REAL(0.888878), + REAL(-0.183807), REAL(0.196970), REAL(0.844480), + REAL(-0.159890), REAL(0.291736), REAL(0.732480), + REAL(-0.199495), REAL(0.207230), REAL(0.779864), + REAL(-0.206182), REAL(0.164608), REAL(0.693257), + REAL(-0.186315), REAL(0.160689), REAL(0.817193), + REAL(-0.192827), REAL(0.166706), REAL(0.782271), + REAL(-0.175112), REAL(0.110008), REAL(0.860621), + REAL(-0.161022), REAL(0.057420), REAL(0.855111), + REAL(-0.172319), REAL(0.036155), REAL(0.816189), + REAL(-0.190318), REAL(0.064083), REAL(0.760605), + REAL(-0.195072), REAL(0.129179), REAL(0.731104), + REAL(-0.203126), REAL(0.410287), REAL(0.680536), + REAL(-0.216677), REAL(0.309274), REAL(0.642272), + REAL(-0.241515), REAL(0.311485), REAL(0.587832), + REAL(-0.002209), REAL(0.366663), REAL(0.749413), + REAL(-0.088230), REAL(0.396265), REAL(0.678635), + REAL(-0.170147), REAL(0.109517), REAL(0.840784), + REAL(-0.160521), REAL(0.067766), REAL(0.830650), + REAL(-0.181546), REAL(0.139805), REAL(0.812146), + REAL(-0.180495), REAL(0.148568), REAL(0.776087), + REAL(-0.180255), REAL(0.129125), REAL(0.744192), + REAL(-0.186298), REAL(0.078308), REAL(0.769352), + REAL(-0.167622), REAL(0.060539), REAL(0.806675), + REAL(-0.189876), REAL(0.102760), REAL(0.802582), + REAL(-0.108340), REAL(0.455446), REAL(0.657174), + REAL(-0.241585), REAL(0.527592), REAL(0.669296), + REAL(-0.265676), REAL(0.513366), REAL(0.634594), + REAL(-0.203073), REAL(0.478550), REAL(0.581526), + REAL(-0.266772), REAL(0.642330), REAL(0.602061), + REAL(-0.216961), REAL(0.564846), REAL(0.535435), + REAL(-0.202210), REAL(0.525495), REAL(0.475944), + REAL(-0.193888), REAL(0.467925), REAL(0.520606), + REAL(-0.265837), REAL(0.757267), REAL(0.500933), + REAL(-0.240306), REAL(0.653440), REAL(0.463215), + REAL(-0.309239), REAL(0.776868), REAL(0.304726), + REAL(-0.271009), REAL(0.683094), REAL(0.382018), + REAL(-0.312111), REAL(0.671099), REAL(0.286687), + REAL(-0.268791), REAL(0.624342), REAL(0.377231), + REAL(-0.302457), REAL(0.533996), REAL(0.360289), + REAL(-0.263656), REAL(0.529310), REAL(0.412564), + REAL(-0.282311), REAL(0.415167), REAL(0.447666), + REAL(-0.239201), REAL(0.442096), REAL(0.495604), + REAL(-0.220043), REAL(0.569026), REAL(0.445877), + REAL(-0.001263), REAL(0.395631), REAL(0.602029), + REAL(-0.057345), REAL(0.442535), REAL(0.572224), + REAL(-0.088927), REAL(0.506333), REAL(0.529106), + REAL(-0.125738), REAL(0.535076), REAL(0.612913), + REAL(-0.126251), REAL(0.577170), REAL(0.483159), + REAL(-0.149594), REAL(0.611520), REAL(0.557731), + REAL(-0.163188), REAL(0.660791), REAL(0.491080), + REAL(-0.172482), REAL(0.663387), REAL(0.415416), + REAL(-0.160464), REAL(0.591710), REAL(0.370659), + REAL(-0.156445), REAL(0.536396), REAL(0.378302), + REAL(-0.136496), REAL(0.444358), REAL(0.425226), + REAL(-0.095564), REAL(0.373768), REAL(0.473659), + REAL(-0.104146), REAL(0.315912), REAL(0.498104), + REAL(-0.000496), REAL(0.384194), REAL(0.473817), + REAL(-0.000183), REAL(0.297770), REAL(0.401486), + REAL(-0.129042), REAL(0.270145), REAL(0.434495), + REAL(0.000100), REAL(0.272963), REAL(0.349138), + REAL(-0.113060), REAL(0.236984), REAL(0.385554), + REAL(0.007260), REAL(0.016311), REAL(-0.883396), + REAL(0.007865), REAL(0.122104), REAL(-0.956137), + REAL(-0.032842), REAL(0.115282), REAL(-0.953252), + REAL(-0.089115), REAL(0.108449), REAL(-0.950317), + REAL(-0.047440), REAL(0.014729), REAL(-0.882756), + REAL(-0.104458), REAL(0.013137), REAL(-0.882070), + REAL(-0.086439), REAL(-0.584866), REAL(-0.608343), + REAL(-0.115026), REAL(-0.662605), REAL(-0.436732), + REAL(-0.071683), REAL(-0.665372), REAL(-0.606385), + REAL(-0.257884), REAL(-0.665381), REAL(-0.658052), + REAL(-0.272542), REAL(-0.665381), REAL(-0.592063), + REAL(-0.371322), REAL(-0.665382), REAL(-0.353620), + REAL(-0.372362), REAL(-0.665381), REAL(-0.224420), + REAL(-0.335166), REAL(-0.665380), REAL(-0.078623), + REAL(-0.225999), REAL(-0.665375), REAL(-0.038981), + REAL(-0.106719), REAL(-0.665374), REAL(-0.186351), + REAL(-0.081749), REAL(-0.665372), REAL(-0.292554), + REAL(0.006943), REAL(-0.091505), REAL(-0.858354), + REAL(0.006117), REAL(-0.280985), REAL(-0.769967), + REAL(0.004495), REAL(-0.502360), REAL(-0.559799), + REAL(-0.198638), REAL(-0.302135), REAL(-0.845816), + REAL(-0.237395), REAL(-0.542544), REAL(-0.587188), + REAL(-0.270001), REAL(-0.279489), REAL(-0.669861), + REAL(-0.134547), REAL(-0.119852), REAL(-0.959004), + REAL(-0.052088), REAL(-0.122463), REAL(-0.944549), + REAL(-0.124463), REAL(-0.293508), REAL(-0.899566), + REAL(-0.047616), REAL(-0.289643), REAL(-0.879292), + REAL(-0.168595), REAL(-0.529132), REAL(-0.654931), + REAL(-0.099793), REAL(-0.515719), REAL(-0.645873), + REAL(-0.186168), REAL(-0.605282), REAL(-0.724690), + REAL(-0.112970), REAL(-0.583097), REAL(-0.707469), + REAL(-0.108152), REAL(-0.665375), REAL(-0.700408), + REAL(-0.183019), REAL(-0.665378), REAL(-0.717630), + REAL(-0.349529), REAL(-0.334459), REAL(-0.511985), + REAL(-0.141182), REAL(-0.437705), REAL(-0.798194), + REAL(-0.212670), REAL(-0.448725), REAL(-0.737447), + REAL(-0.261111), REAL(-0.414945), REAL(-0.613835), + REAL(-0.077364), REAL(-0.431480), REAL(-0.778113), + REAL(0.005174), REAL(-0.425277), REAL(-0.651592), + REAL(0.089236), REAL(-0.431732), REAL(-0.777093), + REAL(0.271006), REAL(-0.415749), REAL(-0.610577), + REAL(0.223981), REAL(-0.449384), REAL(-0.734774), + REAL(0.153275), REAL(-0.438150), REAL(-0.796391), + REAL(0.358414), REAL(-0.335529), REAL(-0.507649), + REAL(0.193434), REAL(-0.665946), REAL(-0.715325), + REAL(0.118363), REAL(-0.665717), REAL(-0.699021), + REAL(0.123515), REAL(-0.583454), REAL(-0.706020), + REAL(0.196851), REAL(-0.605860), REAL(-0.722345), + REAL(0.109788), REAL(-0.516035), REAL(-0.644590), + REAL(0.178656), REAL(-0.529656), REAL(-0.652804), + REAL(0.061157), REAL(-0.289807), REAL(-0.878626), + REAL(0.138234), REAL(-0.293905), REAL(-0.897958), + REAL(0.066933), REAL(-0.122643), REAL(-0.943820), + REAL(0.149571), REAL(-0.120281), REAL(-0.957264), + REAL(0.280989), REAL(-0.280321), REAL(-0.666487), + REAL(0.246581), REAL(-0.543275), REAL(-0.584224), + REAL(0.211720), REAL(-0.302754), REAL(-0.843303), + REAL(0.086966), REAL(-0.665627), REAL(-0.291520), + REAL(0.110634), REAL(-0.665702), REAL(-0.185021), + REAL(0.228099), REAL(-0.666061), REAL(-0.036201), + REAL(0.337743), REAL(-0.666396), REAL(-0.074503), + REAL(0.376722), REAL(-0.666513), REAL(-0.219833), + REAL(0.377265), REAL(-0.666513), REAL(-0.349036), + REAL(0.281411), REAL(-0.666217), REAL(-0.588670), + REAL(0.267564), REAL(-0.666174), REAL(-0.654834), + REAL(0.080745), REAL(-0.665602), REAL(-0.605452), + REAL(0.122016), REAL(-0.662963), REAL(-0.435280), + REAL(0.095767), REAL(-0.585141), REAL(-0.607228), + REAL(0.118944), REAL(0.012799), REAL(-0.880702), + REAL(0.061944), REAL(0.014564), REAL(-0.882086), + REAL(0.104725), REAL(0.108156), REAL(-0.949130), + REAL(0.048513), REAL(0.115159), REAL(-0.952753), + REAL(0.112696), REAL(0.236643), REAL(0.386937), + REAL(0.128177), REAL(0.269757), REAL(0.436071), + REAL(0.102643), REAL(0.315600), REAL(0.499370), + REAL(0.094535), REAL(0.373481), REAL(0.474824), + REAL(0.136270), REAL(0.443946), REAL(0.426895), + REAL(0.157071), REAL(0.535923), REAL(0.380222), + REAL(0.161350), REAL(0.591224), REAL(0.372630), + REAL(0.173035), REAL(0.662865), REAL(0.417531), + REAL(0.162808), REAL(0.660299), REAL(0.493077), + REAL(0.148250), REAL(0.611070), REAL(0.559555), + REAL(0.125719), REAL(0.576790), REAL(0.484702), + REAL(0.123489), REAL(0.534699), REAL(0.614440), + REAL(0.087621), REAL(0.506066), REAL(0.530188), + REAL(0.055321), REAL(0.442365), REAL(0.572915), + REAL(0.219936), REAL(0.568361), REAL(0.448571), + REAL(0.238099), REAL(0.441375), REAL(0.498528), + REAL(0.281711), REAL(0.414315), REAL(0.451121), + REAL(0.263833), REAL(0.528513), REAL(0.415794), + REAL(0.303284), REAL(0.533081), REAL(0.363998), + REAL(0.269687), REAL(0.623528), REAL(0.380528), + REAL(0.314255), REAL(0.670153), REAL(0.290524), + REAL(0.272023), REAL(0.682273), REAL(0.385343), + REAL(0.311480), REAL(0.775931), REAL(0.308527), + REAL(0.240239), REAL(0.652714), REAL(0.466159), + REAL(0.265619), REAL(0.756464), REAL(0.504187), + REAL(0.192562), REAL(0.467341), REAL(0.522972), + REAL(0.201605), REAL(0.524885), REAL(0.478417), + REAL(0.215743), REAL(0.564193), REAL(0.538084), + REAL(0.264969), REAL(0.641527), REAL(0.605317), + REAL(0.201031), REAL(0.477940), REAL(0.584002), + REAL(0.263086), REAL(0.512567), REAL(0.637832), + REAL(0.238615), REAL(0.526867), REAL(0.672237), + REAL(0.105309), REAL(0.455123), REAL(0.658482), + REAL(0.183993), REAL(0.102195), REAL(0.804872), + REAL(0.161563), REAL(0.060042), REAL(0.808692), + REAL(0.180748), REAL(0.077754), REAL(0.771600), + REAL(0.175168), REAL(0.128588), REAL(0.746368), + REAL(0.175075), REAL(0.148030), REAL(0.778264), + REAL(0.175658), REAL(0.139265), REAL(0.814333), + REAL(0.154191), REAL(0.067291), REAL(0.832578), + REAL(0.163818), REAL(0.109013), REAL(0.842830), + REAL(0.084760), REAL(0.396004), REAL(0.679695), + REAL(0.238888), REAL(0.310760), REAL(0.590775), + REAL(0.213380), REAL(0.308625), REAL(0.644905), + REAL(0.199666), REAL(0.409678), REAL(0.683003), + REAL(0.190143), REAL(0.128597), REAL(0.733463), + REAL(0.184833), REAL(0.063516), REAL(0.762902), + REAL(0.166070), REAL(0.035644), REAL(0.818261), + REAL(0.154361), REAL(0.056943), REAL(0.857042), + REAL(0.168542), REAL(0.109489), REAL(0.862725), + REAL(0.187387), REAL(0.166131), REAL(0.784599), + REAL(0.180428), REAL(0.160135), REAL(0.819438), + REAL(0.201823), REAL(0.163991), REAL(0.695756), + REAL(0.194206), REAL(0.206635), REAL(0.782275), + REAL(0.155438), REAL(0.291260), REAL(0.734412), + REAL(0.177696), REAL(0.196424), REAL(0.846693), + REAL(0.152305), REAL(0.125256), REAL(0.890786), + REAL(0.119546), REAL(0.249876), REAL(0.859104), + REAL(0.118369), REAL(0.139643), REAL(0.919173), + REAL(0.079410), REAL(0.132973), REAL(0.948652), + REAL(0.062419), REAL(0.036648), REAL(0.976547), + REAL(0.127847), REAL(-0.035919), REAL(0.947070), + REAL(0.143624), REAL(0.032206), REAL(0.885913), + REAL(0.074888), REAL(-0.085173), REAL(0.980577), + REAL(0.130184), REAL(-0.104656), REAL(0.947620), + REAL(0.156201), REAL(-0.094653), REAL(0.899074), + REAL(0.077366), REAL(-0.171194), REAL(0.926545), + REAL(0.127722), REAL(-0.164729), REAL(0.879810), + REAL(0.052670), REAL(-0.184618), REAL(0.842019), + REAL(0.023477), REAL(-0.184638), REAL(0.889811), + REAL(0.022626), REAL(-0.210587), REAL(0.827500), + REAL(0.223089), REAL(0.211976), REAL(0.620493), + REAL(0.251444), REAL(0.113067), REAL(0.666494), + REAL(0.251419), REAL(0.089540), REAL(0.673887), + REAL(0.214360), REAL(0.019258), REAL(0.771595), + REAL(0.158999), REAL(0.001490), REAL(0.835374), + REAL(0.176696), REAL(-0.059249), REAL(0.849218), + REAL(0.148696), REAL(-0.130091), REAL(0.793599), + REAL(0.108290), REAL(-0.166528), REAL(0.772088), + REAL(0.049820), REAL(-0.201382), REAL(0.764454), + REAL(0.071341), REAL(-0.215195), REAL(0.697209), + REAL(0.073148), REAL(-0.214475), REAL(0.623510), + REAL(0.140502), REAL(-0.169461), REAL(0.699354), + REAL(0.163374), REAL(-0.157073), REAL(0.611416), + REAL(0.189466), REAL(-0.138550), REAL(0.730366), + REAL(0.247593), REAL(-0.082554), REAL(0.759610), + REAL(0.227468), REAL(-0.121982), REAL(0.590197), + REAL(0.284702), REAL(-0.006586), REAL(0.535347), + REAL(0.275741), REAL(0.125287), REAL(0.446676), + REAL(0.266650), REAL(0.192594), REAL(0.506044), + REAL(0.300086), REAL(0.053287), REAL(0.629620), + REAL(0.055450), REAL(-0.663935), REAL(0.375065), + REAL(0.122854), REAL(-0.664138), REAL(0.482323), + REAL(0.046520), REAL(-0.531571), REAL(0.391918), + REAL(0.024824), REAL(-0.568450), REAL(0.275106), + REAL(0.053855), REAL(-0.663931), REAL(0.328224), + REAL(0.112829), REAL(-0.453549), REAL(0.305788), + REAL(0.131265), REAL(-0.510617), REAL(0.080746), + REAL(0.061174), REAL(-0.430716), REAL(-0.042710), + REAL(0.341019), REAL(-0.532887), REAL(-0.208150), + REAL(0.347705), REAL(-0.623533), REAL(-0.081139), + REAL(0.238040), REAL(-0.610732), REAL(-0.038037), + REAL(0.211764), REAL(-0.514274), REAL(-0.132078), + REAL(0.120605), REAL(-0.600219), REAL(-0.186856), + REAL(0.096985), REAL(-0.584476), REAL(-0.293357), + REAL(0.127621), REAL(-0.581941), REAL(-0.437170), + REAL(0.165902), REAL(-0.477425), REAL(-0.291453), + REAL(0.077720), REAL(-0.417975), REAL(-0.220519), + REAL(0.320892), REAL(-0.506363), REAL(-0.320874), + REAL(0.248214), REAL(-0.465684), REAL(-0.239842), + REAL(0.118764), REAL(-0.383338), REAL(-0.187114), + REAL(0.118816), REAL(-0.430106), REAL(-0.123307), + REAL(0.094131), REAL(-0.419464), REAL(-0.044777), + REAL(0.274526), REAL(-0.261706), REAL(0.005110), + REAL(0.259842), REAL(-0.283292), REAL(-0.003185), + REAL(0.222861), REAL(-0.340431), REAL(-0.038210), + REAL(0.204445), REAL(-0.664380), REAL(0.513353), + REAL(0.259286), REAL(-0.664547), REAL(0.471281), + REAL(0.185402), REAL(-0.476020), REAL(0.421718), + REAL(0.279163), REAL(-0.664604), REAL(0.417328), + REAL(0.277157), REAL(-0.528122), REAL(0.400208), + REAL(0.183069), REAL(-0.509812), REAL(0.329995), + REAL(0.282599), REAL(-0.429210), REAL(0.059242), + REAL(0.254816), REAL(-0.664541), REAL(0.290687), + REAL(0.271436), REAL(-0.567707), REAL(0.263966), + REAL(0.386561), REAL(-0.625221), REAL(-0.216870), + REAL(0.387086), REAL(-0.630883), REAL(-0.346073), + REAL(0.380021), REAL(-0.596021), REAL(-0.318679), + REAL(0.291269), REAL(-0.619007), REAL(-0.585707), + REAL(0.339280), REAL(-0.571198), REAL(-0.461946), + REAL(0.400045), REAL(-0.489778), REAL(-0.422640), + REAL(0.406817), REAL(-0.314349), REAL(-0.371230), + REAL(0.300588), REAL(-0.281718), REAL(-0.170549), + REAL(0.290866), REAL(-0.277304), REAL(-0.061905), + REAL(0.187735), REAL(-0.241545), REAL(0.509437), + REAL(0.188032), REAL(-0.287569), REAL(0.424234), + REAL(0.227520), REAL(-0.373262), REAL(0.293102), + REAL(0.266526), REAL(-0.273650), REAL(0.039597), + REAL(0.291592), REAL(-0.291676), REAL(0.111386), + REAL(0.291914), REAL(-0.122741), REAL(0.422683), + REAL(0.297574), REAL(-0.156119), REAL(0.373368), + REAL(0.286603), REAL(-0.232731), REAL(0.027162), + REAL(0.364663), REAL(-0.201399), REAL(0.206850), + REAL(0.353855), REAL(-0.132408), REAL(0.149228), + REAL(0.282208), REAL(-0.019715), REAL(0.314960), + REAL(0.331187), REAL(-0.099266), REAL(0.092701), + REAL(0.375463), REAL(-0.093120), REAL(-0.006467), + REAL(0.375917), REAL(-0.101236), REAL(-0.154882), + REAL(0.466635), REAL(-0.094416), REAL(-0.305669), + REAL(0.455805), REAL(-0.119881), REAL(-0.460632), + REAL(0.277465), REAL(-0.604242), REAL(-0.651871), + REAL(0.261022), REAL(-0.551176), REAL(-0.554667), + REAL(0.093627), REAL(0.258494), REAL(-0.920589), + REAL(0.114248), REAL(0.310608), REAL(-0.798070), + REAL(0.144232), REAL(0.211434), REAL(-0.835001), + REAL(0.119916), REAL(0.176940), REAL(-0.951159), + REAL(0.184061), REAL(0.101854), REAL(-0.918220), + REAL(0.092431), REAL(0.276521), REAL(-0.738231), + REAL(0.133504), REAL(0.218403), REAL(-0.758602), + REAL(0.194987), REAL(0.097655), REAL(-0.812476), + REAL(0.185542), REAL(0.011005), REAL(-0.879202), + REAL(0.230315), REAL(-0.127450), REAL(-0.884202), + REAL(0.260471), REAL(0.255056), REAL(-0.624378), + REAL(0.351567), REAL(-0.042194), REAL(-0.663976), + REAL(0.253742), REAL(0.323524), REAL(-0.433716), + REAL(0.411612), REAL(0.132299), REAL(-0.438264), + REAL(0.270513), REAL(0.356530), REAL(-0.289984), + REAL(0.422146), REAL(0.162819), REAL(-0.273130), + REAL(0.164724), REAL(0.237490), REAL(0.208912), + REAL(0.253806), REAL(0.092900), REAL(0.240640), + REAL(0.203608), REAL(0.284597), REAL(0.096223), + REAL(0.241006), REAL(0.343093), REAL(-0.171396), + REAL(0.356076), REAL(0.149288), REAL(-0.143443), + REAL(0.337656), REAL(0.131992), REAL(0.066374) +}; + +int 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} +}; + + +// 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, (int*)&Indices[0], IndexCount, 3 * sizeof(int)); + + 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 0 + // What is this for??? - Bram + if (!pause) + { + 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, 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.57537403079093) && + cmp(m._I(2,2),4.57537403079093) && + 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, 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, + 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; +} diff --git a/libraries/ode-0.9/ode/demo/demo_plane2d.cpp b/libraries/ode-0.9/ode/demo/demo_plane2d.cpp new file mode 100644 index 0000000000..3ba4df82fc --- /dev/null +++ b/libraries/ode-0.9/ode/demo/demo_plane2d.cpp @@ -0,0 +1,268 @@ +// Test my Plane2D constraint. +// Uses ode-0.35 collision API. + +# include +# include +# include +# include +# include + +# 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 + + +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 () +/*************************/ +{ + 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; + + + dInitODE(); + + // 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 (0); + + { + // 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/textures"; + + dsSimulationLoop (argc, argv, 352,288,&drawstuff_functions); + } + + dCloseODE(); + return 0; +} diff --git a/libraries/ode-0.9/ode/demo/demo_slider.cpp b/libraries/ode-0.9/ode/demo/demo_slider.cpp new file mode 100644 index 0000000000..5de08b0e7a --- /dev/null +++ b/libraries/ode-0.9/ode/demo/demo_slider.cpp @@ -0,0 +1,172 @@ +/************************************************************************* + * * + * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. * + * All rights reserved. Email: russ@q12.org Web: www.q12.org * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 2.1 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without 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 + +#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() +{ + 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/textures"; + if(argc==2) + { + fn.path_to_textures = argv[1]; + } + + // create world + dInitODE(); + world = dWorldCreate(); + dMass m; + dMassSetBox (&m,1,SIDE,SIDE,SIDE); + dMassAdjust (&m,MASS); + + body[0] = dBodyCreate (world); + dBodySetMass (body[0],&m); + dBodySetPosition (body[0],0,0,1); + body[1] = dBodyCreate (world); + dBodySetMass (body[1],&m); + dQuaternion q; + dQFromAxisAndAngle (q,-1,1,0,0.25*M_PI); + dBodySetPosition (body[1],0.2,0.2,1.2); + dBodySetQuaternion (body[1],q); + + slider = dJointCreateSlider (world,0); + dJointAttach (slider,body[0],body[1]); + dJointSetSliderAxis (slider,1,1,1); + + // run simulation + dsSimulationLoop (argc,argv,352,288,&fn); + + dWorldDestroy (world); + dCloseODE(); + return 0; +} diff --git a/libraries/ode-0.9/ode/demo/demo_space.cpp b/libraries/ode-0.9/ode/demo/demo_space.cpp new file mode 100644 index 0000000000..73101b54fb --- /dev/null +++ b/libraries/ode-0.9/ode/demo/demo_space.cpp @@ -0,0 +1,233 @@ +/************************************************************************* + * * + * 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 + +#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",i,j); + if (!good_matrix[i][j] || !good_matrix[j][i]) + printf ("collision (%d,%d) is incorrect\n",i,j); + if (test_matrix[i][j] || test_matrix[j][i]) + printf ("collision (%d,%d) reported more than once\n",i,j); + test_matrix[i][j] = 1; + test_matrix[j][i] = 1; +} + + +// 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}; + 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/textures"; + if(argc==2) + { + fn.path_to_textures = argv[1]; + } + + dInitODE(); + + // test the simple space: + // space = dSimpleSpaceCreate(); + + // test the hash space: + // space = dHashSpaceCreate (0); + // dHashSpaceSetLevels (space,-10,10); + + // test the quadtree space + dVector3 Center = {0, 0, 0, 0}; + dVector3 Extents = {10, 0, 10, 0}; + space = dQuadTreeSpaceCreate(0, Center, Extents, 7); + + for (i=0; i < NUM; i++) geom[i] = 0; + init_test(); + + // run simulation + dsSimulationLoop (argc,argv,352,288,&fn); + + dSpaceDestroy (space); + dCloseODE(); + return 0; +} diff --git a/libraries/ode-0.9/ode/demo/demo_space_stress.cpp b/libraries/ode-0.9/ode/demo/demo_space_stress.cpp new file mode 100644 index 0000000000..e1be369ed5 --- /dev/null +++ b/libraries/ode-0.9/ode/demo/demo_space_stress.cpp @@ -0,0 +1,435 @@ +/************************************************************************* + * * + * 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 + +#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 + +#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 + +#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 dVector3 Vertices[VertexCount]; +static int 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