From a9172d8684bdd78b1764196bc393dd22fcb35e56 Mon Sep 17 00:00:00 2001 From: ejcoumans Date: Sun, 12 Nov 2006 06:15:19 +0000 Subject: [PATCH] =?UTF-8?q?Added=20GIMPACT=20integration=20for=20moving=20?= =?UTF-8?q?concave=20meshes=20(interaction=20with=20all=20other=20Bullet?= =?UTF-8?q?=20collision=20shapes)=20Thanks=20a=20lot=20to=20Francisco=20Le?= =?UTF-8?q?=C3=B3n=20N=C3=A1jera=20for=20the=20contribution!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Demos/Jamfile | 1 + Demos/MovingConcaveDemo/ConcaveDemo.h | 42 + .../MovingConcaveDemo/ConcavePhysicsDemo.cpp | 1889 ++++++++++++++++ Demos/OpenGL/GL_ShapeDrawer.cpp | 103 +- Demos/OpenGL/GL_ShapeDrawer.h | 3 + .../UserCollisionAlgorithm.cpp | 2 +- Extras/GIMPACT/Doxyfile | 267 +++ Extras/GIMPACT/GIMPACT-LICENSE-BSD.TXT | 29 + Extras/GIMPACT/GIMPACT-LICENSE-LGPL.TXT | 502 +++++ Extras/GIMPACT/GIMPACT-LICENSE-ZLIB.TXT | 23 + Extras/GIMPACT/GIMPACT.cbp | 208 ++ Extras/GIMPACT/GIMPACT.depend | 307 +++ Extras/GIMPACT/GIMPACT.layout | 31 + .../include/GIMPACT/gim_box_collision.h | 400 ++++ .../GIMPACT/include/GIMPACT/gim_boxpruning.h | 484 +++++ Extras/GIMPACT/include/GIMPACT/gim_contact.h | 121 ++ Extras/GIMPACT/include/GIMPACT/gim_geometry.h | 1892 +++++++++++++++++ Extras/GIMPACT/include/GIMPACT/gim_math.h | 168 ++ Extras/GIMPACT/include/GIMPACT/gim_memory.h | 1054 +++++++++ .../GIMPACT/include/GIMPACT/gim_radixsort.h | 302 +++ .../GIMPACT/gim_tri_capsule_collision.h | 113 + .../include/GIMPACT/gim_tri_collision.h | 256 +++ .../GIMPACT/gim_tri_sphere_collision.h | 53 + Extras/GIMPACT/include/GIMPACT/gim_trimesh.h | 657 ++++++ .../include/GIMPACT/gim_trimesh_data.h | 182 ++ .../include/GIMPACT/gim_vertex_buffer_util.h | 106 + Extras/GIMPACT/include/GIMPACT/gimpact.h | 47 + Extras/GIMPACT/src/gim_boxpruning.cpp | 1028 +++++++++ Extras/GIMPACT/src/gim_contact.cpp | 185 ++ Extras/GIMPACT/src/gim_math.cpp | 62 + Extras/GIMPACT/src/gim_memory.cpp | 854 ++++++++ Extras/GIMPACT/src/gim_tri_tri_overlap.cpp | 329 +++ Extras/GIMPACT/src/gim_trimesh.cpp | 707 ++++++ .../src/gim_trimesh_capsule_collision.cpp | 281 +++ Extras/GIMPACT/src/gim_trimesh_data.cpp | 454 ++++ .../GIMPACT/src/gim_trimesh_ray_collision.cpp | 180 ++ .../src/gim_trimesh_sphere_collision.cpp | 198 ++ .../src/gim_trimesh_trimesh_collision.cpp | 457 ++++ Extras/GIMPACT/src/gim_vertex_buffer_util.cpp | 56 + Extras/GIMPACT/src/gimpact.cpp | 43 + Extras/GIMPACTBullet/Jamfile | 10 + .../btConcaveConcaveCollisionAlgorithm.cpp | 136 ++ .../btConcaveConcaveCollisionAlgorithm.h | 60 + Extras/GIMPACTBullet/btGIMPACTMeshShape.cpp | 533 +++++ Extras/GIMPACTBullet/btGIMPACTMeshShape.h | 114 + Extras/Jamfile | 2 + .../BroadphaseCollision/btBroadphaseProxy.h | 4 +- 47 files changed, 14930 insertions(+), 5 deletions(-) create mode 100644 Demos/MovingConcaveDemo/ConcaveDemo.h create mode 100644 Demos/MovingConcaveDemo/ConcavePhysicsDemo.cpp create mode 100644 Extras/GIMPACT/Doxyfile create mode 100644 Extras/GIMPACT/GIMPACT-LICENSE-BSD.TXT create mode 100644 Extras/GIMPACT/GIMPACT-LICENSE-LGPL.TXT create mode 100644 Extras/GIMPACT/GIMPACT-LICENSE-ZLIB.TXT create mode 100644 Extras/GIMPACT/GIMPACT.cbp create mode 100644 Extras/GIMPACT/GIMPACT.depend create mode 100644 Extras/GIMPACT/GIMPACT.layout create mode 100644 Extras/GIMPACT/include/GIMPACT/gim_box_collision.h create mode 100644 Extras/GIMPACT/include/GIMPACT/gim_boxpruning.h create mode 100644 Extras/GIMPACT/include/GIMPACT/gim_contact.h create mode 100644 Extras/GIMPACT/include/GIMPACT/gim_geometry.h create mode 100644 Extras/GIMPACT/include/GIMPACT/gim_math.h create mode 100644 Extras/GIMPACT/include/GIMPACT/gim_memory.h create mode 100644 Extras/GIMPACT/include/GIMPACT/gim_radixsort.h create mode 100644 Extras/GIMPACT/include/GIMPACT/gim_tri_capsule_collision.h create mode 100644 Extras/GIMPACT/include/GIMPACT/gim_tri_collision.h create mode 100644 Extras/GIMPACT/include/GIMPACT/gim_tri_sphere_collision.h create mode 100644 Extras/GIMPACT/include/GIMPACT/gim_trimesh.h create mode 100644 Extras/GIMPACT/include/GIMPACT/gim_trimesh_data.h create mode 100644 Extras/GIMPACT/include/GIMPACT/gim_vertex_buffer_util.h create mode 100644 Extras/GIMPACT/include/GIMPACT/gimpact.h create mode 100644 Extras/GIMPACT/src/gim_boxpruning.cpp create mode 100644 Extras/GIMPACT/src/gim_contact.cpp create mode 100644 Extras/GIMPACT/src/gim_math.cpp create mode 100644 Extras/GIMPACT/src/gim_memory.cpp create mode 100644 Extras/GIMPACT/src/gim_tri_tri_overlap.cpp create mode 100644 Extras/GIMPACT/src/gim_trimesh.cpp create mode 100644 Extras/GIMPACT/src/gim_trimesh_capsule_collision.cpp create mode 100644 Extras/GIMPACT/src/gim_trimesh_data.cpp create mode 100644 Extras/GIMPACT/src/gim_trimesh_ray_collision.cpp create mode 100644 Extras/GIMPACT/src/gim_trimesh_sphere_collision.cpp create mode 100644 Extras/GIMPACT/src/gim_trimesh_trimesh_collision.cpp create mode 100644 Extras/GIMPACT/src/gim_vertex_buffer_util.cpp create mode 100644 Extras/GIMPACT/src/gimpact.cpp create mode 100644 Extras/GIMPACTBullet/Jamfile create mode 100644 Extras/GIMPACTBullet/btConcaveConcaveCollisionAlgorithm.cpp create mode 100644 Extras/GIMPACTBullet/btConcaveConcaveCollisionAlgorithm.h create mode 100644 Extras/GIMPACTBullet/btGIMPACTMeshShape.cpp create mode 100644 Extras/GIMPACTBullet/btGIMPACTMeshShape.h diff --git a/Demos/Jamfile b/Demos/Jamfile index 7a938041f..e55413960 100644 --- a/Demos/Jamfile +++ b/Demos/Jamfile @@ -77,6 +77,7 @@ SubInclude TOP Demos BspDemo ; SubInclude TOP Demos VehicleDemo ; SubInclude TOP Demos CollisionDemo ; SubInclude TOP Demos CollisionInterfaceDemo ; +#SubInclude TOP Demos MovingConcaveDemo ; SubInclude TOP Demos ConcaveDemo ; SubInclude TOP Demos ConstraintDemo ; SubInclude TOP Demos ContinuousConvexCollision ; diff --git a/Demos/MovingConcaveDemo/ConcaveDemo.h b/Demos/MovingConcaveDemo/ConcaveDemo.h new file mode 100644 index 000000000..bacef7282 --- /dev/null +++ b/Demos/MovingConcaveDemo/ConcaveDemo.h @@ -0,0 +1,42 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ +#ifndef CONCAVE_DEMO_H +#define CONCAVE_DEMO_H + +#include "DemoApplication.h" + +///ConcaveDemo shows usage of static concave triangle meshes +///It also shows per-triangle material (friction/restitution) through CustomMaterialCombinerCallback +class ConcaveDemo : public DemoApplication +{ + public: + + void initPhysics(); + + virtual void clientMoveAndDisplay(); + + virtual void displayCallback(); + + virtual void renderme(); + virtual void keyboardCallback(unsigned char key, int x, int y); + + ///Demo functions + void shootTrimesh(const btVector3& destination); + + +}; + +#endif //CONCAVE_DEMO_H + diff --git a/Demos/MovingConcaveDemo/ConcavePhysicsDemo.cpp b/Demos/MovingConcaveDemo/ConcavePhysicsDemo.cpp new file mode 100644 index 000000000..9bfa784d6 --- /dev/null +++ b/Demos/MovingConcaveDemo/ConcavePhysicsDemo.cpp @@ -0,0 +1,1889 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#include "btBulletDynamicsCommon.h" + +#include "LinearMath/btDefaultMotionState.h" +#include "LinearMath/btIDebugDraw.h" +#include "LinearMath/btQuickprof.h" +#include "LinearMath/btDefaultMotionState.h" +#include "../Extras/GIMPACTBullet/btGIMPACTMeshShape.h" +#include "../Extras/GIMPACTBullet/btConcaveConcaveCollisionAlgorithm.h" + + + +#include "BMF_Api.h" + +#include "GLDebugDrawer.h" +#include "ConcaveDemo.h" +#include "GL_ShapeDrawer.h" +#include "GlutStuff.h" + + +GLDebugDrawer debugDrawer; + +//***************************THE FAMOUS BUNNY TRIMESH********************************************// + +#define REAL float +const int NUM_TRIANGLES =902; +const int NUM_VERTICES = 453; +const int NUM_INDICES = NUM_TRIANGLES * 3; + + +REAL gVertices[NUM_VERTICES * 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 gIndices[NUM_TRIANGLES][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} +}; + +//TRIMESH GLOBAL +btGIMPACTMeshData * g_trimeshData; + +//***************************THE END OF FAMOUS BUNNY TRIMESH********************************************// + + +///User can override this material combiner by implementing gContactAddedCallback and setting body0->m_collisionFlags |= btCollisionObject::customMaterialCallback; +inline btScalar calculateCombinedFriction(float friction0,float friction1) +{ + btScalar friction = friction0 * friction1; + + const btScalar MAX_FRICTION = 10.f; + if (friction < -MAX_FRICTION) + friction = -MAX_FRICTION; + if (friction > MAX_FRICTION) + friction = MAX_FRICTION; + return friction; + +} + +inline btScalar calculateCombinedRestitution(float restitution0,float restitution1) +{ + return restitution0 * restitution1; +} + + + +bool CustomMaterialCombinerCallback(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1) +{ + + float friction0 = colObj0->getFriction(); + float friction1 = colObj1->getFriction(); + float restitution0 = colObj0->getRestitution(); + float restitution1 = colObj1->getRestitution(); + + if (colObj0->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) + { + friction0 = 1.0;//partId0,index0 + restitution0 = 0.f; + } + if (colObj1->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) + { + if (index1&1) + { + friction1 = 1.0f;//partId1,index1 + } else + { + friction1 = 0.f; + } + restitution1 = 0.f; + } + + cp.m_combinedFriction = calculateCombinedFriction(friction0,friction1); + cp.m_combinedRestitution = calculateCombinedRestitution(restitution0,restitution1); + + //this return value is currently ignored, but to be on the safe side: return false if you don't calculate friction + return true; +} + +extern ContactAddedCallback gContactAddedCallback; + + + +int main(int argc,char** argv) +{ + gContactAddedCallback = CustomMaterialCombinerCallback; + + ConcaveDemo* concaveDemo = new ConcaveDemo(); + concaveDemo->initPhysics(); + concaveDemo->setCameraDistance(30.f); + concaveDemo->stepFront(); + concaveDemo->stepFront(); + concaveDemo->stepFront(); + concaveDemo->stepFront(); + + + return glutmain(argc, argv,640,480,"Moving Concave Mesh Demo",concaveDemo); +} + +void ConcaveDemo::renderme() +{ + updateCamera(); + + float m[16]; + + if (m_dynamicsWorld) + { + int numObjects = m_dynamicsWorld->getNumCollisionObjects(); + btVector3 wireColor(1,0,0); + for (int i=0;igetCollisionObjectArray()[i]; + btRigidBody* body = btRigidBody::upcast(colObj); + + if (body && body->getMotionState()) + { + btDefaultMotionState* myMotionState = (btDefaultMotionState*)body->getMotionState(); + myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(m); + } else + { + colObj->getWorldTransform().getOpenGLMatrix(m); + } + + btVector3 wireColor(1.f,1.0f,0.5f); //wants deactivation + if (i & 1) + { + wireColor = btVector3(0.f,0.0f,1.f); + } + ///color differently for active, sleeping, wantsdeactivation states + if (colObj->getActivationState() == 1) //active + { + if (i & 1) + { + wireColor += btVector3 (1.f,0.f,0.f); + } else + { + wireColor += btVector3 (.5f,0.f,0.f); + } + } + if (colObj->getActivationState() == 2) //ISLAND_SLEEPING + { + if (i & 1) + { + wireColor += btVector3 (0.f,1.f, 0.f); + } else + { + wireColor += btVector3 (0.f,0.5f,0.f); + } + } + + GL_ShapeDrawer::drawOpenGL(m,colObj->getCollisionShape(),wireColor,getDebugMode()); + } + + + float xOffset = 10.f; + float yStart = 20.f; + float yIncr = -2.f; + char buf[124]; + + glColor3f(0, 0, 0); + + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"mouse to interact"); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + + /* glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"space to reset"); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + */ + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"cursor keys and z,x to navigate"); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"i to toggle simulation, s single step"); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"q to quit"); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,". to shoot TRIMESH (dot)"); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + + // not yet hooked up again after refactoring... + +/* glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"d to toggle deactivation"); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; +*/ + + /* + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"a to draw temporal AABBs"); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + */ + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"h to toggle help text"); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + + //bool useBulletLCP = !(getDebugMode() & btIDebugDraw::DBG_DisableBulletLCP); + + bool useCCD = (getDebugMode() & btIDebugDraw::DBG_EnableCCD); + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"1 CCD mode (adhoc) = %i",useCCD); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + + glRasterPos3f(xOffset,yStart,0); + sprintf(buf,"+- shooting speed = %10.2f",m_ShootBoxInitialSpeed); + BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf); + yStart += yIncr; + + } + +} + + +void ConcaveDemo::initPhysics() +{ + + btTriangleIndexVertexArray* indexVertexArrays = new btTriangleIndexVertexArray(NUM_TRIANGLES, + &gIndices[0][0], + 3*sizeof(int), + NUM_VERTICES,(REAL*) &gVertices[0],sizeof(REAL)*3); + + g_trimeshData = new btGIMPACTMeshData(indexVertexArrays); + + //btConstraintSolver* solver = new btSequentialImpulseConstraintSolver; + btCollisionDispatcher* dispatcher = new btCollisionDispatcher(); + //btOverlappingPairCache* broadphase = new btSimpleBroadphase(); + btOverlappingPairCache* broadphase = new btSimpleBroadphase(); + + m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase); + dispatcher->registerCollisionCreateFunc(GIMPACT_SHAPE_PROXYTYPE,GIMPACT_SHAPE_PROXYTYPE,new btConcaveConcaveCollisionAlgorithm::CreateFunc); + dispatcher->registerCollisionCreateFunc(TRIANGLE_MESH_SHAPE_PROXYTYPE,GIMPACT_SHAPE_PROXYTYPE,new btConcaveConcaveCollisionAlgorithm::CreateFunc); + dispatcher->registerCollisionCreateFunc(GIMPACT_SHAPE_PROXYTYPE,TRIANGLE_MESH_SHAPE_PROXYTYPE,new btConcaveConcaveCollisionAlgorithm::CreateFunc); + + + + + bool isDynamic = false; + float mass = 0.f; + btTransform startTransform; + startTransform.setIdentity(); + + btCollisionShape* staticboxShape1 = new btBoxShape(btVector3(200,1,200));//floor + btCollisionShape* staticboxShape2 = new btBoxShape(btVector3(1,50,200));//left wall + btCollisionShape* staticboxShape3 = new btBoxShape(btVector3(1,50,200));//right wall + btCollisionShape* staticboxShape4 = new btBoxShape(btVector3(200,50,1));//front wall + btCollisionShape* staticboxShape5 = new btBoxShape(btVector3(200,50,1));//back wall + + btCompoundShape* staticScenario = new btCompoundShape();//static scenario + + startTransform.setOrigin(btVector3(0,0,0)); + staticScenario->addChildShape(startTransform,staticboxShape1); + startTransform.setOrigin(btVector3(-200,25,0)); + staticScenario->addChildShape(startTransform,staticboxShape2); + startTransform.setOrigin(btVector3(200,25,0)); + staticScenario->addChildShape(startTransform,staticboxShape3); + startTransform.setOrigin(btVector3(0,25,200)); + staticScenario->addChildShape(startTransform,staticboxShape4); + startTransform.setOrigin(btVector3(0,25,-200)); + staticScenario->addChildShape(startTransform,staticboxShape5); + + startTransform.setOrigin(btVector3(0,0,0)); + + btRigidBody* staticBody = localCreateRigidBody(mass, startTransform,staticScenario); + + //enable custom material callback + staticBody->setCollisionFlags(staticBody->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + + { + for (int i=0;i<10;i++) + { + btCollisionShape* boxShape = new btBoxShape(btVector3(1,1,1)); + startTransform.setOrigin(btVector3(2*i,2,1)); + localCreateRigidBody(1, startTransform,boxShape); + } + } + + m_debugMode |= btIDebugDraw::DBG_DrawWireframe; + +} + +void ConcaveDemo::keyboardCallback(unsigned char key, int x, int y) +{ + m_lastKey = 0; + + switch (key) + { + case 'q' : exit(0); break; + + case 'l' : stepLeft(); break; + case 'r' : stepRight(); break; + case 'f' : stepFront(); break; + case 'b' : stepBack(); break; + case 'z' : zoomIn(); break; + case 'x' : zoomOut(); break; + case 'i' : toggleIdle(); break; + case 'h': + if (m_debugMode & btIDebugDraw::DBG_NoHelpText) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_NoHelpText); + else + m_debugMode |= btIDebugDraw::DBG_NoHelpText; + break; + + case 'w': + if (m_debugMode & btIDebugDraw::DBG_DrawWireframe) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawWireframe); + else + m_debugMode |= btIDebugDraw::DBG_DrawWireframe; + break; + + case 'p': + if (m_debugMode & btIDebugDraw::DBG_ProfileTimings) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_ProfileTimings); + else + m_debugMode |= btIDebugDraw::DBG_ProfileTimings; + break; + + case 'm': + if (m_debugMode & btIDebugDraw::DBG_EnableSatComparison) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_EnableSatComparison); + else + m_debugMode |= btIDebugDraw::DBG_EnableSatComparison; + break; + + case 'n': + if (m_debugMode & btIDebugDraw::DBG_DisableBulletLCP) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DisableBulletLCP); + else + m_debugMode |= btIDebugDraw::DBG_DisableBulletLCP; + break; + + case 't' : + if (m_debugMode & btIDebugDraw::DBG_DrawText) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawText); + else + m_debugMode |= btIDebugDraw::DBG_DrawText; + break; + case 'y': + if (m_debugMode & btIDebugDraw::DBG_DrawFeaturesText) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawFeaturesText); + else + m_debugMode |= btIDebugDraw::DBG_DrawFeaturesText; + break; + case 'a': + if (m_debugMode & btIDebugDraw::DBG_DrawAabb) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawAabb); + else + m_debugMode |= btIDebugDraw::DBG_DrawAabb; + break; + case 'c' : + if (m_debugMode & btIDebugDraw::DBG_DrawContactPoints) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_DrawContactPoints); + else + m_debugMode |= btIDebugDraw::DBG_DrawContactPoints; + break; + + case 'd' : + if (m_debugMode & btIDebugDraw::DBG_NoDeactivation) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_NoDeactivation); + else + m_debugMode |= btIDebugDraw::DBG_NoDeactivation; + if (m_debugMode | btIDebugDraw::DBG_NoDeactivation) + { + gDisableDeactivation = true; + } else + { + gDisableDeactivation = false; + } + break; + + + + + case 'o' : + { + m_stepping = !m_stepping; + break; + } + case 's' : clientMoveAndDisplay(); break; +// case ' ' : newRandom(); break; + case ' ': + clientResetScene(); + break; + case '1': + { + if (m_debugMode & btIDebugDraw::DBG_EnableCCD) + m_debugMode = m_debugMode & (~btIDebugDraw::DBG_EnableCCD); + else + m_debugMode |= btIDebugDraw::DBG_EnableCCD; + break; + } + + case '.': + { + shootTrimesh(getCameraTargetPosition()); + break; + } + + case '+': + { + m_ShootBoxInitialSpeed += 10.f; + break; + } + case '-': + { + m_ShootBoxInitialSpeed -= 10.f; + break; + } + + default: +// std::cout << "unused key : " << key << std::endl; + break; + } + + if (getDynamicsWorld() && getDynamicsWorld()->getDebugDrawer()) + getDynamicsWorld()->getDebugDrawer()->setDebugMode(m_debugMode); + + glutPostRedisplay(); + +} + + +btGIMPACTMeshShape * createMesh() +{ + btGIMPACTMeshShape * newtrimeshShape = new btGIMPACTMeshShape(g_trimeshData ); + newtrimeshShape->setLocalScaling(btVector3(4.f,4.f,4.f)); + //OGL_displaylist_register_shape(newtrimeshShape); + return newtrimeshShape; +} + +void ConcaveDemo::shootTrimesh(const btVector3& destination) +{ + + if (m_dynamicsWorld) + { + bool isDynamic = true; + float mass = 4.f; + btTransform startTransform; + startTransform.setIdentity(); + btVector3 camPos = getCameraPosition(); + startTransform.setOrigin(camPos); + + btGIMPACTMeshShape * newtrimeshShape = createMesh(); + + btRigidBody* body = this->localCreateRigidBody(mass, startTransform,newtrimeshShape); + + btVector3 linVel(destination[0]-camPos[0],destination[1]-camPos[1],destination[2]-camPos[2]); + linVel.normalize(); + linVel*=m_ShootBoxInitialSpeed*0.25; + + body->getWorldTransform().setOrigin(camPos); + body->getWorldTransform().setRotation(btQuaternion(0,0,0,1)); + body->setLinearVelocity(linVel); + body->setAngularVelocity(btVector3(0,0,0)); + } +} + +void ConcaveDemo::clientMoveAndDisplay() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + float dt = m_clock.getTimeMilliseconds() * 0.001f; + m_clock.reset(); + + m_dynamicsWorld->stepSimulation(dt); + + renderme(); + + glFlush(); + glutSwapBuffers(); + +} + + + + +void ConcaveDemo::displayCallback(void) { + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderme(); + + glFlush(); + glutSwapBuffers(); +} + + diff --git a/Demos/OpenGL/GL_ShapeDrawer.cpp b/Demos/OpenGL/GL_ShapeDrawer.cpp index 30b633611..89c3c155e 100644 --- a/Demos/OpenGL/GL_ShapeDrawer.cpp +++ b/Demos/OpenGL/GL_ShapeDrawer.cpp @@ -44,6 +44,93 @@ subject to the following restrictions: #include "BMF_Api.h" #include //printf debugging +#ifdef USE_DISPLAY_LISTS + +#include + +using namespace std; + +//Set for storing Display list per trimesh +struct TRIMESH_KEY +{ + btCollisionShape* m_shape; + GLuint m_dlist;//OpenGL display list +}; + +typedef map TRIMESH_KEY_MAP; + +typedef pair TRIMESH_KEY_PAIR; + +TRIMESH_KEY_MAP g_display_lists; + +GLuint OGL_get_displaylist_for_shape(btCollisionShape * shape) +{ + TRIMESH_KEY_MAP::iterator map_iter; + + unsigned long key = (unsigned long)shape; + map_iter = g_display_lists.find(key); + if(map_iter!=g_display_lists.end()) + { + return map_iter->second.m_dlist; + } + + return 0; +} + +void OGL_displaylist_clean() +{ + TRIMESH_KEY_MAP::iterator map_iter,map_itend; + + map_iter = g_display_lists.begin(); + + while(map_iter!=map_itend) + { + glDeleteLists(map_iter->second.m_dlist,1); + map_iter++; + } + + g_display_lists.clear(); +} + + +void OGL_displaylist_register_shape(btCollisionShape * shape) +{ + btVector3 aabbMax(1e30f,1e30f,1e30f); + btVector3 aabbMin(-1e30f,-1e30f,-1e30f); + GlDrawcallback drawCallback; + TRIMESH_KEY dlist; + + dlist.m_dlist = glGenLists(1); + dlist.m_shape = shape; + + unsigned long key = (unsigned long)shape; + + g_display_lists.insert(TRIMESH_KEY_PAIR(key,dlist)); + + glNewList(dlist.m_dlist,GL_COMPILE); + + glEnable(GL_CULL_FACE); + + glCullFace(GL_BACK); + + if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) + { + btTriangleMeshShape* concaveMesh = (btTriangleMeshShape*) shape; + //todo pass camera, for some culling + concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax); + } + else if (shape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE) + { + btGIMPACTMeshShape* gimpactMesh = (btGIMPACTMeshShape*) shape; + gimpactMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax); + } + + glDisable(GL_CULL_FACE); + + glEndList(); +} +#endif //USE_DISPLAY_LISTS + void GL_ShapeDrawer::drawCoordSystem() { glBegin(GL_LINES); glColor3f(1, 0, 0); @@ -322,9 +409,19 @@ void GL_ShapeDrawer::drawOpenGL(float* m, const btCollisionShape* shape, const b } } - if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) + +#ifdef USE_DISPLAY_LISTS + + if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE||shape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE) { - btTriangleMeshShape* concaveMesh = (btTriangleMeshShape*) shape; + GLuint dlist = OGL_get_displaylist_for_shape((btCollisionShape * )shape); + glCallList(dlist); + } +#else + if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE||shape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE) +// if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) + { + ConcaveShape* concaveMesh = (btTriangleMeshShape*) shape; //btVector3 aabbMax(1e30f,1e30f,1e30f); //btVector3 aabbMax(100,100,100);//1e30f,1e30f,1e30f); @@ -337,8 +434,8 @@ void GL_ShapeDrawer::drawOpenGL(float* m, const btCollisionShape* shape, const b concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax); - } +#endif if (shape->getShapeType() == CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE) { diff --git a/Demos/OpenGL/GL_ShapeDrawer.h b/Demos/OpenGL/GL_ShapeDrawer.h index dd900d3d9..57e495b68 100644 --- a/Demos/OpenGL/GL_ShapeDrawer.h +++ b/Demos/OpenGL/GL_ShapeDrawer.h @@ -28,4 +28,7 @@ class GL_ShapeDrawer }; +void OGL_displaylist_register_shape(btCollisionShape * shape); +void OGL_displaylist_clean(); + #endif //GL_SHAPE_DRAWER_H diff --git a/Demos/UserCollisionAlgorithm/UserCollisionAlgorithm.cpp b/Demos/UserCollisionAlgorithm/UserCollisionAlgorithm.cpp index d22ab4d29..f43138ba2 100644 --- a/Demos/UserCollisionAlgorithm/UserCollisionAlgorithm.cpp +++ b/Demos/UserCollisionAlgorithm/UserCollisionAlgorithm.cpp @@ -108,7 +108,7 @@ void UserCollisionAlgorithm::initPhysics() btVector3 maxAabb(10000,10000,10000); btOverlappingPairCache* broadphase = new btAxisSweep3(-maxAabb,maxAabb);//SimpleBroadphase(); - dispatcher->registerCollisionCreateFunc(SPHERE_SHAPE_PROXYTYPE,SPHERE_SHAPE_PROXYTYPE,new btSphereSphereCollisionAlgorithm::CreateFunc); + dispatcher->registerCollisionCreateFunc(GIMPACT_SHAPE_PROXYTYPE,GIMPACT_SHAPE_PROXYTYPE,new btSphereSphereCollisionAlgorithm::CreateFunc); m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase); diff --git a/Extras/GIMPACT/Doxyfile b/Extras/GIMPACT/Doxyfile new file mode 100644 index 000000000..bb5ab6289 --- /dev/null +++ b/Extras/GIMPACT/Doxyfile @@ -0,0 +1,267 @@ +# Doxyfile 1.4.4 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = GIMPACT +PROJECT_NUMBER = 0.0.1a +OUTPUT_DIRECTORY = docs +CREATE_SUBDIRS = YES +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = YES +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = "C:/Documents and Settings/Administrador/" +STRIP_FROM_INC_PATH = +SHORT_NAMES = YES +JAVADOC_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = YES +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_JAVA = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = YES +HIDE_UNDOC_MEMBERS = YES +HIDE_UNDOC_CLASSES = YES +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = NO +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = YES +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = NO +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = include/GIMPACT/gim_boxpruning.h \ + include/GIMPACT/gim_contact.h \ + include/GIMPACT/gim_geometry.h \ + include/GIMPACT/gim_math.h \ + include/GIMPACT/gim_memory.h \ + include/GIMPACT/gim_radixsort.h \ + include/GIMPACT/gim_tri_capsule_collision.h \ + include/GIMPACT/gim_tri_collision.h \ + include/GIMPACT/gim_tri_sphere_collision.h \ + include/GIMPACT/gim_trimesh.h \ + include/GIMPACT/gimpact.h +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox +RECURSIVE = NO +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +USE_HTAGS = NO +VERBATIM_HEADERS = NO +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = NO +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 1000 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/Extras/GIMPACT/GIMPACT-LICENSE-BSD.TXT b/Extras/GIMPACT/GIMPACT-LICENSE-BSD.TXT new file mode 100644 index 000000000..95545aac2 --- /dev/null +++ b/Extras/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/Extras/GIMPACT/GIMPACT-LICENSE-LGPL.TXT b/Extras/GIMPACT/GIMPACT-LICENSE-LGPL.TXT new file mode 100644 index 000000000..60b81560d --- /dev/null +++ b/Extras/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/Extras/GIMPACT/GIMPACT-LICENSE-ZLIB.TXT b/Extras/GIMPACT/GIMPACT-LICENSE-ZLIB.TXT new file mode 100644 index 000000000..616f33f7c --- /dev/null +++ b/Extras/GIMPACT/GIMPACT-LICENSE-ZLIB.TXT @@ -0,0 +1,23 @@ +GIMPACT : Geometric tools for VR. + +Copyright (c) 2006 , Francisco León. +All rights reserved. + + +This software is provided 'as-is', without any express or implied warranty. In no +event will the authors be held liable for any damages arising from the use of this +software. + +Permission is granted to anyone to use this software for any purpose, including commercial +applications, and to alter it and redistribute it freely, subject to the following +restrictions: + + 1. The origin of this software must not be misrepresented; you must not claim that + you wrote the original software. If you use this software in a product, an + acknowledgment in the product documentation would be appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source distribution. + diff --git a/Extras/GIMPACT/GIMPACT.cbp b/Extras/GIMPACT/GIMPACT.cbp new file mode 100644 index 000000000..ef5862608 --- /dev/null +++ b/Extras/GIMPACT/GIMPACT.cbp @@ -0,0 +1,208 @@ + + + + + + \ No newline at end of file diff --git a/Extras/GIMPACT/GIMPACT.depend b/Extras/GIMPACT/GIMPACT.depend new file mode 100644 index 000000000..822376870 --- /dev/null +++ b/Extras/GIMPACT/GIMPACT.depend @@ -0,0 +1,307 @@ +# depslib dependency file v1.0 +1159964131 source:c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\src\gim_contact.cpp + "GIMPACT/gim_contact.h" + + +1159989774 c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_contact.h + "GIMPACT/gim_geometry.h" + "GIMPACT/gim_radixsort.h" + +1159995618 c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_geometry.h + "GIMPACT/gim_math.h" + "GIMPACT/gim_tri_collision.h" + +1159971186 c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_math.h + + + +1159989774 c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_tri_collision.h + +1159989774 c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_radixsort.h + "GIMPACT/gim_memory.h" + +1159989774 c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_memory.h + "GIMPACT/gim_math.h" + + + +1159921899 source:c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\src\gim_math.cpp + "GIMPACT/gim_math.h" + "stdlib.h" + "time.h" + +1159964559 source:c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\src\gim_memory.cpp + "GIMPACT/gim_memory.h" + "stdlib.h" + "malloc.h" + +1159992522 source:c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\src\gim_trimesh.cpp + "GIMPACT/gim_trimesh.h" + +1159994630 c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_trimesh.h + "GIMPACT/gim_boxpruning.h" + "GIMPACT/gim_contact.h" + +1159989774 c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_boxpruning.h + "GIMPACT/gim_radixsort.h" + "GIMPACT/gim_geometry.h" + +1159928249 source:c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\src\gim_trimesh_trimesh_collision.cpp + "GIMPACT/gim_trimesh.h" + +1159992207 source:c:\libreriaswx\oldgammaleon_reloaded\gammaleon\source\gimpact\src\gim_boxpruning.cpp + "GIMPACT/gim_boxpruning.h" + "sglib.h" + +1160663612 source:c:\libreriaswx\physics\ode-0.7\gimpact\src\gim_trimesh_capsule_collision.cpp + "GIMPACT/gim_trimesh.h" + +1160668423 c:\libreriaswx\physics\ode-0.7\gimpact\include\gimpact\gim_trimesh.h + "GIMPACT/gim_boxpruning.h" + "GIMPACT/gim_contact.h" + +1160665573 c:\libreriaswx\physics\ode-0.7\gimpact\include\gimpact\gim_boxpruning.h + "GIMPACT/gim_radixsort.h" + "GIMPACT/gim_geometry.h" + +1159989774 c:\libreriaswx\physics\ode-0.7\gimpact\include\gimpact\gim_radixsort.h + "GIMPACT/gim_memory.h" + +1160666133 c:\libreriaswx\physics\ode-0.7\gimpact\include\gimpact\gim_memory.h + "GIMPACT/gim_math.h" + + + +1160664080 c:\libreriaswx\physics\ode-0.7\gimpact\include\gimpact\gim_math.h + + + +1160665531 c:\libreriaswx\physics\ode-0.7\gimpact\include\gimpact\gim_geometry.h + "GIMPACT/gim_math.h" + "GIMPACT/gim_tri_collision.h" + "GIMPACT/gim_tri_sphere_collision.h" + "GIMPACT/gim_tri_capsule_collision.h" + +1160666237 c:\libreriaswx\physics\ode-0.7\gimpact\include\gimpact\gim_tri_collision.h + +1160666277 c:\libreriaswx\physics\ode-0.7\gimpact\include\gimpact\gim_tri_sphere_collision.h + +1160663800 c:\libreriaswx\physics\ode-0.7\gimpact\include\gimpact\gim_tri_capsule_collision.h + "GIMPACT/gim_memory.h" + +1160663800 c:\libreriaswx\physics\ode-0.7\gimpact\include\gimpact\gim_contact.h + "GIMPACT/gim_geometry.h" + "GIMPACT/gim_radixsort.h" + +1160663612 source:c:\libreriaswx\physics\ode-0.7\gimpact\src\gim_contact.cpp + "GIMPACT/gim_contact.h" + + +1136910978 c:\libreriaswx\physics\ode-0.7\gimpact\include\sglib.h + + +1160663502 source:c:\libreriaswx\physics\ode-0.7\gimpact\src\gim_math.cpp + "GIMPACT/gim_math.h" + "stdlib.h" + "time.h" + +1160663502 source:c:\libreriaswx\physics\ode-0.7\gimpact\src\gim_memory.cpp + "GIMPACT/gim_memory.h" + "stdlib.h" + "malloc.h" + +1160663502 source:c:\libreriaswx\physics\ode-0.7\gimpact\src\gim_trimesh.cpp + "GIMPACT/gim_trimesh.h" + +1160663502 source:c:\libreriaswx\physics\ode-0.7\gimpact\src\gim_boxpruning.cpp + "GIMPACT/gim_boxpruning.h" + "sglib.h" + +1160663502 source:c:\libreriaswx\physics\ode-0.7\gimpact\src\gim_trimesh_ray_collision.cpp + "GIMPACT/gim_trimesh.h" + +1160663612 source:c:\libreriaswx\physics\ode-0.7\gimpact\src\gim_trimesh_sphere_collision.cpp + "GIMPACT/gim_trimesh.h" + +1160663503 source:c:\libreriaswx\physics\ode-0.7\gimpact\src\gim_trimesh_trimesh_collision.cpp + "GIMPACT/gim_trimesh.h" + +1160663612 source:c:\libreriaswx\physics\ode-0.7\gimpact\src\gimpact.cpp + "GIMPACT/gimpact.h" + +1160663925 c:\libreriaswx\physics\ode-0.7\gimpact\include\gimpact\gimpact.h + "GIMPACT/gim_trimesh.h" + +1161470699 source:c:\desarrollo\gimpact\src\gim_boxpruning.cpp + "GIMPACT/gim_boxpruning.h" + +1161561167 c:\desarrollo\gimpact\include\gimpact\gim_boxpruning.h + "GIMPACT/gim_radixsort.h" + "GIMPACT/gim_geometry.h" + +1161493754 c:\desarrollo\gimpact\include\gimpact\gim_radixsort.h + "GIMPACT/gim_memory.h" + +1161546016 c:\desarrollo\gimpact\include\gimpact\gim_memory.h + "GIMPACT/gim_math.h" + + + +1161407413 c:\desarrollo\gimpact\include\gimpact\gim_math.h + + + +1161493719 c:\desarrollo\gimpact\include\gimpact\gim_geometry.h + "GIMPACT/gim_math.h" + "GIMPACT/gim_tri_collision.h" + "GIMPACT/gim_tri_sphere_collision.h" + "GIMPACT/gim_tri_capsule_collision.h" + +1161535917 c:\desarrollo\gimpact\include\gimpact\gim_tri_collision.h + +1161407944 c:\desarrollo\gimpact\include\gimpact\gim_tri_sphere_collision.h + +1161407945 c:\desarrollo\gimpact\include\gimpact\gim_tri_capsule_collision.h + "GIMPACT/gim_memory.h" + +1161470699 source:c:\desarrollo\gimpact\src\gim_contact.cpp + "GIMPACT/gim_contact.h" + +1161493737 c:\desarrollo\gimpact\include\gimpact\gim_contact.h + "GIMPACT/gim_geometry.h" + "GIMPACT/gim_radixsort.h" + +1160663502 source:c:\desarrollo\gimpact\src\gim_math.cpp + "GIMPACT/gim_math.h" + "stdlib.h" + "time.h" + +1160663502 source:c:\desarrollo\gimpact\src\gim_memory.cpp + "GIMPACT/gim_memory.h" + "stdlib.h" + "malloc.h" + +1161546129 source:c:\desarrollo\gimpact\src\gim_tri_tri_overlap.cpp + "GIMPACT/gim_trimesh.h" + +1161493760 c:\desarrollo\gimpact\include\gimpact\gim_trimesh.h + "GIMPACT/gim_boxpruning.h" + "GIMPACT/gim_contact.h" + +1161543680 source:c:\desarrollo\gimpact\src\gim_trimesh.cpp + "GIMPACT/gim_trimesh.h" + +1160663612 source:c:\desarrollo\gimpact\src\gim_trimesh_capsule_collision.cpp + "GIMPACT/gim_trimesh.h" + +1160663502 source:c:\desarrollo\gimpact\src\gim_trimesh_ray_collision.cpp + "GIMPACT/gim_trimesh.h" + +1160663612 source:c:\desarrollo\gimpact\src\gim_trimesh_sphere_collision.cpp + "GIMPACT/gim_trimesh.h" + +1161545852 source:c:\desarrollo\gimpact\src\gim_trimesh_trimesh_collision.cpp + "GIMPACT/gim_trimesh.h" + +1160663612 source:c:\desarrollo\gimpact\src\gimpact.cpp + "GIMPACT/gimpact.h" + +1161488518 c:\desarrollo\gimpact\include\gimpact\gimpact.h + "GIMPACT/gim_trimesh.h" + +1163169405 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gim_trimesh_capsule_collision.cpp + "GIMPACT/gim_trimesh.h" + +1163156330 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_trimesh.h + "GIMPACT/gim_trimesh_data.h" + "GIMPACT/gim_vertex_buffer_util.h" + "GIMPACT/gim_contact.h" + +1163156330 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_trimesh_data.h + "GIMPACT/gim_boxpruning.h" + +1163169530 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_boxpruning.h + "GIMPACT/gim_radixsort.h" + "GIMPACT/gim_geometry.h" + +1163156180 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_radixsort.h + "GIMPACT/gim_memory.h" + +1163156168 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_memory.h + "GIMPACT/gim_math.h" + + + +1163169574 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_math.h + + + +1163169881 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_geometry.h + "GIMPACT/gim_math.h" + "GIMPACT/gim_box_collision.h" + "GIMPACT/gim_tri_collision.h" + "GIMPACT/gim_tri_sphere_collision.h" + "GIMPACT/gim_tri_capsule_collision.h" + +1163169574 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_box_collision.h + +1163156329 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_tri_collision.h + +1163156330 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_tri_sphere_collision.h + +1163156199 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_tri_capsule_collision.h + "GIMPACT/gim_memory.h" + +1163156330 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_vertex_buffer_util.h + "GIMPACT/gim_geometry.h" + "GIMPACT/gim_memory.h" + +1163168527 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gim_contact.h + "GIMPACT/gim_geometry.h" + "GIMPACT/gim_radixsort.h" + +1163156330 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gim_math.cpp + "GIMPACT/gim_math.h" + "stdlib.h" + "time.h" + +1163156330 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gim_memory.cpp + "GIMPACT/gim_memory.h" + "stdlib.h" + "malloc.h" + +1163156330 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gim_tri_tri_overlap.cpp + "GIMPACT/gim_trimesh.h" + +1163169405 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gim_trimesh.cpp + "GIMPACT/gim_trimesh.h" + "assert.h" + +1163156330 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gim_trimesh_data.cpp + "GIMPACT/gim_trimesh_data.h" + +1163156330 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gim_trimesh_ray_collision.cpp + "GIMPACT/gim_trimesh.h" + +1163169405 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gim_trimesh_sphere_collision.cpp + "GIMPACT/gim_trimesh.h" + +1163156330 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gim_trimesh_trimesh_collision.cpp + "GIMPACT/gim_trimesh.h" + +1163156330 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gim_vertex_buffer_util.cpp + "GIMPACT/gim_vertex_buffer_util.h" + +1163156328 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gimpact.cpp + "GIMPACT/gimpact.h" + +1163156330 c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\include\gimpact\gimpact.h + "GIMPACT/gim_trimesh.h" + +1163169629 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gim_contact.cpp + "GIMPACT/gim_contact.h" + +1163169723 source:c:\libreriaswx\gammaleon_reloaded\gammaleon\source\gimpact\src\gim_boxpruning.cpp + "GIMPACT/gim_boxpruning.h" + + diff --git a/Extras/GIMPACT/GIMPACT.layout b/Extras/GIMPACT/GIMPACT.layout new file mode 100644 index 000000000..7b3db8241 --- /dev/null +++ b/Extras/GIMPACT/GIMPACT.layout @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Extras/GIMPACT/include/GIMPACT/gim_box_collision.h b/Extras/GIMPACT/include/GIMPACT/gim_box_collision.h new file mode 100644 index 000000000..405e0a3da --- /dev/null +++ b/Extras/GIMPACT/include/GIMPACT/gim_box_collision.h @@ -0,0 +1,400 @@ +#ifndef GIM_BOX_COLLISION_H_INCLUDED +#define GIM_BOX_COLLISION_H_INCLUDED + +/*! \file gim_box_collision.h +\author Francisco León Nájera +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that 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, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + +/*! \defgroup BOUND_AABB_OPERATIONS +*/ +//! @{ + +//!Initializes an AABB +#define INVALIDATE_AABB(aabb) {\ + (aabb).minX = G_REAL_INFINITY;\ + (aabb).maxX = -G_REAL_INFINITY;\ + (aabb).minY = G_REAL_INFINITY;\ + (aabb).maxY = -G_REAL_INFINITY;\ + (aabb).minZ = G_REAL_INFINITY;\ + (aabb).maxZ = -G_REAL_INFINITY;\ +}\ + +#define AABB_GET_MIN(aabb,vmin) {\ + vmin[0] = (aabb).minX;\ + vmin[1] = (aabb).minY;\ + vmin[2] = (aabb).minZ;\ +}\ + +#define AABB_GET_MAX(aabb,vmax) {\ + vmax[0] = (aabb).maxX;\ + vmax[1] = (aabb).maxY;\ + vmax[2] = (aabb).maxZ;\ +}\ + +//!Copy boxes +#define AABB_COPY(dest_aabb,src_aabb)\ +{\ + (dest_aabb).minX = (src_aabb).minX;\ + (dest_aabb).maxX = (src_aabb).maxX;\ + (dest_aabb).minY = (src_aabb).minY;\ + (dest_aabb).maxY = (src_aabb).maxY;\ + (dest_aabb).minZ = (src_aabb).minZ;\ + (dest_aabb).maxZ = (src_aabb).maxZ;\ +}\ + +//! Computes an Axis aligned box from a triangle +#define COMPUTEAABB_FOR_TRIANGLE(aabb,V1,V2,V3) {\ + (aabb).minX = GIM_MIN3(V1[0],V2[0],V3[0]);\ + (aabb).maxX = GIM_MAX3(V1[0],V2[0],V3[0]);\ + (aabb).minY = GIM_MIN3(V1[1],V2[1],V3[1]);\ + (aabb).maxY = GIM_MAX3(V1[1],V2[1],V3[1]);\ + (aabb).minZ = GIM_MIN3(V1[2],V2[2],V3[2]);\ + (aabb).maxZ = GIM_MAX3(V1[2],V2[2],V3[2]);\ +}\ + +//! Apply a transform to an AABB +#define AABB_TRANSFORM(dest_box,source_box,mat4trans)\ +{\ + vec3f _vx,_vy,_vz;\ + float _vtemp[] = {(source_box.maxX-source_box.minX),(source_box.maxY-source_box.minY),(source_box.maxZ-source_box.minZ)};\ + MAT_GET_COL(mat4trans,_vx,0);\ + VEC_SCALE(_vx,_vtemp[0],_vx); \ + MAT_GET_COL(mat4trans,_vy,1);\ + VEC_SCALE(_vy,_vtemp[1],_vy); \ + MAT_GET_COL(mat4trans,_vz,2);\ + VEC_SCALE(_vz,_vtemp[2],_vz);\ + float _vtrans[] = {source_box.minX,source_box.minY,source_box.minZ}; \ + MAT_DOT_VEC_3X4(_vtemp,mat4trans,_vtrans);\ + dest_box.minX = dest_box.maxX = _vtemp[0];\ + dest_box.minY = dest_box.maxY = _vtemp[1];\ + dest_box.minZ = dest_box.maxZ = _vtemp[2]; \ + if(_vx[0]<0.0f) dest_box.minX += _vx[0]; else dest_box.maxX += _vx[0];\ + if(_vx[1]<0.0f) dest_box.minY += _vx[1]; else dest_box.maxY += _vx[1];\ + if(_vx[2]<0.0f) dest_box.minZ += _vx[2]; else dest_box.maxZ += _vx[2];\ + if(_vy[0]<0.0f) dest_box.minX += _vy[0]; else dest_box.maxX += _vy[0];\ + if(_vy[1]<0.0f) dest_box.minY += _vy[1]; else dest_box.maxY += _vy[1];\ + if(_vy[2]<0.0f) dest_box.minZ += _vy[2]; else dest_box.maxZ += _vy[2];\ + if(_vz[0]<0.0f) dest_box.minX += _vz[0]; else dest_box.maxX += _vz[0];\ + if(_vz[1]<0.0f) dest_box.minY += _vz[1]; else dest_box.maxY += _vz[1];\ + if(_vz[2]<0.0f) dest_box.minZ += _vz[2]; else dest_box.maxZ += _vz[2];\ +}\ + + +//! Merge two boxes to destaabb +#define MERGEBOXES(destaabb,aabb) {\ + (destaabb).minX = GIM_MIN((aabb).minX,(destaabb).minX);\ + (destaabb).minY = GIM_MIN((aabb).minY,(destaabb).minY);\ + (destaabb).minZ = GIM_MIN((aabb).minZ,(destaabb).minZ);\ + (destaabb).maxX = GIM_MAX((aabb).maxX,(destaabb).maxX);\ + (destaabb).maxY = GIM_MAX((aabb).maxY,(destaabb).maxY);\ + (destaabb).maxZ = GIM_MAX((aabb).maxZ,(destaabb).maxZ);\ +}\ + +//! Extends the box +#define AABB_POINT_EXTEND(destaabb,p) {\ + (destaabb).minX = GIM_MIN(p[0],(destaabb).minX);\ + (destaabb).maxX = GIM_MAX(p[0],(destaabb).maxX);\ + (destaabb).minY = GIM_MIN(p[1],(destaabb).minY);\ + (destaabb).maxY = GIM_MAX(p[1],(destaabb).maxY);\ + (destaabb).minZ = GIM_MIN(p[2],(destaabb).minZ);\ + (destaabb).maxZ = GIM_MAX(p[2],(destaabb).maxZ);\ +}\ + +//! Gets the center and the dimension of the AABB +#define AABB_GET_CENTER_EXTEND(aabb,center,extend)\ +{\ + extend[0] = (aabb.maxX - aabb.minX)*0.5f;\ + extend[1] = (aabb.maxY - aabb.minY)*0.5f;\ + extend[2] = (aabb.maxZ - aabb.minZ)*0.5f;\ + center[0] = aabb.minX + extend[0];\ + center[1] = aabb.minY + extend[1];\ + center[2] = aabb.minZ + extend[2];\ +}\ + +//! Finds the intersection box of two boxes +#define BOXINTERSECTION(aabb1, aabb2, iaabb) {\ + (iaabb).minX = GIM_MAX((aabb1).minX,(aabb2).minX);\ + (iaabb).minY = GIM_MAX((aabb1).minY,(aabb2).minY);\ + (iaabb).minZ = GIM_MAX((aabb1).minZ,(aabb2).minZ);\ + (iaabb).maxX = GIM_MIN((aabb1).maxX,(aabb2).maxX);\ + (iaabb).maxY = GIM_MIN((aabb1).maxY,(aabb2).maxY);\ + (iaabb).maxZ = GIM_MIN((aabb1).maxZ,(aabb2).maxZ);\ +}\ + +//! Determines if two aligned boxes do intersect +#define AABBCOLLISION(intersected,aabb1,aabb2) {\ + intersected = 1;\ + if ((aabb1).minX > (aabb2).maxX ||\ + (aabb1).maxX < (aabb2).minX ||\ + (aabb1).minY > (aabb2).maxY ||\ + (aabb1).maxY < (aabb2).minY ||\ + (aabb1).minZ > (aabb2).maxZ ||\ + (aabb1).maxZ < (aabb2).minZ )\ + {\ + intersected = 0;\ + }\ +}\ + +#define AXIS_INTERSECT(min,max, a, d,tfirst, tlast,is_intersected) {\ + if(GIM_IS_ZERO(d))\ + {\ + is_intersected = !(a < min || a > max);\ + }\ + else\ + {\ + GREAL a0, a1;\ + a0 = (min - a) / (d);\ + a1 = (max - a) / (d);\ + if(a0 > a1) GIM_SWAP_NUMBERS(a0, a1);\ + tfirst = GIM_MAX(a0, tfirst);\ + tlast = GIM_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;\ +}\ + +/*! \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 +*/ +inline int BOX_INTERSECTS_RAY_FAST(aabb3f & aabb, vec3f vorigin,vec3f vdir) +{ + vec3f extents,center; + AABB_GET_CENTER_EXTEND(aabb,center,extents); + + GREAL Dx = vorigin[0] - center[0]; + if(GIM_GREATER(Dx, extents[0]) && Dx*vdir[0]>=0.0f) return 0; + GREAL Dy = vorigin[1] - center[1]; + if(GIM_GREATER(Dy, extents[1]) && Dy*vdir[1]>=0.0f) return 0; + GREAL Dz = vorigin[2] - center[2]; + if(GIM_GREATER(Dz, extents[2]) && Dz*vdir[2]>=0.0f) return 0; + GREAL f; + f = vdir[1] * Dz - vdir[2] * Dy; + if(fabsf(f) > extents[1]*fabsf(vdir[2]) + extents[2]*fabsf(vdir[1])) return 0; + f = vdir[2] * Dx - vdir[0] * Dz; + if(fabsf(f) > extents[0]*fabsf(vdir[2]) + extents[2]*fabsf(vdir[0]))return 0; + f = vdir[0] * Dy - vdir[1] * Dx; + if(fabsf(f) > extents[0]*fabsf(vdir[1]) + extents[1]*fabsf(vdir[0]))return 0; + return 1; +} + +#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; \ +}\ + +#define BOX_PLANE_EPSILON 0.000001f + +/*! +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 + BOX_PLANE_EPSILON ) \ + { \ + classify = 0;/*In back of*/ \ + } \ + else \ + { \ + if(plane[3]+BOX_PLANE_EPSILON >=_fmin) \ + { \ + classify = 1;/*Spanning*/ \ + } \ + else \ + { \ + classify = 2;/*In front of*/ \ + } \ + } \ +}\ + +//! Class for transforming a model1 to the space of model0 +class GIM_BOX_BOX_TRANSFORM_CACHE +{ +public: + vec3f m_T1to0;//!< Transforms translation of model1 to model 0 + mat3f m_R1to0;//!< Transforms Rotation of model1 to model 0, equal to R0' * R1 + mat3f m_AR;//!< Absolute value of m_R1to0 + + GIM_BOX_BOX_TRANSFORM_CACHE(mat4f trans1_to_0) + { + COPY_MATRIX_3X3(m_R1to0,trans1_to_0) + MAT_GET_TRANSLATION(trans1_to_0,m_T1to0) + int i,j; + + for(i=0;i<3;i++) + { + for(j=0;j<3;j++ ) + { + m_AR[i][j] = 1e-6f + fabsf(m_R1to0[i][j]); + } + } + } +}; + + + +inline int gim_box_box_overlap_trans_conservative(aabb3f * box0,aabb3f * box1,mat4f trans1_to_0) +{ + aabb3f pbox1; + AABB_TRANSFORM(pbox1,(*box1),trans1_to_0); + int intersected; + AABBCOLLISION(intersected,pbox1,(*box0)); + return intersected; +} + +inline int gim_box_box_overlap_cache(aabb3f * box0,aabb3f * box1,GIM_BOX_BOX_TRANSFORM_CACHE * boxcache, bool fulltest) +{ + //Taken from OPCODE + vec3f ea,eb;//extends + vec3f ca,cb;//extends + AABB_GET_CENTER_EXTEND((*box0),ca,ea); + AABB_GET_CENTER_EXTEND((*box1),cb,eb); + + + vec3f T; + + GREAL t,t2; + int i; + + // Class I : A's basis vectors + for(i=0;i<3;i++) + { + T[i] = MAT_DOT_ROW(boxcache->m_R1to0,cb,i) + boxcache->m_T1to0[i] - ca[i]; + t = MAT_DOT_ROW(boxcache->m_AR,eb,i) + ea[i]; + if(GIM_GREATER(T[i], t)) return 0; + } + // Class II : B's basis vectors + for(i=0;i<3;i++) + { + t = MAT_DOT_COL(boxcache->m_R1to0,T,i); + t2 = MAT_DOT_COL(boxcache->m_AR,ea,i) + eb[i]; + if(GIM_GREATER(t,t2)) return 0; + } + // Class III : 9 cross products + if(fulltest) + { + int j,m,n,o,p,q,r; + for(i=0;i<3;i++) + { + m = (i+1)%3; + n = (i+2)%3; + o = i==0?1:0; + p = i==2?1:2; + for(j=0;j<3;j++) + { + q = j==2?1:2; + r = j==0?1:0; + t = T[n]*boxcache->m_R1to0[m][j] - T[m]*boxcache->m_R1to0[n][j]; + t2 = ea[o]*boxcache->m_AR[p][j] + ea[p]*boxcache->m_AR[o][j] + + eb[r]*boxcache->m_AR[i][q] + eb[q]*boxcache->m_AR[i][r]; + if(GIM_GREATER(t,t2)) return 0; + } + } + + } + return 1; +} + + +/// conservative test for overlap between triangle and aabb +inline int gim_box_collide_triangle(vec3f p1, vec3f p2, vec3f p3,aabb3f & box) +{ + if(GIM_MIN3(p1[0],p2[0],p3[0])> box.maxX) return 0; + if(GIM_MAX3(p1[0],p2[0],p3[0])< box.minX) return 0; + + if(GIM_MIN3(p1[2],p2[2],p3[2])> box.maxZ) return 0; + if(GIM_MAX3(p1[2],p2[2],p3[2])< box.minZ) return 0; + + if(GIM_MIN3(p1[1],p2[1],p3[1])> box.maxY) return 0; + if(GIM_MAX3(p1[1],p2[1],p3[1])< box.minY) return 0; + + vec4f plane; + TRIANGLE_PLANE_FAST(p1,p2,p3,plane); + char classify; + PLANE_CLASSIFY_BOX(plane,box,classify); + + if(classify != 1) return 0; + + return 1; +} + + +//! @} + +#endif // GIM_BOX_COLLISION_H_INCLUDED diff --git a/Extras/GIMPACT/include/GIMPACT/gim_boxpruning.h b/Extras/GIMPACT/include/GIMPACT/gim_boxpruning.h new file mode 100644 index 000000000..453b390fa --- /dev/null +++ b/Extras/GIMPACT/include/GIMPACT/gim_boxpruning.h @@ -0,0 +1,484 @@ +#ifndef GIM_BOXPRUNING_H_INCLUDED +#define GIM_BOXPRUNING_H_INCLUDED + +/*! \file gim_boxpruning.h +\author Francisco León Nájera +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that 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, GIMPACT-LICENSE-ZLIB.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 + +/** +If 1, then the system manages objects that are far away beyond the limits of the world [-1638,1638.0f] +*/ +#define CLAMP_FURTHER_OBJECTS 0 + +//! 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 = GIM_CLAMP(vx,-MAX_AABB_SIZE,MAX_AABB_SIZE);\ + GREAL _cz = GIM_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 = GIM_CLAMP(vx,-MAX_AABB_SIZE,MAX_AABB_SIZE);\ + GREAL _cz = GIM_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;\ +}\ + + +#if (CLAMP_FURTHER_OBJECTS == 1) + +#define GIM_CONVERT_VEC3F_GUINT_XZ(vx,vz,uint_key) GIM_CONVERT_VEC3F_GUINT_XZ_CLAMPED(vx,vz,uint_key) + +#define GIM_CONVERT_VEC3F_GUINT_XZ_UPPER(vx,vz,uint_key) GIM_CONVERT_VEC3F_GUINT_XZ_UPPER_CLAMPED(vx,vz,uint_key) + +#else + +//! 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;\ +}\ + + +#endif + + + +//! @} + +/*! \defgroup HIERARCHY_BOX_PRUNNING + +\brief +Tools for find overlapping objects on a scenary, by using Bounding Volume Trees. +*/ +//! @{ + +struct GIM_AABB_DATA +{ + aabb3f m_aabb;//!< Bounding volume + GUINT m_data; +}; + +#define AABB_DATA_COPY(dest_data,src_data)\ +{\ + AABB_COPY(dest_data.m_aabb,src_data.m_aabb);\ + dest_data.m_data = src_data.m_data;\ +}\ + +//! Node Structure for trees +struct GIM_AABB_TREE_NODE +{ + GIM_AABB_TREE_NODE * m_left;//!< Left subtree + GIM_AABB_TREE_NODE * m_right;//!< Right subtree + GUINT m_escapeIndex;//!< Scape index for traversing + GIM_AABB_DATA m_data; + + GIM_AABB_TREE_NODE() + { + m_left = 0; + m_right = 0; + m_escapeIndex = 0; + } + + bool is_leaf_node() + { + return (!m_left && !m_right); + } +}; + +//! AABB tree +struct GIM_AABB_TREE +{ + GIM_AABB_TREE_NODE * m_node_array; + GUINT m_num_nodes; + GUINT m_nodes_array_size; + GIM_AABB_TREE_NODE * m_root_node; + + void clear_nodes() + { + if(m_node_array != 0) gim_free(m_node_array,0); + m_num_nodes = 0; + m_root_node = 0; + m_nodes_array_size = 0; + } + + GIM_AABB_TREE() + { + m_node_array = 0; + m_num_nodes = 0; + m_root_node = 0; + m_nodes_array_size = 0; + } + + ~GIM_AABB_TREE() + { + clear_nodes(); + } +}; + + +//! Creates and intializes a GIM_AABB_TREE from an array of boxes +/*! +\param newtree Tree for be build +\param boxarray A GIM_AABB_DATA array for sorting, must be allocated by user. +\param boxcount box count. +*/ +void gim_aabbtree_create(GIM_AABB_TREE * newtree, GIM_AABB_DATA * boxarray, GUINT boxcount); + +//! Destroy an GIM_AABB_TREE. +void gim_aabbtree_destroy(GIM_AABB_TREE * tree); + +//! Finds intersections between a box and a tree. Return the indices from the colliding nodes of the tree +/*! +\pre aabbtree must be initialized. +\param test_aabb Box for collision query +\param aabbtree Tree of boxes. +\param collided Array of GUINT elements which corresponds to the index of the collided node in the m_nodes_array menber. Must be initialized before (Reserve size ~ 100) +*/ +void gim_aabbtree_box_collision_get_nodes(aabb3f *test_aabb, GIM_AABB_TREE * aabbtree, GDYNAMIC_ARRAY * collided); + + +//! Finds intersections between a box and a tree. Return the data index from the colliding leaf boxes of the tree +/*! +\pre aabbtree must be initialized. +\param test_aabb Box for collision query +\param aabbtree Tree of boxes. +\param collided Array of GUINT elements which corresponds to the data index in the leafs. Must be initialized before (Reserve size ~ 100) +*/ +void gim_aabbtree_box_collision(aabb3f *test_aabb, GIM_AABB_TREE * aabbtree, GDYNAMIC_ARRAY * collided); + +//! Finds intersections between a box and a tree. Return the colliding boxes of the set +/*! +\param vorigin Origin point of ray. +\param vdir Direction vector of ray. +\param tmax Max distance param for ray. +\param aabbtree Set of boxes. +\param collided Array of GUINT elements, indices of boxes. Must be initialized before (Reserve size ~ 100) +*/ +void gim_aabbtree_ray_collision(vec3f vorigin,vec3f vdir, GREAL tmax, GIM_AABB_TREE * aabbtree, GDYNAMIC_ARRAY * collided); + + + +//! Collides two transformed box trees. Returns a list of the data (m_data) from the overlapping pairs of box leafs, each leaf data belongs to a different tree. +/*! +\param aabbtree1 Must be updated. +\param aabbtree2 Must be updated. +\param trans1inverse Inverse Transformation of aabbtree1. +\param trans2 Transformation of aabbtree2. +\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100) +*/ +void gim_aabbtree_bipartite_intersections_trans(GIM_AABB_TREE * aabbtree1, GIM_AABB_TREE * aabbtree2, +mat4f trans1,mat4f trans1inverse, +mat4f trans2,mat4f trans2inverse, + GDYNAMIC_ARRAY * collision_pairs); + + +//! Collides an aabbset and aabbtree. Returns a pair list of overlapping pairs. The first element of the pair belongs to aabbset and the second belongs to aabbtree. +/*! +\param aabbset Must be updated. +\param aabbtree Must be initialized. +\param trans_aabbtree Transformation of the aabbtree. +\param inv_trans_aabbtree Inverse Transformation of the aabbtree. +\param collision_pairs Array of GIM_PAIR elements. The first element of the pair belongs to aabbset and the second belongs to aabbtree having the m_data value from leaf. Must be initialized before (Reserve size ~ 100) +*/ +void gim_aabbset_aabbtree_intersections_trans(GIM_AABB_SET * aabbset, GIM_AABB_TREE * aabbtree, mat4f trans_aabbtree, mat4f inv_trans_aabbtree, GDYNAMIC_ARRAY * collision_pairs); + + + + +//! @} +#endif // GIM_BOXPRUNING_H_INCLUDED diff --git a/Extras/GIMPACT/include/GIMPACT/gim_contact.h b/Extras/GIMPACT/include/GIMPACT/gim_contact.h new file mode 100644 index 000000000..03ba62aff --- /dev/null +++ b/Extras/GIMPACT/include/GIMPACT/gim_contact.h @@ -0,0 +1,121 @@ +#ifndef GIM_CONTACT_H_INCLUDED +#define GIM_CONTACT_H_INCLUDED + +/*! \file gim_contact.h +\author Francisco León Nájera +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that 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, GIMPACT-LICENSE-ZLIB.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 +
+ +*/ +//! @{ + +/** +Configuration var for applying interpolation of contact normals +*/ +#define NORMAL_CONTACT_AVERAGE 1 + +/// 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,64) + +#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/Extras/GIMPACT/include/GIMPACT/gim_geometry.h b/Extras/GIMPACT/include/GIMPACT/gim_geometry.h new file mode 100644 index 000000000..e91bbcfea --- /dev/null +++ b/Extras/GIMPACT/include/GIMPACT/gim_geometry.h @@ -0,0 +1,1892 @@ +#ifndef GIM_VECTOR_H_INCLUDED +#define GIM_VECTOR_H_INCLUDED + +/*! \file gim_geometry.h +\author Francisco León Nájera +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that 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, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + + +#include "GIMPACT/gim_math.h" + +/*! \defgroup GEOMETRIC_TYPES +\brief +Basic types and constants for geometry +*/ +//! @{ + +//! Short Integer vector 2D +typedef GSHORT vec2s[2]; +//! Integer vector 3D +typedef GSHORT vec3s[3]; +//! Integer vector 4D +typedef GSHORT vec4s[4]; + +//! Short Integer vector 2D +typedef GUSHORT vec2us[2]; +//! Integer vector 3D +typedef GUSHORT vec3us[3]; +//! Integer vector 4D +typedef GUSHORT vec4us[4]; + +//! Integer vector 2D +typedef GINT vec2i[2]; +//! Integer vector 3D +typedef GINT vec3i[3]; +//! Integer vector 4D +typedef GINT vec4i[4]; + +//! Unsigned Integer vector 2D +typedef GUINT vec2ui[2]; +//! Unsigned Integer vector 3D +typedef GUINT vec3ui[3]; +//! Unsigned Integer vector 4D +typedef GUINT vec4ui[4]; + +//! Float vector 2D +typedef GREAL vec2f[2]; +//! Float vector 3D +typedef GREAL vec3f[3]; +//! Float vector 4D +typedef GREAL vec4f[4]; + +//! Double vector 2D +typedef GREAL2 vec2d[2]; +//! Float vector 3D +typedef GREAL2 vec3d[3]; +//! Float vector 4D +typedef GREAL2 vec4d[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(lenA[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; \ + }\ + } \ +}\ + + +//! Finds the bigger cartesian coordinate from a vector +#define VEC_MAYOR_COORD(vec, maxc)\ +{\ + maxc = fabs(vec[0])>fabs(vec[1])?(fabs(vec[0])>fabs(vec[2])?0:2):(fabs(vec[1])>fabs(vec[2])?1:2);\ +}\ + + +//! @} + + +/*! \defgroup MATRIX_OPERATIONS +Operations for matrices : mat2f, mat3f and mat4f +*/ +//! @{ + +/// initialize matrix +#define IDENTIFY_MATRIX_3X3(m) \ +{ \ + m[0][0] = 1.0; \ + m[0][1] = 0.0; \ + m[0][2] = 0.0; \ + \ + m[1][0] = 0.0; \ + m[1][1] = 1.0; \ + m[1][2] = 0.0; \ + \ + m[2][0] = 0.0; \ + m[2][1] = 0.0; \ + m[2][2] = 1.0; \ +}\ + +/*! initialize matrix */ +#define IDENTIFY_MATRIX_4X4(m) \ +{ \ + m[0][0] = 1.0; \ + m[0][1] = 0.0; \ + m[0][2] = 0.0; \ + m[0][3] = 0.0; \ + \ + m[1][0] = 0.0; \ + m[1][1] = 1.0; \ + m[1][2] = 0.0; \ + m[1][3] = 0.0; \ + \ + m[2][0] = 0.0; \ + m[2][1] = 0.0; \ + m[2][2] = 1.0; \ + m[2][3] = 0.0; \ + \ + m[3][0] = 0.0; \ + m[3][1] = 0.0; \ + m[3][2] = 0.0; \ + m[3][3] = 1.0; \ +}\ + +/*! initialize matrix */ +#define ZERO_MATRIX_4X4(m) \ +{ \ + m[0][0] = 0.0; \ + m[0][1] = 0.0; \ + m[0][2] = 0.0; \ + m[0][3] = 0.0; \ + \ + m[1][0] = 0.0; \ + m[1][1] = 0.0; \ + m[1][2] = 0.0; \ + m[1][3] = 0.0; \ + \ + m[2][0] = 0.0; \ + m[2][1] = 0.0; \ + m[2][2] = 0.0; \ + m[2][3] = 0.0; \ + \ + m[3][0] = 0.0; \ + m[3][1] = 0.0; \ + m[3][2] = 0.0; \ + m[3][3] = 0.0; \ +}\ + +/*! matrix rotation X */ +#define ROTX_CS(m,cosine,sine) \ +{ \ + /* rotation about the x-axis */ \ + \ + m[0][0] = 1.0; \ + m[0][1] = 0.0; \ + m[0][2] = 0.0; \ + m[0][3] = 0.0; \ + \ + m[1][0] = 0.0; \ + m[1][1] = (cosine); \ + m[1][2] = (sine); \ + m[1][3] = 0.0; \ + \ + m[2][0] = 0.0; \ + m[2][1] = -(sine); \ + m[2][2] = (cosine); \ + m[2][3] = 0.0; \ + \ + m[3][0] = 0.0; \ + m[3][1] = 0.0; \ + m[3][2] = 0.0; \ + m[3][3] = 1.0; \ +}\ + +/*! matrix rotation Y */ +#define ROTY_CS(m,cosine,sine) \ +{ \ + /* rotation about the y-axis */ \ + \ + m[0][0] = (cosine); \ + m[0][1] = 0.0; \ + m[0][2] = -(sine); \ + m[0][3] = 0.0; \ + \ + m[1][0] = 0.0; \ + m[1][1] = 1.0; \ + m[1][2] = 0.0; \ + m[1][3] = 0.0; \ + \ + m[2][0] = (sine); \ + m[2][1] = 0.0; \ + m[2][2] = (cosine); \ + m[2][3] = 0.0; \ + \ + m[3][0] = 0.0; \ + m[3][1] = 0.0; \ + m[3][2] = 0.0; \ + m[3][3] = 1.0; \ +}\ + +/*! matrix rotation Z */ +#define ROTZ_CS(m,cosine,sine) \ +{ \ + /* rotation about the z-axis */ \ + \ + m[0][0] = (cosine); \ + m[0][1] = (sine); \ + m[0][2] = 0.0; \ + m[0][3] = 0.0; \ + \ + m[1][0] = -(sine); \ + m[1][1] = (cosine); \ + m[1][2] = 0.0; \ + m[1][3] = 0.0; \ + \ + m[2][0] = 0.0; \ + m[2][1] = 0.0; \ + m[2][2] = 1.0; \ + m[2][3] = 0.0; \ + \ + m[3][0] = 0.0; \ + m[3][1] = 0.0; \ + m[3][2] = 0.0; \ + m[3][3] = 1.0; \ +}\ + +/*! matrix copy */ +#define COPY_MATRIX_2X2(b,a) \ +{ \ + b[0][0] = a[0][0]; \ + b[0][1] = a[0][1]; \ + \ + b[1][0] = a[1][0]; \ + b[1][1] = a[1][1]; \ + \ +}\ + + +/*! matrix copy */ +#define COPY_MATRIX_2X3(b,a) \ +{ \ + b[0][0] = a[0][0]; \ + b[0][1] = a[0][1]; \ + b[0][2] = a[0][2]; \ + \ + b[1][0] = a[1][0]; \ + b[1][1] = a[1][1]; \ + b[1][2] = a[1][2]; \ +}\ + + +/*! matrix copy */ +#define COPY_MATRIX_3X3(b,a) \ +{ \ + b[0][0] = a[0][0]; \ + b[0][1] = a[0][1]; \ + b[0][2] = a[0][2]; \ + \ + b[1][0] = a[1][0]; \ + b[1][1] = a[1][1]; \ + b[1][2] = a[1][2]; \ + \ + b[2][0] = a[2][0]; \ + b[2][1] = a[2][1]; \ + b[2][2] = a[2][2]; \ +}\ + + +/*! matrix copy */ +#define COPY_MATRIX_4X4(b,a) \ +{ \ + b[0][0] = a[0][0]; \ + b[0][1] = a[0][1]; \ + b[0][2] = a[0][2]; \ + b[0][3] = a[0][3]; \ + \ + b[1][0] = a[1][0]; \ + b[1][1] = a[1][1]; \ + b[1][2] = a[1][2]; \ + b[1][3] = a[1][3]; \ + \ + b[2][0] = a[2][0]; \ + b[2][1] = a[2][1]; \ + b[2][2] = a[2][2]; \ + b[2][3] = a[2][3]; \ + \ + b[3][0] = a[3][0]; \ + b[3][1] = a[3][1]; \ + b[3][2] = a[3][2]; \ + b[3][3] = a[3][3]; \ +}\ + + +/*! matrix transpose */ +#define TRANSPOSE_MATRIX_2X2(b,a) \ +{ \ + b[0][0] = a[0][0]; \ + b[0][1] = a[1][0]; \ + \ + b[1][0] = a[0][1]; \ + b[1][1] = a[1][1]; \ +}\ + + +/*! matrix transpose */ +#define TRANSPOSE_MATRIX_3X3(b,a) \ +{ \ + b[0][0] = a[0][0]; \ + b[0][1] = a[1][0]; \ + b[0][2] = a[2][0]; \ + \ + b[1][0] = a[0][1]; \ + b[1][1] = a[1][1]; \ + b[1][2] = a[2][1]; \ + \ + b[2][0] = a[0][2]; \ + b[2][1] = a[1][2]; \ + b[2][2] = a[2][2]; \ +}\ + + +/*! matrix transpose */ +#define TRANSPOSE_MATRIX_4X4(b,a) \ +{ \ + b[0][0] = a[0][0]; \ + b[0][1] = a[1][0]; \ + b[0][2] = a[2][0]; \ + b[0][3] = a[3][0]; \ + \ + b[1][0] = a[0][1]; \ + b[1][1] = a[1][1]; \ + b[1][2] = a[2][1]; \ + b[1][3] = a[3][1]; \ + \ + b[2][0] = a[0][2]; \ + b[2][1] = a[1][2]; \ + b[2][2] = a[2][2]; \ + b[2][3] = a[3][2]; \ + \ + b[3][0] = a[0][3]; \ + b[3][1] = a[1][3]; \ + b[3][2] = a[2][3]; \ + b[3][3] = a[3][3]; \ +}\ + + +/*! multiply matrix by scalar */ +#define SCALE_MATRIX_2X2(b,s,a) \ +{ \ + b[0][0] = (s) * a[0][0]; \ + b[0][1] = (s) * a[0][1]; \ + \ + b[1][0] = (s) * a[1][0]; \ + b[1][1] = (s) * a[1][1]; \ +}\ + + +/*! multiply matrix by scalar */ +#define SCALE_MATRIX_3X3(b,s,a) \ +{ \ + b[0][0] = (s) * a[0][0]; \ + b[0][1] = (s) * a[0][1]; \ + b[0][2] = (s) * a[0][2]; \ + \ + b[1][0] = (s) * a[1][0]; \ + b[1][1] = (s) * a[1][1]; \ + b[1][2] = (s) * a[1][2]; \ + \ + b[2][0] = (s) * a[2][0]; \ + b[2][1] = (s) * a[2][1]; \ + b[2][2] = (s) * a[2][2]; \ +}\ + + +/*! multiply matrix by scalar */ +#define SCALE_MATRIX_4X4(b,s,a) \ +{ \ + b[0][0] = (s) * a[0][0]; \ + b[0][1] = (s) * a[0][1]; \ + b[0][2] = (s) * a[0][2]; \ + b[0][3] = (s) * a[0][3]; \ + \ + b[1][0] = (s) * a[1][0]; \ + b[1][1] = (s) * a[1][1]; \ + b[1][2] = (s) * a[1][2]; \ + b[1][3] = (s) * a[1][3]; \ + \ + b[2][0] = (s) * a[2][0]; \ + b[2][1] = (s) * a[2][1]; \ + b[2][2] = (s) * a[2][2]; \ + b[2][3] = (s) * a[2][3]; \ + \ + b[3][0] = s * a[3][0]; \ + b[3][1] = s * a[3][1]; \ + b[3][2] = s * a[3][2]; \ + b[3][3] = s * a[3][3]; \ +}\ + + +/*! multiply matrix by scalar */ +#define SCALE_VEC_MATRIX_2X2(b,svec,a) \ +{ \ + b[0][0] = svec[0] * a[0][0]; \ + b[0][1] = svec[0] * a[0][1]; \ + \ + b[1][0] = svec[1] * a[1][0]; \ + b[1][1] = svec[1] * a[1][1]; \ +}\ + + +/*! multiply matrix by scalar */ +#define SCALE_VEC_MATRIX_3X3(b,svec,a) \ +{ \ + b[0][0] = svec[0] * a[0][0]; \ + b[0][1] = svec[0] * a[0][1]; \ + b[0][2] = svec[0] * a[0][2]; \ + \ + b[1][0] = svec[1] * a[1][0]; \ + b[1][1] = svec[1] * a[1][1]; \ + b[1][2] = svec[1] * a[1][2]; \ + \ + b[2][0] = svec[2] * a[2][0]; \ + b[2][1] = svec[2] * a[2][1]; \ + b[2][2] = svec[2] * a[2][2]; \ +}\ + + +/*! multiply matrix by scalar */ +#define SCALE_VEC_MATRIX_4X4(b,svec,a) \ +{ \ + b[0][0] = svec[0] * a[0][0]; \ + b[0][1] = svec[0] * a[0][1]; \ + b[0][2] = svec[0] * a[0][2]; \ + b[0][3] = svec[0] * a[0][3]; \ + \ + b[1][0] = svec[1] * a[1][0]; \ + b[1][1] = svec[1] * a[1][1]; \ + b[1][2] = svec[1] * a[1][2]; \ + b[1][3] = svec[1] * a[1][3]; \ + \ + b[2][0] = svec[2] * a[2][0]; \ + b[2][1] = svec[2] * a[2][1]; \ + b[2][2] = svec[2] * a[2][2]; \ + b[2][3] = svec[2] * a[2][3]; \ + \ + b[3][0] = svec[3] * a[3][0]; \ + b[3][1] = svec[3] * a[3][1]; \ + b[3][2] = svec[3] * a[3][2]; \ + b[3][3] = svec[3] * a[3][3]; \ +}\ + + +/*! multiply matrix by scalar */ +#define ACCUM_SCALE_MATRIX_2X2(b,s,a) \ +{ \ + b[0][0] += (s) * a[0][0]; \ + b[0][1] += (s) * a[0][1]; \ + \ + b[1][0] += (s) * a[1][0]; \ + b[1][1] += (s) * a[1][1]; \ +}\ + + +/*! multiply matrix by scalar */ +#define ACCUM_SCALE_MATRIX_3X3(b,s,a) \ +{ \ + b[0][0] += (s) * a[0][0]; \ + b[0][1] += (s) * a[0][1]; \ + b[0][2] += (s) * a[0][2]; \ + \ + b[1][0] += (s) * a[1][0]; \ + b[1][1] += (s) * a[1][1]; \ + b[1][2] += (s) * a[1][2]; \ + \ + b[2][0] += (s) * a[2][0]; \ + b[2][1] += (s) * a[2][1]; \ + b[2][2] += (s) * a[2][2]; \ +}\ + + +/*! multiply matrix by scalar */ +#define ACCUM_SCALE_MATRIX_4X4(b,s,a) \ +{ \ + b[0][0] += (s) * a[0][0]; \ + b[0][1] += (s) * a[0][1]; \ + b[0][2] += (s) * a[0][2]; \ + b[0][3] += (s) * a[0][3]; \ + \ + b[1][0] += (s) * a[1][0]; \ + b[1][1] += (s) * a[1][1]; \ + b[1][2] += (s) * a[1][2]; \ + b[1][3] += (s) * a[1][3]; \ + \ + b[2][0] += (s) * a[2][0]; \ + b[2][1] += (s) * a[2][1]; \ + b[2][2] += (s) * a[2][2]; \ + b[2][3] += (s) * a[2][3]; \ + \ + b[3][0] += (s) * a[3][0]; \ + b[3][1] += (s) * a[3][1]; \ + b[3][2] += (s) * a[3][2]; \ + b[3][3] += (s) * a[3][3]; \ +}\ + +/*! matrix product */ +/*! c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/ +#define MATRIX_PRODUCT_2X2(c,a,b) \ +{ \ + c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]; \ + c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]; \ + \ + c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]; \ + c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]; \ + \ +}\ + +/*! matrix product */ +/*! c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/ +#define MATRIX_PRODUCT_3X3(c,a,b) \ +{ \ + c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]+a[0][2]*b[2][0]; \ + c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]+a[0][2]*b[2][1]; \ + c[0][2] = a[0][0]*b[0][2]+a[0][1]*b[1][2]+a[0][2]*b[2][2]; \ + \ + c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]+a[1][2]*b[2][0]; \ + c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]+a[1][2]*b[2][1]; \ + c[1][2] = a[1][0]*b[0][2]+a[1][1]*b[1][2]+a[1][2]*b[2][2]; \ + \ + c[2][0] = a[2][0]*b[0][0]+a[2][1]*b[1][0]+a[2][2]*b[2][0]; \ + c[2][1] = a[2][0]*b[0][1]+a[2][1]*b[1][1]+a[2][2]*b[2][1]; \ + c[2][2] = a[2][0]*b[0][2]+a[2][1]*b[1][2]+a[2][2]*b[2][2]; \ +}\ + + +/*! matrix product */ +/*! c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/ +#define MATRIX_PRODUCT_4X4(c,a,b) \ +{ \ + c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]+a[0][2]*b[2][0]+a[0][3]*b[3][0];\ + c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]+a[0][2]*b[2][1]+a[0][3]*b[3][1];\ + c[0][2] = a[0][0]*b[0][2]+a[0][1]*b[1][2]+a[0][2]*b[2][2]+a[0][3]*b[3][2];\ + c[0][3] = a[0][0]*b[0][3]+a[0][1]*b[1][3]+a[0][2]*b[2][3]+a[0][3]*b[3][3];\ + \ + c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]+a[1][2]*b[2][0]+a[1][3]*b[3][0];\ + c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]+a[1][2]*b[2][1]+a[1][3]*b[3][1];\ + c[1][2] = a[1][0]*b[0][2]+a[1][1]*b[1][2]+a[1][2]*b[2][2]+a[1][3]*b[3][2];\ + c[1][3] = a[1][0]*b[0][3]+a[1][1]*b[1][3]+a[1][2]*b[2][3]+a[1][3]*b[3][3];\ + \ + c[2][0] = a[2][0]*b[0][0]+a[2][1]*b[1][0]+a[2][2]*b[2][0]+a[2][3]*b[3][0];\ + c[2][1] = a[2][0]*b[0][1]+a[2][1]*b[1][1]+a[2][2]*b[2][1]+a[2][3]*b[3][1];\ + c[2][2] = a[2][0]*b[0][2]+a[2][1]*b[1][2]+a[2][2]*b[2][2]+a[2][3]*b[3][2];\ + c[2][3] = a[2][0]*b[0][3]+a[2][1]*b[1][3]+a[2][2]*b[2][3]+a[2][3]*b[3][3];\ + \ + c[3][0] = a[3][0]*b[0][0]+a[3][1]*b[1][0]+a[3][2]*b[2][0]+a[3][3]*b[3][0];\ + c[3][1] = a[3][0]*b[0][1]+a[3][1]*b[1][1]+a[3][2]*b[2][1]+a[3][3]*b[3][1];\ + c[3][2] = a[3][0]*b[0][2]+a[3][1]*b[1][2]+a[3][2]*b[2][2]+a[3][3]*b[3][2];\ + c[3][3] = a[3][0]*b[0][3]+a[3][1]*b[1][3]+a[3][2]*b[2][3]+a[3][3]*b[3][3];\ +}\ + + +/*! matrix times vector */ +#define MAT_DOT_VEC_2X2(p,m,v) \ +{ \ + p[0] = m[0][0]*v[0] + m[0][1]*v[1]; \ + p[1] = m[1][0]*v[0] + m[1][1]*v[1]; \ +}\ + + +/*! matrix times vector */ +#define MAT_DOT_VEC_3X3(p,m,v) \ +{ \ + p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2]; \ + p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2]; \ + p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2]; \ +}\ + + +/*! matrix times vector +v is a vec4f +*/ +#define MAT_DOT_VEC_4X4(p,m,v) \ +{ \ + p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2] + m[0][3]*v[3]; \ + p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2] + m[1][3]*v[3]; \ + p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2] + m[2][3]*v[3]; \ + p[3] = m[3][0]*v[0] + m[3][1]*v[1] + m[3][2]*v[2] + m[3][3]*v[3]; \ +}\ + +/*! matrix times vector +v is a vec3f +and m is a mat4f
+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) \ +{ \ + GREAL len; \ + \ + /* do nothing if off-diagonals are zero and diagonals are \ + * equal */ \ + if ((m[0][1] != 0.0) || (m[1][0] != 0.0) || (m[0][0] != m[1][1])) { \ + p[0] = m[1][1]*v[0] - m[1][0]*v[1]; \ + p[1] = - m[0][1]*v[0] + m[0][0]*v[1]; \ + \ + len = p[0]*p[0] + p[1]*p[1]; \ + GIM_INV_SQRT(len,len); \ + p[0] *= len; \ + p[1] *= len; \ + } else { \ + VEC_COPY_2 (p, v); \ + } \ +}\ + + +/** outer product of vector times vector transpose + * + * The outer product of vector v and vector transpose t yeilds + * dyadic matrix m. + */ +#define OUTER_PRODUCT_2X2(m,v,t) \ +{ \ + m[0][0] = v[0] * t[0]; \ + m[0][1] = v[0] * t[1]; \ + \ + m[1][0] = v[1] * t[0]; \ + m[1][1] = v[1] * t[1]; \ +}\ + + +/** 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) \ +{ \ + GUINT __ii[4], __jj[4], __k; \ + \ + for (__k=0; __k0.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) VEC_MINOR_AXES(plane, i0, i1) + +//! 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);\ + GREAL _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 = GIM_CLAMP(_tp,0.0f,1.0f); \ + VEC_SCALE(vPointB,_tp,_BD);\ + VEC_SUM(vPointB,vPointB,vB1);\ +}\ + +//! @} + +///Additional Headers for Collision +#include "GIMPACT/gim_box_collision.h" +#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/Extras/GIMPACT/include/GIMPACT/gim_math.h b/Extras/GIMPACT/include/GIMPACT/gim_math.h new file mode 100644 index 000000000..ee8bf61b4 --- /dev/null +++ b/Extras/GIMPACT/include/GIMPACT/gim_math.h @@ -0,0 +1,168 @@ +#ifndef GIM_MATH_H_INCLUDED +#define GIM_MATH_H_INCLUDED + +/*! \file gim_math.h +\author Francisco León Nájera +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that 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, GIMPACT-LICENSE-ZLIB.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 GREAL2 double +#define GINT long +#define GUINT unsigned long +#define GSHORT short +#define GUSHORT unsigned short +/*! 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 SCALAR_TYPES +\brief +Precision type constants +*/ +//! @{ +#define G_STYPE_REAL 0 +#define G_STYPE_REAL2 1 +#define G_STYPE_SHORT 2 +#define G_STYPE_USHORT 3 +#define G_STYPE_INT 4 +#define G_STYPE_UINT 5 +//! @} + +/*! \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 GIM_IR(x) ((GUINT&)(x)) + +//! Signed integer representation of a floating-point value. +#define GIM_SIR(x) ((GINT&)(x)) + +//! Absolute integer representation of a floating-point value +#define GIM_AIR(x) (GIM_IR(x)&0x7fffffff) + +//! Floating-point representation of an integer value. +#define GIM_FR(x) ((GREAL&)(x)) + +#define GIM_MAX(a,b) (ab?b:a) + +#define GIM_MAX3(a,b,c) GIM_MAX(a,GIM_MAX(b,c)) +#define GIM_MIN3(a,b,c) GIM_MIN(a,GIM_MIN(b,c)) + +#define GIM_IS_ZERO(value) (value < G_EPSILON && value > -G_EPSILON) + +#define GIM_IS_NEGATIVE(value) (value <= -G_EPSILON) + +#define GIM_IS_POSISITVE(value) (value >= G_EPSILON) + +///returns a clamped number +#define GIM_CLAMP(number,minval,maxval) (numbermaxval?maxval:number)) + +#define GIM_GREATER(x, y) fabsf(x) > (y) + +///Swap numbers +#define GIM_SWAP_NUMBERS(a,b){ \ + a = a+b; \ + b = a-b; \ + a = a-b; \ +}\ + +#define GIM_INV_SQRT(va,isva)\ +{\ + if(va<=0.0000001f)\ + {\ + isva = G_REAL_INFINITY;\ + }\ + else\ + {\ + GREAL _x = va * 0.5f;\ + GUINT _y = 0x5f3759df - ( GIM_IR(va) >> 1);\ + isva = GIM_FR(_y);\ + isva = isva * ( 1.5f - ( _x * isva * isva ) );\ + }\ +}\ + +#define GIM_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/Extras/GIMPACT/include/GIMPACT/gim_memory.h b/Extras/GIMPACT/include/GIMPACT/gim_memory.h new file mode 100644 index 000000000..329807ac8 --- /dev/null +++ b/Extras/GIMPACT/include/GIMPACT/gim_memory.h @@ -0,0 +1,1054 @@ +#ifndef GIM_MEMORY_H_INCLUDED +#define GIM_MEMORY_H_INCLUDED +/*! \file gim_memory.h +\author Francisco León Nájera +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that 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, GIMPACT-LICENSE-ZLIB.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; + +#define GIM_DYNARRAY_IS_VALID(array_data) (array_data.m_pdata != 0) + +#define GIM_DYNARRAY_INVALIDATE(array_data) array_data.m_pdata = 0; + +//! 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 +*/ +//! @{ + + +#define GIM_IS_VALID_BUFFER_ID(buffer_handle) (buffer_handle.m_buffer_id!=G_UINT_INFINITY) + +//! 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; +//! Tells if this is a valid buffer array +#define GIM_BUFFER_ARRAY_IS_VALID(buffer_array) (buffer_array.m_buffer_id.m_buffer_id!=G_UINT_INFINITY) + +//! Invalidates a buffer array +#define GIM_BUFFER_ARRAY_INVALIDATE(buffer_array) buffer_array.m_buffer_id.m_buffer_id = G_UINT_INFINITY; + +//! 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 element +\param 3 the destination stream element +*/ +typedef void (* gim_kernel_func)(void *,void *,void *); + +//! 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/Extras/GIMPACT/include/GIMPACT/gim_radixsort.h b/Extras/GIMPACT/include/GIMPACT/gim_radixsort.h new file mode 100644 index 000000000..f6daea529 --- /dev/null +++ b/Extras/GIMPACT/include/GIMPACT/gim_radixsort.h @@ -0,0 +1,302 @@ +#ifndef GIM_RADIXSORT_H_INCLUDED +#define GIM_RADIXSORT_H_INCLUDED +/*! \file gim_radixsort.h +\author Francisco León Nájera. +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 Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that 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, GIMPACT-LICENSE-ZLIB.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))) + +//! Iterative binary search +/*! +\param _array +\param _start_i the beginning of the array +\param _end_i the ending index of the array +\param _search_key Value to find +\param _comp_macro macro for comparing elements +\param _found If 1 the value has found +\param _result_index the index of the found element, or if not found then it will get the index of the closest bigger value +*/ +#define GIM_BINARY_SEARCH(_array, _start_i, _end_i, _search_key, _comp_macro, _found, _result_index)\ +{\ + GUINT _k, _comp_result, _i, _j;\ + _i = _start_i; \ + _j = _end_i+1;\ + _found = 0;\ + while ((_i < _j) &&( _found==0)) \ + {\ + _k = (_j+_i-1)/2;\ + _comp_result = _comp_macro(_array[_k], _search_key);\ + if (_comp_result == 0) \ + {\ + _result_index = _k; \ + _found = 1;\ + }\ + else if (_comp_result < 0) \ + {\ + _i = _k+1;\ + } \ + else\ + {\ + _j = _k;\ + }\ + }\ + if (_found == 0) \ + {\ + _result_index = _j;\ + }\ +}\ + + +//! @} +#endif // GIM_RADIXSORT_H_INCLUDED diff --git a/Extras/GIMPACT/include/GIMPACT/gim_tri_capsule_collision.h b/Extras/GIMPACT/include/GIMPACT/gim_tri_capsule_collision.h new file mode 100644 index 000000000..45968f478 --- /dev/null +++ b/Extras/GIMPACT/include/GIMPACT/gim_tri_capsule_collision.h @@ -0,0 +1,113 @@ +#ifndef GIM_TRI_CAPSULE_COLLISION_H_INCLUDED +#define GIM_TRI_CAPSULE_COLLISION_H_INCLUDED + +/*! \file gim_tri_capsule_collision.h +\author Francisco León Nájera +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that 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, GIMPACT-LICENSE-ZLIB.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/Extras/GIMPACT/include/GIMPACT/gim_tri_sphere_collision.h b/Extras/GIMPACT/include/GIMPACT/gim_tri_sphere_collision.h new file mode 100644 index 000000000..162879bed --- /dev/null +++ b/Extras/GIMPACT/include/GIMPACT/gim_tri_sphere_collision.h @@ -0,0 +1,53 @@ +#ifndef GIM_TRI_SPHERE_COLLISION_H_INCLUDED +#define GIM_TRI_SPHERE_COLLISION_H_INCLUDED + +/*! \file gim_tri_sphere_collision.h +\author Francisco León Nájera +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that 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, GIMPACT-LICENSE-ZLIB.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/Extras/GIMPACT/include/GIMPACT/gim_trimesh.h b/Extras/GIMPACT/include/GIMPACT/gim_trimesh.h new file mode 100644 index 000000000..ecbe9e628 --- /dev/null +++ b/Extras/GIMPACT/include/GIMPACT/gim_trimesh.h @@ -0,0 +1,657 @@ +#ifndef GIM_TRIMESH_H_INCLUDED +#define GIM_TRIMESH_H_INCLUDED +/*! \file gim_trimesh.h +\author Francisco León Nájera +*/ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that 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, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + +#include "GIMPACT/gim_trimesh_data.h" +#include "GIMPACT/gim_vertex_buffer_util.h" +#include "GIMPACT/gim_contact.h" + + +/*! \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 *); + +struct GIM_TRIMESH_CACHE +{ + GDYNAMIC_ARRAY m_planes_cache_buffer;//! Allocated GIM_TRIPLANES_CACHE + GDYNAMIC_ARRAY m_planes_cache_bitset; + + //! Allocated transformed vertices vec3f + /*! + \invariant must be aligned + */ + GBUFFER_ARRAY m_transformed_vertex_buffer; + GDYNAMIC_ARRAY m_transformed_vertices_cache_bitset; + GUINT m_tranformed_scalar_type; + +}; + +//! Constant which defines the Bounding volume method +#define G_TRIMESH_BOUND_NONE 0 +//! Constant which defines the Bounding volume method +#define G_TRIMESH_BOUND_AABB_TREE 1 +//! Constant which defines the Bounding volume method +#define G_TRIMESH_BOUND_AABB_SET 2 + +///MAsk defines +#define GIM_TRIMESH_APPLY_TRANSFORMATION 1 +#define GIM_TRIMESH_NEED_UPDATE 2 + +//! Trimesh +struct GIM_TRIMESH +{ + GUINT m_trimesh_data_handle;//!< Handle to a trimesh data object + GIM_TRIMESH_DATA * m_unlocked_trimesh_data; //!< temporal pointer + char m_mask;//!< Don't use directly + GIM_AABB_SET * m_aabbset; + GIM_TRIMESH_CACHE * m_cache; + gim_update_trimesh_function * m_update_callback;//! If null, then m_transform is applied. + mat4f m_transform; + mat4f m_inv_transform; +}; +//typedef struct _GIM_TRIMESH GIM_TRIMESH; + +//! Return the bound method +/*! +\ return G_TRIMESH_BOUND_AABB_TREE or G_TRIMESH_BOUND_AABB_SET +*/ +GUINT gim_trimesh_get_bound_method(GIM_TRIMESH * trimesh); + +/// Info about mesh +//! Return the trimesh triangle count +GUINT gim_trimesh_get_triangle_count(GIM_TRIMESH * trimesh); + +GUINT gim_trimesh_get_vertex_count(GIM_TRIMESH * trimesh); + +//! Returns 1 if the m_transformed_vertex_buffer is a reply of m_source_vertex_buffer +char gim_trimesh_has_tranform(GIM_TRIMESH * trimesh); + +//! Get the global bounding box +void gim_trimesh_get_aabb(GIM_TRIMESH * trimesh,aabb3f * bound); + +//! 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 +*/ +void gim_trimesh_post_update(GIM_TRIMESH * trimesh); + + + +//! Creates cache information for this mesh +/*! +*/ +void gim_trimesh_initialize_cache(GIM_TRIMESH * trimesh); + +//! Destroys the cache +/*! +*/ +void gim_trimesh_destroy_cache(GIM_TRIMESH * trimesh); + +//! Creates an AABB set for triangles. +/*! +*/ +void gim_trimesh_initialize_bound(GIM_TRIMESH * trimesh); + +//! Destroys the AABB set +/*! +*/ +void gim_trimesh_destroy_bound(GIM_TRIMESH * trimesh); + +//! Creates a trimesh +/*! + +\param trimesh for be created +\param trimesh_data_handle Handle to a trimesh data +\param apply_transform If 1, then it transforms the source vertices. +\param create_Cache If 1, then it allocates a cache for transformed vertices and planes. +\post Adds a reference to the trimesh_data_handle, and creates the auxiliary data (m_aabbset,m_planes_cache_buffer) +*/ +void gim_trimesh_create(GIM_TRIMESH * trimesh, GUINT trimesh_data_handle,char apply_transform,char create_cache); + +//! Creates the aabb set and the triangles cache +/*! + +\param trimesh +\param vertex_array +\param triindex_array +\param apply_transform If 1, then it transforms the source vertices. +\param create_Cache If 1, then it allocates a cache for transformed vertices and planes. +\param vertex_scalar_type G_STYPE_REAL or G_STYPE_REAL2 +\param index_scalar_type G_STYPE_SHORT,G_STYPE_USHORT,G_STYPE_INT or G_STYPE_UINT +\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,GUINT vertex_scalar_type, GBUFFER_ARRAY * triindex_array,GUINT index_scalar_type, +char apply_transform,char create_cache); + + + +//! 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 triangle_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 apply_transform If 1, then it transforms the source vertices. +\param create_Cache If 1, then it allocates a cache for transformed vertices and planes. +*/ +void gim_trimesh_create_from_data(GIM_TRIMESH * trimesh, vec3f * vertex_array, GUINT vertex_count,char copy_vertices, GUINT * triindex_array, GUINT triangle_count,char copy_indices, +char apply_transform,char create_cache); + +//! 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 apply_transform If 1, then it transforms the source vertices. +\param create_Cache If 1, then it allocates a cache for transformed vertices and planes. +*/ +void gim_trimesh_copy(GIM_TRIMESH * source_trimesh,GIM_TRIMESH * dest_trimesh, char copy_by_reference, +char apply_transform,char create_cache); + + +//! Locks the trimesh for working with it +/*! +\post locks m_trimesh_data_handle in G_MA_READ_ONLY and m_transformed_vertex_buffer in G_MA_READ_WRITE. +\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 the cache variables +void gim_trimesh_update_cache(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 data +/*! +\pre gim_trimesh_locks_work_data must be called before +If Planes cache is not avaliable, it doesn't calc the planes +*/ +void gim_trimesh_get_triangle_data_lazy(GIM_TRIMESH * trimesh, GUINT triangle_index, GIM_TRIANGLE_DATA * tri_data); + + +//! Fetch triangle vertices, transformed to global space +/*! +\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); + +//! Fetch a single transformed vertex +/*! +\pre gim_trimesh_locks_work_data must be called before +*/ +void gim_trimesh_get_vertex(GIM_TRIMESH * trimesh, GUINT vertex_index, vec3f vec); + +//! Fetch triangle vertices, transformed to global space +/*! +\pre gim_trimesh_locks_work_data must be called before +*/ +void gim_trimesh_get_triangle_vertices_local(GIM_TRIMESH * trimesh, GUINT triangle_index, vec3f v1,vec3f v2,vec3f v3); + +//! Fetch a single transformed vertex +/*! +\pre gim_trimesh_locks_work_data must be called before +*/ +void gim_trimesh_get_vertex_local(GIM_TRIMESH * trimesh, GUINT vertex_index, vec3f vec); + + +//! Finds Intersected boxes +/*! +\param trimesh +\param test_aabb Box for collision query, in global space +\param collided Array of GUINT elements, indices of trinagles. Must be initialized before (Reserve size ~ 100) +*/ +void gim_trimesh_midphase_box_collision(GIM_TRIMESH * trimesh,aabb3f *test_aabb, GDYNAMIC_ARRAY * collided); + + + +//! Finds Intersected boxes in local space +/*! +\param trimesh +\param test_aabb Box for collision query, in global space +\param collided Array of GUINT elements, indices of trinagles. Must be initialized before (Reserve size ~ 100) +*/ +void gim_trimesh_midphase_box_collision_local(GIM_TRIMESH * trimesh,aabb3f *test_aabb, GDYNAMIC_ARRAY * collided); + + +//! Finds overlapping boxes between sets +/*! +\param trimesh1 +\param trimesh2 +\param collision_pairs Array of GIM_PAIR elements. Must be initialized before (Reserve size ~ 100) +\param swaped If 1, result pairs are swaped and that would means that element 1 belongs to trimesh2 and element 2 belongs to trimesh1. 0 is normal. +*/ +void gim_trimesh_midphase_trimesh_collision(GIM_TRIMESH * trimesh1, +GIM_TRIMESH * trimesh2, GDYNAMIC_ARRAY * collision_pairs, char * swaped); + + + + +//! Trimesh Trimesh Collisions +/*! +Before use this function you must update each trimesh: +\code +gim_trimesh_update(TriMesh1); +gim_trimesh_update(TriMesh2); +\endcode +Then you must use the trimesh collision in this way: +\code +int collide_trimeshes(GIM_TRIMESH * TriMesh1, GIM_TRIMESH * TriMesh2) +{ + //Create contact list + GDYNAMIC_ARRAY trimeshcontacts; + GIM_CREATE_CONTACT_LIST(trimeshcontacts); + + //Collide trimeshes + gim_trimesh_trimesh_collision(TriMesh1,TriMesh2,&trimeshcontacts); + + if(trimeshcontacts.m_size == 0) //do nothing + { + GIM_DYNARRAY_DESTROY(trimeshcontacts);//clean contact array + return 0; + } + + //Getting a pointer to the contact array + GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts); + + int contactcount = trimeshcontacts.m_size; + int i; + //Process contacts + for (i=0;i +
  • m_handle1 points to trimesh1. +
  • m_handle2 points to trimesh2. +
  • m_feature1 Is a triangle index of trimesh1. +
  • m_feature2 Is a triangle index of trimesh2. + + +\param trimesh1 Collider +\param trimesh2 Collidee +\param contacts A GIM_CONTACT array. Must be initialized +*/ +void gim_trimesh_trimesh_collision(GIM_TRIMESH * trimesh1, GIM_TRIMESH * trimesh2, GDYNAMIC_ARRAY * contacts); + + +//! Trimesh Sphere Collisions +/*! +Before use this function you must update the trimesh: +\code +gim_trimesh_update(trimesh); +\endcode +Then you must use this function in this way: +\code +int collide_trimesh_sphere(GIM_TRIMESH * trimesh, vec3f center,GREAL radius) +{ + //Create contact list + GDYNAMIC_ARRAY trimeshcontacts; + GIM_CREATE_CONTACT_LIST(trimeshcontacts); + + //Collide trimeshes + gim_trimesh_sphere_collision(trimesh,center,radius,&trimeshcontacts); + + if(trimeshcontacts.m_size == 0) //do nothing + { + GIM_DYNARRAY_DESTROY(trimeshcontacts);//clean contact array + return 0; + } + + //Getting a pointer to the contact array + GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts); + + int contactcount = trimeshcontacts.m_size; + int i; + //Process contacts + for (i=0;i +
  • m_handle1 points to trimesh. +
  • m_handle2 points to NULL. +
  • m_feature1 Is a triangle index of trimesh. + + +\param trimesh +\param center +\param radius +\param contacts A GIM_CONTACT array. Must be initialized +*/ +void gim_trimesh_sphere_collision(GIM_TRIMESH * trimesh,vec3f center,GREAL radius, GDYNAMIC_ARRAY * contacts); + + +//! Trimesh Capsule collision +/*! +Find the closest primitive collided by the ray. + +Before use this function you must update the trimesh: +\code +gim_trimesh_update(trimesh); +\endcode +Then you must use this function in this way: +\code +int collide_trimesh_capsule(GIM_TRIMESH * trimesh, GIM_CAPSULE_DATA * capsule) +{ + //Create contact list + GDYNAMIC_ARRAY trimeshcontacts; + GIM_CREATE_CONTACT_LIST(trimeshcontacts); + + //Collide trimeshes + gim_trimesh_capsule_collision(trimesh,capsule,&trimeshcontacts); + + if(trimeshcontacts.m_size == 0) //do nothing + { + GIM_DYNARRAY_DESTROY(trimeshcontacts);//clean contact array + return 0; + } + + //Getting a pointer to the contact array + GIM_CONTACT * ptrimeshcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,trimeshcontacts); + + int contactcount = trimeshcontacts.m_size; + int i; + //Process contacts + for (i=0;i +
  • m_handle1 points to trimesh. +
  • m_handle2 points to NULL. +
  • m_feature1 Is a triangle index of trimesh. + + +\param trimesh +\param capsule +\param contacts A GIM_CONTACT array. Must be initialized +*/ +void gim_trimesh_capsule_collision(GIM_TRIMESH * trimesh, GIM_CAPSULE_DATA * capsule, GDYNAMIC_ARRAY * contacts); + + +///Function for create Trimesh Plane collision result +#define GIM_CREATE_TRIMESHPLANE_CONTACTS(dynarray) GIM_DYNARRAY_CREATE(vec4f,dynarray,G_ARRAY_GROW_SIZE) + +//! Trimesh Plane Collisions +/*! + +Before use this function you must update the trimesh: +\code +gim_trimesh_update(trimesh); +\endcode +Then you must use this function in this way: +\code +int collide_trimesh_plane(GIM_TRIMESH * trimesh, vec4f plane) +{ + //Create contact list + GDYNAMIC_ARRAY tri_plane_contacts; + GIM_CREATE_TRIMESHPLANE_CONTACTS(tri_plane_contacts); + + //Collide trimeshes + gim_trimesh_plane_collision(trimesh,plane,&tri_plane_contacts); + + if(tri_plane_contacts.m_size == 0) //do nothing + { + GIM_DYNARRAY_DESTROY(tri_plane_contacts);//clean contact array + return 0; + } + + //Getting a pointer to the contact array + vec4f * planecontacts = GIM_DYNARRAY_POINTER(vec4f,tri_plane_contacts); + + int contactcount = tri_plane_contacts.m_size; + int i; + //Process contacts + for (i=0;i + + + +//! Allocate memory for all aabb set. +void gim_aabbset_alloc(GIM_AABB_SET * aabbset, GUINT count) +{ + aabbset->m_count = count; + aabbset->m_boxes = (aabb3f *)gim_alloc(sizeof(aabb3f)*count); + + if(countm_maxcoords = 0; + aabbset->m_sorted_mincoords = 0; + } + else + { + aabbset->m_maxcoords = (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_size = 0; + char intersected; + GUINT i; + GUINT count = aabbset->m_count; + aabb3f * paabb = aabbset->m_boxes; + for (i=0;i< count;i++ ) + { + AABBCOLLISION(intersected,paabb[i],test_aabb); + if(intersected) + { + GIM_DYNARRAY_PUSH_ITEM(GUINT,(*collided),i); + } + } +} + +#define COMP_MACRO_TOKEN(x, key) ((GINT)((x.m_key) - (key))) +//!Traverse set for collision sorted +void _gim_aabbset_traverse_box_collision_sorted(aabb3f & test_aabb, GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collided) +{ + collided->m_size = 0; + GUINT count = aabbset->m_count; + aabb3f * paabb = aabbset->m_boxes; + GIM_RSORT_TOKEN * ptokens = aabbset->m_sorted_mincoords; + + //Convert the upper corner + GUINT uppercorner; + GIM_CONVERT_VEC3F_GUINT_XZ_UPPER(test_aabb.maxX,test_aabb.maxZ,uppercorner); + + //Search the token + GUINT i,starttoken=0; + char intersected; + GIM_BINARY_SEARCH(ptokens, 0,(count-1), uppercorner, COMP_MACRO_TOKEN, intersected, starttoken); + + if(starttoken>=count) starttoken = count-1; + if(ptokens[starttoken].m_key>uppercorner) + { + count = starttoken; + } + + for (starttoken = 0;starttokenm_size = 0; + GUINT count = aabbset->m_count; + aabb3f * paabb = aabbset->m_boxes; + GIM_RSORT_TOKEN * ptokens = aabbset->m_sorted_mincoords; + + //Convert the upper corner + GUINT uppercorner; + GIM_CONVERT_VEC3F_GUINT_XZ_UPPER(test_aabb.maxX,test_aabb.maxZ,uppercorner); + + //Search the token + GUINT i,starttoken=0; + char intersected; + GIM_BINARY_SEARCH(ptokens, 0, + count-1, uppercorner, COMP_MACRO_TOKEN, intersected, starttoken); + + if(starttoken>=count) starttoken = count-1; + if(ptokens[starttoken].m_key>uppercorner) + { + count = starttoken; + } + else + { + count = starttoken+1; + } + + for (starttoken = 0;starttokenm_sorted_mincoords == 0) + { + _gim_aabbset_traverse_box_collision_brute_force(test_aabb, aabbset, collided); + } + else + { + _gim_aabbset_traverse_box_collision_sorted(test_aabb, aabbset, collided); + } +} + + +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; + + aabb3f _testaabb; + AABB_COPY(_testaabb,*test_aabb); + + _gim_aabbset_traverse_box_collision(_testaabb,aabbset, collided); +} + + +//utility macros + +/*#define PUSH_PAIR(i,j,pairset)\ +{\ + GIM_PAIR _pair={i,j};\ + GIM_DYNARRAY_PUSH_ITEM(GIM_PAIR,pairset,_pair);\ +}*/ + +#define PUSH_PAIR(i,j,pairset)\ +{\ + GIM_DYNARRAY_PUSH_EMPTY(GIM_PAIR,pairset);\ + GIM_PAIR * _pair = GIM_DYNARRAY_POINTER(GIM_PAIR,pairset) + (pairset).m_size - 1;\ + _pair->m_index1 = i;\ + _pair->m_index2 = j;\ +} + +#define PUSH_PAIR_INV(i,j,pairset)\ +{\ + GIM_DYNARRAY_PUSH_EMPTY(GIM_PAIR,pairset);\ + GIM_PAIR * _pair = GIM_DYNARRAY_POINTER(GIM_PAIR,pairset) + (pairset).m_size - 1;\ + _pair->m_index1 = j;\ + _pair->m_index2 = i;\ +} + +#define FIND_OVERLAPPING_FOWARD(\ + curr_index,\ + test_count,\ + test_aabb,\ + max_coord_uint,\ + sorted_tokens,\ + aabbarray,\ + pairset,\ + push_pair_macro)\ +{\ + 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; + + //Classify boxes + //Find Set intersection + aabb3f int_abbb; + BOXINTERSECTION(aabbset1->m_global_bound,aabbset2->m_global_bound, int_abbb); + + //Clasify set 1 + GDYNAMIC_ARRAY classified_results1; + GIM_DYNARRAY_CREATE(GIM_RSORT_TOKEN,classified_results1,aabbset1->m_count); + + _gim_aabbset_traverse_box_collision_sorted_pushtoken(int_abbb,aabbset1, &classified_results1); + + if(classified_results1.m_size==0) + { + GIM_DYNARRAY_DESTROY(classified_results1); + return; + } + + //Clasify set 2 + GDYNAMIC_ARRAY classified_results2; + GIM_DYNARRAY_CREATE(GIM_RSORT_TOKEN,classified_results2,aabbset2->m_count); + + _gim_aabbset_traverse_box_collision_sorted_pushtoken(int_abbb,aabbset2, &classified_results2); + + if(classified_results2.m_size==0) + { + GIM_DYNARRAY_DESTROY(classified_results1); + GIM_DYNARRAY_DESTROY(classified_results2); + return; + } + + + aabb3f * paabb1 = aabbset1->m_boxes; + GUINT * maxcoords1 = aabbset1->m_maxcoords; + + aabb3f * paabb2 = aabbset2->m_boxes; + GUINT * maxcoords2 = aabbset2->m_maxcoords; + + GUINT curr_index; + + GUINT max_coord_uint; + aabb3f test_aabb; + + GUINT classified_count1 = classified_results1.m_size; + GUINT classified_count2 = classified_results2.m_size; + + GIM_RSORT_TOKEN * sorted_tokens1 = GIM_DYNARRAY_POINTER(GIM_RSORT_TOKEN,classified_results1); + GIM_RSORT_TOKEN * sorted_tokens2 = GIM_DYNARRAY_POINTER(GIM_RSORT_TOKEN,classified_results2); + + while(classified_count1>0&&classified_count2>0) + { + if(sorted_tokens1->m_key <= sorted_tokens2->m_key) + { + ///current cache variables + curr_index = sorted_tokens1->m_value; + max_coord_uint = maxcoords1[curr_index]; + AABB_COPY(test_aabb,paabb1[curr_index]); + ///next pairs + sorted_tokens1++; + classified_count1--; + FIND_OVERLAPPING_FOWARD( curr_index, classified_count2, test_aabb, max_coord_uint, sorted_tokens2 , paabb2, (*collision_pairs), PUSH_PAIR); + } + else ///Switch test + { + ///current cache variables + curr_index = sorted_tokens2->m_value; + max_coord_uint = maxcoords2[curr_index]; + AABB_COPY(test_aabb,paabb2[curr_index]); + ///next pairs + sorted_tokens2++; + classified_count2--; + FIND_OVERLAPPING_FOWARD( curr_index, classified_count1, test_aabb, max_coord_uint, sorted_tokens1 , paabb1, (*collision_pairs), PUSH_PAIR_INV ); + } + } + GIM_DYNARRAY_DESTROY(classified_results1); + GIM_DYNARRAY_DESTROY(classified_results2); +} + +//! 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 + GDYNAMIC_ARRAY classified_results1; + GIM_DYNARRAY_CREATE(GUINT,classified_results1,(aabbset1->m_count/4)); + + _gim_aabbset_traverse_box_collision(int_abbb,aabbset1, &classified_results1); + + if(classified_results1.m_size==0) + { + GIM_DYNARRAY_DESTROY(classified_results1); + return; + } + + aabb3f * paabb1 = aabbset1->m_boxes; + aabb3f * paabb2 = aabbset2->m_boxes; + + GUINT i,j,count1,count2; + + //intesect set2 + GUINT * classified1 = GIM_DYNARRAY_POINTER(GUINT,classified_results1); + count1 = classified_results1.m_size; + count2 = aabbset2->m_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_ray_collision(vec3f vorigin,vec3f vdir, GREAL tmax, GIM_AABB_SET * aabbset, GDYNAMIC_ARRAY * collided) +{ + collided->m_size = 0; + char intersected; + + intersected = BOX_INTERSECTS_RAY_FAST(aabbset->m_global_bound, vorigin,vdir); + + if(intersected==0) return; + + GUINT i; + GUINT count = aabbset->m_count; + aabb3f * paabb = aabbset->m_boxes; + + for (i=0;i< count;i++ ) + { + intersected = BOX_INTERSECTS_RAY_FAST(paabb[i], vorigin,vdir); + if(intersected) + { + GIM_DYNARRAY_PUSH_ITEM(GUINT,(*collided),i); + } + } +} + +//***********************************AABB Trees ***************************************************// + +GUINT _gim_sort_and_calc_splitting_index(GIM_AABB_DATA * boxarray, GUINT startIndex, GUINT endIndex, GUINT splitAxis) +{ + GUINT i; + GUINT splitIndex =startIndex; + GUINT numIndices = endIndex - startIndex; + GREAL splitValue = 0.f; + GREAL * boxvalues; + for (i=startIndex;i splitValue) + { + //swap + AABB_DATA_COPY(tmp,boxarray[i]); + AABB_DATA_COPY(boxarray[i],boxarray[splitIndex]); + AABB_DATA_COPY(boxarray[splitIndex],tmp); + splitIndex++; + } + } + + if ((splitIndex==startIndex) || (splitIndex == (endIndex-1))) + { + splitIndex = startIndex+ (numIndices>>1); + } + return splitIndex; +} + + +GUINT _gim_calc_splitting_axis(GIM_AABB_DATA * boxarray, GUINT startIndex, GUINT endIndex) +{ + GUINT i; + GREAL means[]= {0.f,0.f,0.f}; + GUINT numIndices = endIndex-startIndex; + + for (i=startIndex;i0); + + internalNode = &node_array[node_index]; + node_index++; + + if (numIndices==1) + { + //We have a leaf node + internalNode->m_left = 0; + internalNode->m_right = 0; + internalNode->m_escapeIndex = 0; + AABB_DATA_COPY(internalNode->m_data,boxarray[startIndex]); + + return internalNode; + } + //calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'. + + splitAxis = _gim_calc_splitting_axis(boxarray,startIndex,endIndex); + + splitIndex = _gim_sort_and_calc_splitting_index(boxarray,startIndex,endIndex,splitAxis); + + INVALIDATE_AABB(internalNode->m_data.m_aabb); + + for (i=startIndex;im_data.m_aabb,boxarray[i].m_aabb); + } + + //internalNode->m_escapeIndex; + internalNode->m_left = _gim_build_subtree(node_array,node_index,boxarray,startIndex,splitIndex); + internalNode->m_right = _gim_build_subtree(node_array,node_index,boxarray,splitIndex,endIndex); + internalNode->m_escapeIndex = node_index - curIndex; + return internalNode; +} + + + +void gim_aabbtree_create(GIM_AABB_TREE * newtree, GIM_AABB_DATA * boxarray, GUINT boxcount) +{ + newtree->clear_nodes();//For security + newtree->m_nodes_array_size = boxcount*2; + newtree->m_node_array = (GIM_AABB_TREE_NODE * )gim_alloc(newtree->m_nodes_array_size*sizeof(GIM_AABB_TREE_NODE)); + newtree->m_num_nodes = 0; + newtree->m_root_node = _gim_build_subtree(newtree->m_node_array,newtree->m_num_nodes,boxarray,0,boxcount); +} + +void gim_aabbtree_destroy(GIM_AABB_TREE * tree) +{ + tree->clear_nodes(); +} + +//******boxtree collision + + +//Tree traversing macros +#define NEXT_SUBNODE(rootNode,curIndex)\ +{\ + rootNode++;\ + curIndex++;\ +}\ + +#define SKIP_NODE(rootNode,curIndex)\ +{\ + curIndex+= rootNode->m_escapeIndex;\ + rootNode+= rootNode->m_escapeIndex;\ +}\ + + +void gim_aabbtree_box_collision_get_nodes(aabb3f *test_aabb, GIM_AABB_TREE * aabbtree, GDYNAMIC_ARRAY * collided) +{ + GUINT curIndex = 0; + + GUINT aabbOverlap; + bool isLeafNode; + GIM_AABB_TREE_NODE * pnode = aabbtree->m_node_array; + + while (curIndex < aabbtree->m_num_nodes) + { + //catch bugs in tree data + + AABBCOLLISION(aabbOverlap,pnode->m_data.m_aabb,(*test_aabb)); + isLeafNode = pnode->is_leaf_node(); + + if (isLeafNode && aabbOverlap) + { + GIM_DYNARRAY_PUSH_ITEM(GUINT,(*collided),curIndex);//Push leaf index + } + + if (aabbOverlap || isLeafNode) + { + NEXT_SUBNODE(pnode,curIndex); + } + else + { + SKIP_NODE(pnode,curIndex); + } + } +} + + +void gim_aabbtree_box_collision(aabb3f *test_aabb, GIM_AABB_TREE * aabbtree, GDYNAMIC_ARRAY * collided) +{ + GUINT curIndex = 0; + + GUINT aabbOverlap; + bool isLeafNode; + GIM_AABB_TREE_NODE * pnode = aabbtree->m_node_array; + + while (curIndex < aabbtree->m_num_nodes) + { + //catch bugs in tree data + + AABBCOLLISION(aabbOverlap,pnode->m_data.m_aabb,(*test_aabb)); + isLeafNode = pnode->is_leaf_node(); + + if (isLeafNode && aabbOverlap) + { + GIM_DYNARRAY_PUSH_ITEM(GUINT,(*collided),pnode->m_data.m_data);//Push leaf dataindex + } + + if (aabbOverlap || isLeafNode) + { + NEXT_SUBNODE(pnode,curIndex); + } + else + { + SKIP_NODE(pnode,curIndex); + } + } +} + +void gim_aabbtree_ray_collision(vec3f vorigin,vec3f vdir, GREAL tmax, GIM_AABB_TREE * aabbtree, GDYNAMIC_ARRAY * collided) +{ + GUINT curIndex = 0; + + GUINT rayOverlap; + bool isLeafNode; + GIM_AABB_TREE_NODE * pnode = aabbtree->m_node_array; + + while (curIndex < aabbtree->m_num_nodes) + { + //catch bugs in tree data + + rayOverlap = BOX_INTERSECTS_RAY_FAST(pnode->m_data.m_aabb, vorigin,vdir); + + isLeafNode = pnode->is_leaf_node(); + + if (isLeafNode && rayOverlap) + { + GIM_DYNARRAY_PUSH_ITEM(GUINT,(*collided),pnode->m_data.m_data);//Push leaf dataindex + } + + if (rayOverlap || isLeafNode) + { + NEXT_SUBNODE(pnode,curIndex); + } + else + { + SKIP_NODE(pnode,curIndex); + } + } +} + + +static void _gim_walk_tree_duo_cache( +GIM_AABB_TREE_NODE * node0, +GIM_AABB_TREE_NODE * node1, +GIM_BOX_BOX_TRANSFORM_CACHE * trans_cache, +GDYNAMIC_ARRAY * collision_pairs, bool full_test=true) +{ + if(gim_box_box_overlap_cache(&node0->m_data.m_aabb, + &node1->m_data.m_aabb, trans_cache,full_test)==0) return; + + //Test children + if(node0->is_leaf_node()) + { + if(node1->is_leaf_node()) + { + PUSH_PAIR(node0->m_data.m_data,node1->m_data.m_data,(*collision_pairs)); + return; + } + else + { + if(node1->m_left) + { + _gim_walk_tree_duo_cache(node0,node1->m_left, + trans_cache,collision_pairs,false); + } + if(node1->m_right) + { + _gim_walk_tree_duo_cache(node0,node1->m_right, + trans_cache,collision_pairs,false); + } + } + } + else + { + if(node1->is_leaf_node()) + { + if(node0->m_left) + { + _gim_walk_tree_duo_cache(node0->m_left,node1, + trans_cache,collision_pairs,false); + } + if(node0->m_right) + { + _gim_walk_tree_duo_cache(node0->m_right,node1, + trans_cache,collision_pairs,false); + } + } + else + { + if(node0->m_left) + { + if(node1->m_left) + { + _gim_walk_tree_duo_cache(node0->m_left,node1->m_left, + trans_cache,collision_pairs,false); + } + if(node1->m_right) + { + _gim_walk_tree_duo_cache(node0->m_left,node1->m_right, + trans_cache,collision_pairs,false); + } + } + if(node0->m_right) + { + if(node1->m_left) + { + _gim_walk_tree_duo_cache(node0->m_right,node1->m_left, + trans_cache,collision_pairs,false); + } + if(node1->m_right) + { + _gim_walk_tree_duo_cache(node0->m_right,node1->m_right, + trans_cache,collision_pairs,false); + } + } + } + }// if(node0->is_leaf_node()) else +} + + +void gim_aabbtree_bipartite_intersections_trans(GIM_AABB_TREE * aabbtree1, GIM_AABB_TREE * aabbtree2, +mat4f trans1,mat4f trans1inverse, +mat4f trans2,mat4f trans2inverse, + GDYNAMIC_ARRAY * collision_pairs) +{ + collision_pairs->m_size = 0; + + //Find relative transformation + mat4f trans2to1; + MATRIX_PRODUCT_4X4(trans2to1,trans1inverse,trans2); + //Find Box filter + /*aabb3f transbox1,transbox2; + AABB_TRANSFORM(transbox1,aabbtree1->m_root_node->m_data.m_aabb,trans1); + AABB_TRANSFORM(transbox2,aabbtree2->m_root_node->m_data.m_aabb,trans2); + + char intersected; + AABBCOLLISION(intersected,transbox1,transbox2); + if(intersected == 0) return; + aabb3f filter_aabb; + + BOXINTERSECTION(transbox1,transbox2, filter_aabb); + + AABB_TRANSFORM(transbox1,filter_aabb,trans1inverse); + AABB_TRANSFORM(transbox2,filter_aabb,trans2inverse);*/ + + + GIM_BOX_BOX_TRANSFORM_CACHE boxcache(trans2to1); + //_gim_walk_tree_duo_cache(aabbtree1->m_root_node,aabbtree2->m_root_node,&boxcache,&transbox1,&transbox2,collision_pairs); + _gim_walk_tree_duo_cache(aabbtree1->m_root_node,aabbtree2->m_root_node, + &boxcache,collision_pairs); + +} + +void gim_aabbset_aabbtree_intersections_trans(GIM_AABB_SET * aabbset, GIM_AABB_TREE * aabbtree, mat4f trans_aabbtree, mat4f inv_trans_aabbtree, GDYNAMIC_ARRAY * collision_pairs) +{ + aabb3f global_box_aabbtree; + + //Calc the box aabbtree + AABB_TRANSFORM(global_box_aabbtree,aabbtree->m_root_node->m_data.m_aabb,trans_aabbtree); + + char intersected; + collision_pairs->m_size = 0; + AABBCOLLISION(intersected,aabbset->m_global_bound,global_box_aabbtree); + if(intersected == 0) return; + + + aabb3f int_aabb; + //Find Set intersection + BOXINTERSECTION(aabbset->m_global_bound,global_box_aabbtree, int_aabb); + + //Classify set + GDYNAMIC_ARRAY classified_results1; + GIM_DYNARRAY_CREATE(GUINT,classified_results1,(aabbset->m_count/4)); + + _gim_aabbset_traverse_box_collision(int_aabb,aabbset, &classified_results1); + + if(classified_results1.m_size==0) + { + GIM_DYNARRAY_DESTROY(classified_results1); + return; + } + + //Test against tree + //Collide classified + aabb3f * paabb = aabbset->m_boxes; + GDYNAMIC_ARRAY classified_results2; + GIM_DYNARRAY_CREATE(GUINT,classified_results2,G_ARRAY_GROW_SIZE); + + GUINT * classified1 = GIM_DYNARRAY_POINTER(GUINT,classified_results1); + GUINT * classified2; + GUINT i,j; + + for (i=0;im_depth,normals[i]); + VEC_SUM(vec_sum,vec_sum,test_vec); + } + + if(VEC_DOT(vec_sum,vec_sum)m_depth); + test_vec[0] = 1.0f/destcontact->m_depth; + + VEC_SCALE(destcontact->m_normal,test_vec[0],vec_sum); +} + + + +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 - CONTACT_DIFF_EPSILON > scontact->m_depth)//) + { + GIM_COPY_CONTACTS(pcontact, scontact); + coincident_count = 0; + } + else + { + #if (NORMAL_CONTACT_AVERAGE == 1) + + if(fabsf(pcontact->m_depth - scontact->m_depth)m_normal); + coincident_count++; + } + } + #endif + } + } + else + {//add new contact + #if (NORMAL_CONTACT_AVERAGE == 1) + if(pcontact&&coincident_count>0) + { + gim_interpolate_contact_normals(pcontact,coincident_normals,coincident_count); + coincident_count = 0; + } + #endif + GIM_DYNARRAY_PUSH_EMPTY(GIM_CONTACT,(*dest_contacts)); + pcontact = GIM_DYNARRAY_POINTER_LAST(GIM_CONTACT,(*dest_contacts)); + GIM_COPY_CONTACTS(pcontact, scontact); + coincident_count=0; + + } + 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/Extras/GIMPACT/src/gim_math.cpp b/Extras/GIMPACT/src/gim_math.cpp new file mode 100644 index 000000000..ed81761ba --- /dev/null +++ b/Extras/GIMPACT/src/gim_math.cpp @@ -0,0 +1,62 @@ +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that 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, GIMPACT-LICENSE-ZLIB.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(time(0)); +} + +//! Generates an unit random +GREAL gim_unit_random() +{ + GREAL rn = rand(); + rn/=(GREAL)RAND_MAX; + return rn; +} diff --git a/Extras/GIMPACT/src/gim_memory.cpp b/Extras/GIMPACT/src/gim_memory.cpp new file mode 100644 index 000000000..a273d1b5b --- /dev/null +++ b/Extras/GIMPACT/src/gim_memory.cpp @@ -0,0 +1,854 @@ + +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that 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, GIMPACT-LICENSE-ZLIB.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); + array_data.m_buffer_id.m_buffer_id = G_UINT_INFINITY; + array_data.m_element_count = 0; +} + +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) +{ + char * ptr = 0; + ptr = new char[size]; //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 + { + char * cptr = (char *)ptr; + delete [] cptr; + //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/Extras/GIMPACT/src/gim_tri_tri_overlap.cpp b/Extras/GIMPACT/src/gim_tri_tri_overlap.cpp new file mode 100644 index 000000000..a3220a817 --- /dev/null +++ b/Extras/GIMPACT/src/gim_tri_tri_overlap.cpp @@ -0,0 +1,329 @@ + +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that 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, GIMPACT-LICENSE-ZLIB.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;\ + }\ +}\ + +#define CLASSIFY_TRIPOINTS_BY_PLANE(v1,v2,v3,faceplane,out_of_face)\ +{ \ + _distances[0] = DISTANCE_PLANE_POINT(faceplane,v1);\ + _distances[1] = DISTANCE_PLANE_POINT(faceplane,v2);\ + _distances[2] = DISTANCE_PLANE_POINT(faceplane,v3); \ + if(_distances[0]<=0.0f || _distances[1]<=0.0f || _distances[2]<=0.0f)\ + {\ + out_of_face = 0;\ + }\ + else\ + {\ + out_of_face = 1;\ + }\ +}\ + + +/* 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;*/ + + POINT_IN_TRI(tri1->m_vertices[0],tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2]) + POINT_IN_TRI(tri2->m_vertices[0],tri1->m_vertices[0],tri1->m_vertices[1],tri1->m_vertices[2]) + + 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_fast( + 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_PLANE(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; + + + /*vec3f _points[3]; + VEC_COPY(_points[0],tri2->m_vertices[0]); + VEC_COPY(_points[1],tri2->m_vertices[1]); + VEC_COPY(_points[2],tri2->m_vertices[2]); + + CLASSIFY_TRIPOINTS_BY_FACE(_points[0],_points[1],_points[2],tri1->m_planes.m_planes[0],out_of_face); + if(out_of_face==1) return 0; + + CLASSIFY_TRIPOINTS_BY_PLANE(_points[0],_points[1],_points[2],tri1->m_planes.m_planes[1],out_of_face); + if(out_of_face==1) return 0; + + CLASSIFY_TRIPOINTS_BY_PLANE(_points[0],_points[1],_points[2],tri1->m_planes.m_planes[2],out_of_face); + if(out_of_face==1) return 0; + + CLASSIFY_TRIPOINTS_BY_PLANE(_points[0],_points[1],_points[2],tri1->m_planes.m_planes[3],out_of_face); + if(out_of_face==1) return 0; + + return 1;*/ + + + short i0,i1; + /* first project onto an axis-aligned plane, that maximizes the area */ + /* of the triangles, compute indices: i0,i1. */ + PLANE_MINOR_AXES(tri2->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;*/ + + POINT_IN_TRI(tri1->m_vertices[0],tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2]) + POINT_IN_TRI(tri2->m_vertices[0],tri1->m_vertices[0],tri1->m_vertices[1],tri1->m_vertices[2]) + + return 0; +} + + + +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]m_trimesh_data_handle); +} + +GUINT gim_trimesh_get_vertex_count(GIM_TRIMESH * trimesh) +{ + return gim_trimesh_data_get_vertex_count(trimesh->m_trimesh_data_handle); +} + +GUINT gim_trimesh_get_bound_method(GIM_TRIMESH * trimesh) +{ + if(gim_trimesh_data_has_bv_tree(trimesh->m_trimesh_data_handle) != 0) return G_TRIMESH_BOUND_AABB_TREE; + else if(trimesh->m_aabbset != 0) return G_TRIMESH_BOUND_AABB_SET; + return G_TRIMESH_BOUND_NONE; +} + + +#define LAZY_TRANSFORM_VERTEX(bitset,vec_index,transform,source_trimesh_data,dest_vert,temp_vert)\ +{\ + GUINT bit_eval;\ + if(GIM_DYNARRAY_IS_VALID(bitset))\ + {\ + GIM_BITSET_GET(bitset,vec_index,bit_eval);\ + if(bit_eval == 0)\ + {\ + gim_trimesh_data_get_vertex(source_trimesh_data,vec_index,vec);\ + MAT_DOT_VEC_3X4(dest_vert,transform,temp_vert);\ + }\ + }\ +}\ + + + + +//! Fetch a single transformed vertex +/*! +\pre gim_trimesh_locks_work_data must be called before +*/ +void gim_trimesh_get_vertex(GIM_TRIMESH * trimesh, GUINT vertex_index, vec3f vec) +{ + if(trimesh->m_cache) + { + if(GIM_BUFFER_ARRAY_IS_VALID(trimesh->m_cache->m_transformed_vertex_buffer)) + { + GREAL * transvecf = GIM_BUFFER_ARRAY_POINTER(GREAL,trimesh->m_cache->m_transformed_vertex_buffer,vertex_index); + LAZY_TRANSFORM_VERTEX(trimesh->m_cache->m_transformed_vertices_cache_bitset,vertex_index,trimesh->m_transform,trimesh->m_unlocked_trimesh_data,transvecf,vec); + VEC_COPY(vec,transvecf); + return; + } + } + + if(gim_trimesh_has_tranform(trimesh)) + { + vec3f vectemp; + gim_trimesh_data_get_vertex(trimesh->m_unlocked_trimesh_data,vertex_index,vectemp); + MAT_DOT_VEC_3X4(vec,trimesh->m_transform,vectemp); + return; + } + gim_trimesh_data_get_vertex(trimesh->m_unlocked_trimesh_data,vertex_index,vec); +} + +void gim_trimesh_get_triangle_vertices_local(GIM_TRIMESH * trimesh, GUINT triangle_index, + vec3f v1,vec3f v2,vec3f v3) +{ + vec3ui triangle_indices; + gim_trimesh_data_get_triangle_indices( + trimesh->m_unlocked_trimesh_data,triangle_index,triangle_indices); + + gim_trimesh_data_get_vertex(trimesh->m_unlocked_trimesh_data,triangle_indices[0],v1); + gim_trimesh_data_get_vertex(trimesh->m_unlocked_trimesh_data,triangle_indices[1],v2); + gim_trimesh_data_get_vertex(trimesh->m_unlocked_trimesh_data,triangle_indices[2],v3); +} + +void gim_trimesh_get_vertex_local(GIM_TRIMESH * trimesh, GUINT vertex_index, vec3f vec) +{ + gim_trimesh_data_get_vertex(trimesh->m_unlocked_trimesh_data,vertex_index,vec); +} + + +void gim_trimesh_get_triangle_vertices(GIM_TRIMESH * trimesh, GUINT triangle_index, vec3f v1,vec3f v2,vec3f v3) +{ + if(gim_trimesh_has_tranform(trimesh)==0) + { + gim_trimesh_get_triangle_vertices_local(trimesh,triangle_index,v1,v2,v3); + return; + } + + vec3ui triangle_indices; + gim_trimesh_data_get_triangle_indices( + trimesh->m_unlocked_trimesh_data,triangle_index,triangle_indices); + if(trimesh->m_aabbset) + { + vec3f * vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_cache->m_transformed_vertex_buffer,0); + VEC_COPY(v1,vertices[triangle_indices[0]]); + VEC_COPY(v2,vertices[triangle_indices[1]]); + VEC_COPY(v3,vertices[triangle_indices[2]]); + return; + } + gim_trimesh_get_vertex(trimesh, triangle_indices[0], v1); + gim_trimesh_get_vertex(trimesh, triangle_indices[1], v2); + gim_trimesh_get_vertex(trimesh, triangle_indices[2], v3); +} + +void gim_trimesh_initialize_cache(GIM_TRIMESH * trimesh) +{ + trimesh->m_cache = (GIM_TRIMESH_CACHE *)gim_alloc(sizeof(GIM_TRIMESH_CACHE)); + + //Initializes the transformed vertices + if(gim_trimesh_has_tranform(trimesh)) + { + gim_trimesh_data_get(trimesh->m_trimesh_data_handle,&trimesh->m_unlocked_trimesh_data ); + //Create vertex buffer + gim_create_common_vertex_buffer(&trimesh->m_cache->m_transformed_vertex_buffer, + trimesh->m_unlocked_trimesh_data->m_source_vertex_buffer.m_element_count); + //Copy the vertex buffer + gim_copy_vertex_buffers(&trimesh->m_unlocked_trimesh_data->m_source_vertex_buffer, + trimesh->m_unlocked_trimesh_data->m_vertex_scalar_type, + &trimesh->m_cache->m_transformed_vertex_buffer,G_STYPE_REAL); + + trimesh->m_cache->m_tranformed_scalar_type = G_STYPE_REAL; + + trimesh->m_unlocked_trimesh_data = 0; + + //Create vertices bitset + if(gim_trimesh_get_bound_method(trimesh)==G_TRIMESH_BOUND_AABB_TREE) + { + //Create the bitset + GIM_BITSET_CREATE_SIZED(trimesh->m_cache->m_transformed_vertices_cache_bitset, + trimesh->m_cache->m_transformed_vertex_buffer.m_element_count); + } + else + { + GIM_DYNARRAY_INVALIDATE(trimesh->m_cache->m_transformed_vertices_cache_bitset); + } + } + else + { + GIM_BUFFER_ARRAY_INVALIDATE(trimesh->m_cache->m_transformed_vertex_buffer); + GIM_DYNARRAY_INVALIDATE(trimesh->m_cache->m_transformed_vertices_cache_bitset); + } + + GUINT facecount = gim_trimesh_get_triangle_count(trimesh); + //create the planes cache + GIM_DYNARRAY_CREATE_SIZED(GIM_TRIPLANES_CACHE,trimesh->m_cache->m_planes_cache_buffer,facecount); + //Create the bitset + GIM_BITSET_CREATE_SIZED(trimesh->m_cache->m_planes_cache_bitset,facecount); +} + +void gim_trimesh_destroy_cache(GIM_TRIMESH * trimesh) +{ + if(trimesh->m_cache==0) return; + if(trimesh->m_unlocked_trimesh_data != 0) + { + gim_trimesh_unlocks_work_data(trimesh); + } + GIM_DYNARRAY_DESTROY(trimesh->m_cache->m_planes_cache_buffer); + GIM_DYNARRAY_DESTROY(trimesh->m_cache->m_planes_cache_bitset); + + if(GIM_BUFFER_ARRAY_IS_VALID(trimesh->m_cache->m_transformed_vertex_buffer)) + { + GIM_BUFFER_ARRAY_DESTROY(trimesh->m_cache->m_transformed_vertex_buffer); + if(GIM_DYNARRAY_IS_VALID(trimesh->m_cache->m_transformed_vertices_cache_bitset)) + { + GIM_DYNARRAY_DESTROY(trimesh->m_cache->m_transformed_vertices_cache_bitset); + } + } + + gim_free(trimesh->m_cache,0); + trimesh->m_cache = 0; +} + +void gim_trimesh_initialize_bound(GIM_TRIMESH * trimesh) +{ + if(gim_trimesh_get_bound_method(trimesh)==G_TRIMESH_BOUND_NONE) + { + GUINT facecount = gim_trimesh_get_triangle_count(trimesh); + trimesh->m_aabbset = (GIM_AABB_SET *)gim_alloc(sizeof(GIM_AABB_SET)); + gim_aabbset_alloc(trimesh->m_aabbset,facecount); + } +} + +void gim_trimesh_destroy_bound(GIM_TRIMESH * trimesh) +{ + if(trimesh->m_aabbset != 0) + { + gim_aabbset_destroy(trimesh->m_aabbset); + gim_free(trimesh->m_aabbset,0); + } + trimesh->m_aabbset = 0; +} + + +void gim_trimesh_create(GIM_TRIMESH * trimesh, GUINT trimesh_data_handle, +char apply_transform,char create_cache) +{ + trimesh->m_mask = GIM_TRIMESH_NEED_UPDATE;//needs update + + trimesh->m_trimesh_data_handle = trimesh_data_handle; + trimesh->m_unlocked_trimesh_data = 0; + gim_trimesh_data_inc_ref(trimesh->m_trimesh_data_handle); + + trimesh->m_aabbset = 0; + trimesh->m_cache = 0; + + if(apply_transform==1) trimesh->m_mask |= GIM_TRIMESH_APPLY_TRANSFORMATION; + + gim_trimesh_initialize_bound(trimesh); + + if(create_cache == 1 || gim_trimesh_get_bound_method(trimesh)==G_TRIMESH_BOUND_AABB_SET ) + { + gim_trimesh_initialize_cache(trimesh); + } + //Callback is 0 + trimesh->m_update_callback = 0; + //set to identity + IDENTIFY_MATRIX_4X4(trimesh->m_transform); + IDENTIFY_MATRIX_4X4(trimesh->m_inv_transform); +} + +void gim_trimesh_create_from_arrays(GIM_TRIMESH * trimesh, GBUFFER_ARRAY * vertex_array,GUINT vertex_scalar_type, GBUFFER_ARRAY * triindex_array,GUINT index_scalar_type, +char apply_transform,char create_cache) +{ + //Create mesh data + gim_trimesh_data_create_from_arrays( + &trimesh->m_trimesh_data_handle,vertex_array,vertex_scalar_type,triindex_array,index_scalar_type); + //Create + gim_trimesh_create(trimesh,trimesh->m_trimesh_data_handle,apply_transform,create_cache); +} + + + +//! 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 triangle_count,char copy_indices, +char apply_transform,char create_cache) +{ + + //Create mesh data + gim_trimesh_data_create_from_array_data( + &trimesh->m_trimesh_data_handle,vertex_array,vertex_count,copy_vertices, + triindex_array, triangle_count,copy_indices); + //Create + gim_trimesh_create(trimesh,trimesh->m_trimesh_data_handle, + apply_transform,create_cache); +} + +//! Clears auxiliary data and releases buffer arrays +void gim_trimesh_destroy(GIM_TRIMESH * trimesh) +{ + gim_trimesh_destroy_cache(trimesh); + gim_trimesh_destroy_bound(trimesh); + //Release trimesh data + gim_trimesh_data_dec_ref(trimesh->m_trimesh_data_handle); + trimesh->m_trimesh_data_handle = 0; +} + +//! 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 apply_transform,char create_cache) +{ + if(copy_by_reference==1) + { + + gim_trimesh_create(dest_trimesh,source_trimesh->m_trimesh_data_handle, + apply_transform,create_cache); + } + else + { + gim_trimesh_data_create_copy(source_trimesh->m_trimesh_data_handle,&dest_trimesh->m_trimesh_data_handle,0); + + gim_trimesh_create(dest_trimesh,dest_trimesh->m_trimesh_data_handle, + apply_transform,create_cache); + } +} + + +void gim_trimesh_locks_work_data(GIM_TRIMESH * trimesh) +{ + gim_trimesh_data_lock(trimesh->m_trimesh_data_handle,G_MA_READ_ONLY,&trimesh->m_unlocked_trimesh_data); + if(trimesh->m_cache) + { + if(GIM_BUFFER_ARRAY_IS_VALID(trimesh->m_cache->m_transformed_vertex_buffer)) + { + gim_buffer_array_lock(&trimesh->m_cache->m_transformed_vertex_buffer,G_MA_READ_ONLY); + } + } +} + +//! 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) +{ + trimesh->m_unlocked_trimesh_data = 0; + gim_trimesh_data_unlock(trimesh->m_trimesh_data_handle); + + if(trimesh->m_cache) + { + if(GIM_BUFFER_ARRAY_IS_VALID(trimesh->m_cache->m_transformed_vertex_buffer)) + { + gim_buffer_array_unlock(&trimesh->m_cache->m_transformed_vertex_buffer); + } + } +} + + +//! Returns 1 if the m_transformed_vertex_buffer is a reply of m_source_vertex_buffer +char gim_trimesh_has_tranform(GIM_TRIMESH * trimesh) +{ + if(trimesh->m_mask&GIM_TRIMESH_APPLY_TRANSFORMATION) 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; +} + + + +//! Updates m_transformed_vertex_buffer +/*! +\pre m_transformed_vertex_buffer must be unlocked +*/ +void gim_trimesh_update_vertices(GIM_TRIMESH * trimesh) +{ + if(trimesh->m_cache == 0) return; + if(gim_trimesh_has_tranform(trimesh) == 0) return; //Don't perform transformation + + if(GIM_DYNARRAY_IS_VALID( trimesh->m_cache->m_transformed_vertices_cache_bitset)) + { + GIM_BITSET_CLEAR_ALL(trimesh->m_cache->m_transformed_vertices_cache_bitset); + return; + } + + +//transform vertices + mat4f transform; + COPY_MATRIX_4X4(transform,trimesh->m_transform); + + gim_trimesh_data_get(trimesh->m_trimesh_data_handle,&trimesh->m_unlocked_trimesh_data ); + + gim_transform_vertex_buffers( + &trimesh->m_unlocked_trimesh_data->m_source_vertex_buffer, + trimesh->m_unlocked_trimesh_data->m_vertex_scalar_type, + &trimesh->m_cache->m_transformed_vertex_buffer,trimesh->m_cache->m_tranformed_scalar_type,transform); + + trimesh->m_unlocked_trimesh_data = 0; +} + +void gim_trimesh_update_cache(GIM_TRIMESH * trimesh) +{ + if(trimesh->m_cache == 0) return; + //Clear planes cache + GIM_BITSET_CLEAR_ALL(trimesh->m_cache->m_planes_cache_bitset); + gim_trimesh_update_vertices(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) +{ + if(trimesh->m_aabbset == 0) return; + assert(trimesh->m_cache); + assert(GIM_BUFFER_ARRAY_IS_VALID(trimesh->m_cache->m_transformed_vertex_buffer)); + + vec3f * vertices = GIM_BUFFER_ARRAY_POINTER(vec3f,trimesh->m_cache->m_transformed_vertex_buffer,0); + + // box set + aabb3f * paabb = trimesh->m_aabbset->m_boxes; + GUINT triangle_count = gim_trimesh_get_triangle_count(trimesh); + vec3ui triangle_indices; + GUINT i; + for (i=0; im_unlocked_trimesh_data,i,triangle_indices); + COMPUTEAABB_FOR_TRIANGLE((*paabb), + vertices[triangle_indices[0]], + vertices[triangle_indices[1]],vertices[triangle_indices[2]]); + paabb++; + } + + //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_cache(trimesh); + + if(trimesh->m_aabbset!=0) + { + 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(GIM_IS_ZERO(diff)) return ;///don't need to update + //if(diff< 0.0006f) return ;///don't need to update + + COPY_MATRIX_4X4(trimesh->m_transform,transform); + + GREAL det; + INVERT_4X4(trimesh->m_inv_transform,det,transform); + + gim_trimesh_post_update(trimesh); +} + +void gim_trimesh_get_triangle_data(GIM_TRIMESH * trimesh, GUINT triangle_index, GIM_TRIANGLE_DATA * tri_data) +{ + gim_trimesh_get_triangle_vertices(trimesh,triangle_index, + tri_data->m_vertices[0], + tri_data->m_vertices[1], + tri_data->m_vertices[2]); + + if(trimesh->m_cache) + { + //Get the planes + GIM_TRIPLANES_CACHE * planes = GIM_DYNARRAY_POINTER(GIM_TRIPLANES_CACHE,trimesh->m_cache->m_planes_cache_buffer); + planes += triangle_index; + + //verify planes cache + char bit_eval; + GIM_BITSET_GET(trimesh->m_cache->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_cache->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 + tri_data->m_has_planes = 1; + return; + } + GIM_CALC_TRIANGLE_DATA_PLANES((*tri_data)); + tri_data->m_has_planes = 1; +} + +void gim_trimesh_get_triangle_data_lazy(GIM_TRIMESH * trimesh, GUINT triangle_index, GIM_TRIANGLE_DATA * tri_data) +{ + gim_trimesh_get_triangle_vertices(trimesh,triangle_index, + tri_data->m_vertices[0], + tri_data->m_vertices[1], + tri_data->m_vertices[2]); + + if(trimesh->m_cache) + { + //Get the planes + GIM_TRIPLANES_CACHE * planes = GIM_DYNARRAY_POINTER(GIM_TRIPLANES_CACHE,trimesh->m_cache->m_planes_cache_buffer); + planes += triangle_index; + + //verify planes cache + char bit_eval; + GIM_BITSET_GET(trimesh->m_cache->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_cache->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 + tri_data->m_has_planes = 1; + return; + } + tri_data->m_has_planes = 0; + +} + +void gim_trimesh_get_aabb(GIM_TRIMESH * trimesh,aabb3f * bound) +{ + if(trimesh->m_aabbset) + { + AABB_COPY((*bound),trimesh->m_aabbset->m_global_bound); + return; + } + + if(gim_trimesh_data_has_bv_tree(trimesh->m_trimesh_data_handle)) + { + gim_trimesh_data_get(trimesh->m_trimesh_data_handle,&trimesh->m_unlocked_trimesh_data); + if(gim_trimesh_has_tranform(trimesh)) + { + AABB_TRANSFORM((*bound), + trimesh->m_unlocked_trimesh_data->m_bv_tree.m_root_node->m_data.m_aabb, + trimesh->m_transform); + } + else + { + AABB_COPY((*bound),trimesh->m_unlocked_trimesh_data->m_bv_tree.m_root_node->m_data.m_aabb); + } + trimesh->m_unlocked_trimesh_data = 0; + return; + } +} + + +void gim_trimesh_midphase_box_collision(GIM_TRIMESH * trimesh,aabb3f *test_aabb, GDYNAMIC_ARRAY * collided) +{ + collided->m_size = 0; + if(gim_trimesh_get_bound_method(trimesh)==G_TRIMESH_BOUND_AABB_TREE) + { + GIM_TRIMESH_DATA * tridata; + gim_trimesh_data_get(trimesh->m_trimesh_data_handle,&tridata); + aabb3f transbound; + AABB_TRANSFORM(transbound,(*test_aabb),trimesh->m_inv_transform); + gim_aabbtree_box_collision(&transbound,&tridata->m_bv_tree,collided); + } + else if(gim_trimesh_get_bound_method(trimesh)==G_TRIMESH_BOUND_AABB_SET) + { + gim_aabbset_box_collision(test_aabb,trimesh->m_aabbset,collided); + } +} + +void gim_trimesh_midphase_box_collision_local(GIM_TRIMESH * trimesh,aabb3f *test_aabb, GDYNAMIC_ARRAY * collided) +{ + collided->m_size = 0; + if(gim_trimesh_get_bound_method(trimesh)==G_TRIMESH_BOUND_AABB_TREE) + { + GIM_TRIMESH_DATA * tridata; + gim_trimesh_data_get(trimesh->m_trimesh_data_handle,&tridata); + gim_aabbtree_box_collision(test_aabb,&tridata->m_bv_tree,collided); + } + else if(gim_trimesh_get_bound_method(trimesh)==G_TRIMESH_BOUND_AABB_SET) + { + gim_aabbset_box_collision(test_aabb,trimesh->m_aabbset,collided); + } +} + +void gim_trimesh_midphase_trimesh_collision(GIM_TRIMESH * trimesh1, +GIM_TRIMESH * trimesh2, GDYNAMIC_ARRAY * collision_pairs, char * swaped) +{ + collision_pairs->m_size = 0; + GIM_TRIMESH_DATA * tridata1; + GIM_TRIMESH_DATA * tridata2; + if(gim_trimesh_get_bound_method(trimesh1)==G_TRIMESH_BOUND_AABB_TREE) + { + gim_trimesh_data_get(trimesh1->m_trimesh_data_handle,&tridata1); + if(gim_trimesh_get_bound_method(trimesh2)==G_TRIMESH_BOUND_AABB_TREE) + { + *swaped = 0; + gim_trimesh_data_get(trimesh2->m_trimesh_data_handle,&tridata2); + + gim_aabbtree_bipartite_intersections_trans( + &tridata1->m_bv_tree, + &tridata2->m_bv_tree, + trimesh1->m_transform, + trimesh1->m_inv_transform, + trimesh2->m_transform, + trimesh2->m_inv_transform, + collision_pairs); + } + else if(gim_trimesh_get_bound_method(trimesh2)==G_TRIMESH_BOUND_AABB_SET) + { + *swaped = 1; + + gim_aabbset_aabbtree_intersections_trans( + trimesh2->m_aabbset, + &tridata1->m_bv_tree, + trimesh1->m_transform, + trimesh1->m_inv_transform, + collision_pairs); + } + } + else if(gim_trimesh_get_bound_method(trimesh1)==G_TRIMESH_BOUND_AABB_SET) + { + *swaped = 0; + if(gim_trimesh_get_bound_method(trimesh2)==G_TRIMESH_BOUND_AABB_TREE) + { + gim_trimesh_data_get(trimesh2->m_trimesh_data_handle,&tridata2); + + gim_aabbset_aabbtree_intersections_trans( + trimesh1->m_aabbset, + &tridata2->m_bv_tree, + trimesh2->m_transform, + trimesh2->m_inv_transform, + collision_pairs); + } + else if(gim_trimesh_get_bound_method(trimesh2)==G_TRIMESH_BOUND_AABB_SET) + { + gim_aabbset_bipartite_intersections( + trimesh1->m_aabbset, + trimesh2->m_aabbset, + collision_pairs); + } + } +} + diff --git a/Extras/GIMPACT/src/gim_trimesh_capsule_collision.cpp b/Extras/GIMPACT/src/gim_trimesh_capsule_collision.cpp new file mode 100644 index 000000000..5d6f16bec --- /dev/null +++ b/Extras/GIMPACT/src/gim_trimesh_capsule_collision.cpp @@ -0,0 +1,281 @@ + +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that 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, GIMPACT-LICENSE-ZLIB.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(!GIM_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(GIM_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_trimesh_midphase_box_collision(trimesh,&test_aabb,&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/Extras/GIMPACT/src/gim_trimesh_data.cpp b/Extras/GIMPACT/src/gim_trimesh_data.cpp new file mode 100644 index 000000000..66ade477d --- /dev/null +++ b/Extras/GIMPACT/src/gim_trimesh_data.cpp @@ -0,0 +1,454 @@ + +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that 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, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + +#include "GIMPACT/gim_trimesh_data.h" + +GDYNAMIC_ARRAY g_trimesh_data_array; +GDYNAMIC_ARRAY g_trimesh_data_free_positions; + + +void gim_trimesh_data_manager_init() +{ + GIM_DYNARRAY_CREATE(GIM_TRIMESH_DATA,g_trimesh_data_array,G_ARRAY_GROW_SIZE); + GIM_DYNARRAY_CREATE(GUINT,g_trimesh_data_free_positions,G_ARRAY_GROW_SIZE); +} + +void gim_trimesh_data_manager_end() +{ + //Destroy all trimeshes + GUINT i,tricount; + GIM_TRIMESH_DATA * trimeshes = GIM_DYNARRAY_POINTER(GIM_TRIMESH_DATA,g_trimesh_data_array); + tricount = g_trimesh_data_array.m_size; + + for (i=0;i0) + { + GUINT freeposition = *GIM_DYNARRAY_POINTER_LAST(GUINT,g_trimesh_data_free_positions); + GIM_DYNARRAY_POP_ITEM(g_trimesh_data_free_positions); + return freeposition+1; + } + GIM_DYNARRAY_PUSH_EMPTY(GIM_TRIMESH_DATA,g_trimesh_data_array); + return g_trimesh_data_array.m_size; +} + +void _gim_trimesh_data_free_handle(GUINT handle) +{ + if(gim_trimesh_data_is_valid_manager()==0) return; + GUINT freeposition = handle-1; + GIM_DYNARRAY_PUSH_ITEM(GUINT,g_trimesh_data_free_positions,freeposition); +} + + + +void gim_trimesh_data_get(GUINT trimesh_data_handle,GIM_TRIMESH_DATA ** trimesh_data) +{ + if(gim_trimesh_data_is_valid_manager()==0) + { + *trimesh_data = 0; + return; + } + GIM_TRIMESH_DATA * trimeshes = GIM_DYNARRAY_POINTER(GIM_TRIMESH_DATA,g_trimesh_data_array); + *trimesh_data = trimeshes+(trimesh_data_handle-1); +} + +void _gim_gim_trimesh_data_create_empty(GIM_TRIMESH_DATA * tridata) +{ + tridata->m_vertex_scalar_type = G_STYPE_REAL; + tridata->m_index_scalar_type = G_STYPE_UINT; + tridata->m_ref_count = 0; + //Init bvh + tridata->m_bv_tree.m_node_array = 0; + tridata->m_bv_tree.m_num_nodes = 0; + tridata->m_bv_tree.m_root_node = 0; + tridata->m_bv_tree.m_nodes_array_size = 0; + + //Reference buffer arrays + tridata->m_source_vertex_buffer.m_buffer_data = 0; + tridata->m_source_vertex_buffer.m_buffer_id.m_buffer_id = G_UINT_INFINITY; + tridata->m_source_vertex_buffer.m_element_count = 0; + + tridata->m_tri_index_buffer.m_buffer_data = 0; + tridata->m_tri_index_buffer.m_buffer_id.m_buffer_id = G_UINT_INFINITY; + tridata->m_tri_index_buffer.m_element_count = 0; +} + + + +void _gim_gim_trimesh_data_build_from_arrays(GIM_TRIMESH_DATA * tridata,GBUFFER_ARRAY * vertex_array,GUINT vertex_scalar_type, GBUFFER_ARRAY * triindex_array,GUINT index_scalar_type) +{ + tridata->m_vertex_scalar_type = vertex_scalar_type; + tridata->m_index_scalar_type = index_scalar_type; + tridata->m_ref_count = 0; + //Init bvh + tridata->m_bv_tree.m_node_array = 0; + tridata->m_bv_tree.m_num_nodes = 0; + tridata->m_bv_tree.m_root_node = 0; + tridata->m_bv_tree.m_nodes_array_size = 0; + + //Reference buffer arrays + gim_buffer_array_copy_ref(vertex_array,&tridata->m_source_vertex_buffer); + gim_buffer_array_copy_ref(triindex_array,&tridata->m_tri_index_buffer); +} + +void _gim_gim_trimesh_data_destroy_data(GIM_TRIMESH_DATA * tridata) +{ + GIM_BUFFER_ARRAY_DESTROY(tridata->m_source_vertex_buffer); + GIM_BUFFER_ARRAY_DESTROY(tridata->m_tri_index_buffer); + gim_aabbtree_destroy(&tridata->m_bv_tree); +} + +void gim_trimesh_data_create_empty(GUINT * trimesh_data_handle) +{ + *trimesh_data_handle = _gim_trimesh_data_get_avaliable_pos(); + if(*trimesh_data_handle == 0) return ; //an error ocurred + GIM_TRIMESH_DATA * tridata; + + gim_trimesh_data_get(*trimesh_data_handle,&tridata); + + //init trimesh + tridata->m_handle = *trimesh_data_handle; + + _gim_gim_trimesh_data_create_empty(tridata); +} + +void gim_trimesh_data_create_from_arrays(GUINT * trimesh_data_handle, GBUFFER_ARRAY * vertex_array,GUINT vertex_scalar_type, GBUFFER_ARRAY * triindex_array,GUINT index_scalar_type) +{ + *trimesh_data_handle = _gim_trimesh_data_get_avaliable_pos(); + if(*trimesh_data_handle == 0) return ; //an error ocurred + GIM_TRIMESH_DATA * tridata; + + gim_trimesh_data_get(*trimesh_data_handle,&tridata); + + //init trimesh + tridata->m_handle = *trimesh_data_handle; + //construct + _gim_gim_trimesh_data_build_from_arrays(tridata,vertex_array,vertex_scalar_type,triindex_array,index_scalar_type); +} + +void gim_trimesh_data_create_from_array_data(GUINT * trimesh_data_handle, vec3f * vertex_array, GUINT vertex_count,char copy_vertices, GUINT * triindex_array, GUINT triangle_count,char copy_indices) +{ + if(gim_trimesh_data_is_valid_manager()==0) + { + *trimesh_data_handle = 0; + return; + } + + 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, triangle_count*sizeof(vec3ui), &buffer_triindex_array.m_buffer_id); + } + else//Create a shared buffer + { + gim_create_shared_buffer_from_data(triindex_array, triangle_count*sizeof(vec3ui), &buffer_triindex_array.m_buffer_id); + } + GIM_BUFFER_ARRAY_INIT_TYPE(vec3ui,buffer_triindex_array,buffer_triindex_array.m_buffer_id,triangle_count); + + gim_trimesh_data_create_from_arrays(trimesh_data_handle, &buffer_vertex_array,G_STYPE_REAL, &buffer_triindex_array,G_STYPE_UINT); + + ///always call this after create a buffer_array + GIM_BUFFER_ARRAY_DESTROY(buffer_vertex_array); + GIM_BUFFER_ARRAY_DESTROY(buffer_triindex_array); +} + +void gim_trimesh_data_inc_ref(GUINT trimesh_data_handle) +{ + if(gim_trimesh_data_is_valid_manager()==0) return; + GIM_TRIMESH_DATA * tridata; + gim_trimesh_data_get(trimesh_data_handle,&tridata); + tridata->m_ref_count++; +} + +void gim_trimesh_data_dec_ref(GUINT trimesh_data_handle) +{ + if(gim_trimesh_data_is_valid_manager()==0) return; + GIM_TRIMESH_DATA * tridata; + gim_trimesh_data_get(trimesh_data_handle,&tridata); + if(tridata->m_ref_count==0) + { + //Attemps to destroy the trimesh + gim_trimesh_data_destroy(trimesh_data_handle); + return; + } + tridata->m_ref_count--; + + if(tridata->m_ref_count==0) + { + //Attemps to destroy the trimesh + gim_trimesh_data_destroy(trimesh_data_handle); + } +} + +void gim_trimesh_data_destroy(GUINT trimesh_data_handle) +{ + if(gim_trimesh_data_is_valid_manager()==0) return; + GIM_TRIMESH_DATA * tridata; + gim_trimesh_data_get(trimesh_data_handle,&tridata); + if(tridata->m_ref_count>0) return; //Can't destroy it now + + _gim_gim_trimesh_data_destroy_data(tridata); + + //Get a free position + _gim_trimesh_data_free_handle(trimesh_data_handle); +} + +void gim_trimesh_data_lock(GUINT trimesh_data_handle, int access,GIM_TRIMESH_DATA ** trimesh_data) +{ + if(gim_trimesh_data_is_valid_manager()==0) return; + gim_trimesh_data_get(trimesh_data_handle,trimesh_data); + gim_buffer_array_lock(&(*trimesh_data)->m_source_vertex_buffer,access); + gim_buffer_array_lock(&(*trimesh_data)->m_tri_index_buffer,access); +} + + + +void gim_trimesh_data_unlock(GUINT trimesh_data_handle) +{ + if(gim_trimesh_data_is_valid_manager()==0) return; + GIM_TRIMESH_DATA * tridata; + gim_trimesh_data_get(trimesh_data_handle,&tridata); + gim_buffer_array_unlock(&tridata->m_source_vertex_buffer); + gim_buffer_array_unlock(&tridata->m_tri_index_buffer); +} + +GUINT gim_trimesh_data_get_vertex_count(GUINT trimesh_data_handle) +{ + GIM_TRIMESH_DATA * tridata; + gim_trimesh_data_get(trimesh_data_handle,&tridata); + return tridata->m_source_vertex_buffer.m_element_count; +} + +GUINT gim_trimesh_data_get_triangle_count(GUINT trimesh_data_handle) +{ + GIM_TRIMESH_DATA * tridata; + gim_trimesh_data_get(trimesh_data_handle,&tridata); + return tridata->m_tri_index_buffer.m_element_count; +} + +void gim_trimesh_data_get_triangle_indices(GIM_TRIMESH_DATA * trimesh_data, GUINT tri_index, GUINT * indices) +{ + if(trimesh_data->m_index_scalar_type == G_STYPE_UINT) + { + GUINT * uipindices = GIM_BUFFER_ARRAY_POINTER(GUINT,trimesh_data->m_tri_index_buffer,tri_index); + indices[0] = uipindices[0]; + indices[1] = uipindices[1]; + indices[2] = uipindices[2]; + } + else if(trimesh_data->m_index_scalar_type == G_STYPE_INT) + { + GINT * ipindices = GIM_BUFFER_ARRAY_POINTER(GINT,trimesh_data->m_tri_index_buffer,tri_index); + indices[0] = ipindices[0]; + indices[1] = ipindices[1]; + indices[2] = ipindices[2]; + } + else if(trimesh_data->m_index_scalar_type == G_STYPE_USHORT) + { + GUSHORT * uspindices = GIM_BUFFER_ARRAY_POINTER(GUSHORT,trimesh_data->m_tri_index_buffer,tri_index); + indices[0] = uspindices[0]; + indices[1] = uspindices[1]; + indices[2] = uspindices[2]; + } + else if(trimesh_data->m_index_scalar_type == G_STYPE_SHORT) + { + GSHORT * spindices = GIM_BUFFER_ARRAY_POINTER(GSHORT,trimesh_data->m_tri_index_buffer,tri_index); + indices[0] = spindices[0]; + indices[1] = spindices[1]; + indices[2] = spindices[2]; + } +} + +void gim_trimesh_data_get_vertex(GIM_TRIMESH_DATA * trimesh_data, GUINT vertex_index, vec3f vec) +{ + if(trimesh_data->m_vertex_scalar_type == G_STYPE_REAL) + { + GREAL * rvalues = GIM_BUFFER_ARRAY_POINTER(GREAL,trimesh_data->m_source_vertex_buffer,vertex_index); + vec[0] = rvalues[0]; + vec[1] = rvalues[1]; + vec[2] = rvalues[2]; + } + else if(trimesh_data->m_vertex_scalar_type == G_STYPE_REAL2) + { + GREAL2 * r2values = GIM_BUFFER_ARRAY_POINTER(GREAL2,trimesh_data->m_source_vertex_buffer,vertex_index); + vec[0] = r2values[0]; + vec[1] = r2values[1]; + vec[2] = r2values[2]; + } +} + +void gim_trimesh_data_get_triangle_vertices(GIM_TRIMESH_DATA * trimesh_data, GUINT tri_index, vec3f v1, vec3f v2, vec3f v3) +{ + GUINT tri_indices[3]; + gim_trimesh_data_get_triangle_indices(trimesh_data,tri_index,tri_indices); + + if(trimesh_data->m_vertex_scalar_type == G_STYPE_REAL) + { + GREAL * rvalues = GIM_BUFFER_ARRAY_POINTER(GREAL,trimesh_data->m_source_vertex_buffer,tri_indices[0]); + VEC_COPY(v1,rvalues); + + rvalues = GIM_BUFFER_ARRAY_POINTER(GREAL,trimesh_data->m_source_vertex_buffer,tri_indices[1]); + VEC_COPY(v2,rvalues); + + rvalues = GIM_BUFFER_ARRAY_POINTER(GREAL,trimesh_data->m_source_vertex_buffer,tri_indices[2]); + VEC_COPY(v3,rvalues); + } + else if(trimesh_data->m_vertex_scalar_type == G_STYPE_REAL2) + { + GREAL2 * r2values = GIM_BUFFER_ARRAY_POINTER(GREAL2,trimesh_data->m_source_vertex_buffer,tri_indices[0]); + VEC_COPY(v1,r2values); + + r2values = GIM_BUFFER_ARRAY_POINTER(GREAL2,trimesh_data->m_source_vertex_buffer,tri_indices[1]); + VEC_COPY(v2,r2values); + + r2values = GIM_BUFFER_ARRAY_POINTER(GREAL2,trimesh_data->m_source_vertex_buffer,tri_indices[2]); + VEC_COPY(v3,r2values); + } +} + +void gim_trimesh_data_build_aabbtree(GUINT trimesh_data_handle) +{ + if(gim_trimesh_data_is_valid_manager()==0) return; + GIM_TRIMESH_DATA * tridata; + gim_trimesh_data_lock(trimesh_data_handle, G_MA_READ_ONLY,&tridata); + + GUINT i,tricount; + tricount = gim_trimesh_data_get_triangle_count(trimesh_data_handle); + GIM_AABB_DATA * boxarray = (GIM_AABB_DATA *)gim_alloc(tricount*sizeof(GIM_AABB_DATA)); + + vec3f trivertices[3]; + + for (i=0;im_bv_tree,boxarray,tricount); + gim_free(boxarray,0); +} + +int gim_trimesh_data_has_bv_tree(GUINT trimesh_data_handle) +{ + GIM_TRIMESH_DATA * tridata; + gim_trimesh_data_get(trimesh_data_handle,&tridata); + + if(tridata->m_bv_tree.m_node_array == 0) return 0; + return 1; +} + + +void gim_trimesh_data_copy(GUINT source_trimesh_data,GUINT dest_trimesh_data, char copy_by_reference) +{ + if(gim_trimesh_data_is_valid_manager()==0) return; + GIM_TRIMESH_DATA * sourcetridata; + gim_trimesh_data_get(source_trimesh_data,&sourcetridata); + + GIM_TRIMESH_DATA * desttridata; + gim_trimesh_data_get(dest_trimesh_data,&desttridata); + + _gim_gim_trimesh_data_destroy_data(desttridata);//Clear previus data + + if(copy_by_reference==1) + { + _gim_gim_trimesh_data_build_from_arrays(desttridata, &sourcetridata->m_source_vertex_buffer, + sourcetridata->m_vertex_scalar_type, &sourcetridata->m_tri_index_buffer, + sourcetridata->m_index_scalar_type); + } + else + { + GBUFFER_ARRAY buffer_vertex_array; + GBUFFER_ARRAY buffer_triindex_array; + + gim_buffer_array_copy_value(&sourcetridata->m_source_vertex_buffer,&buffer_vertex_array,G_BUFFER_MANAGER_SYSTEM,G_MU_DYNAMIC_READ_WRITE); + + gim_buffer_array_copy_value(&sourcetridata->m_tri_index_buffer,&buffer_triindex_array,G_BUFFER_MANAGER_SYSTEM,G_MU_DYNAMIC_READ_WRITE); + + _gim_gim_trimesh_data_build_from_arrays(desttridata, &buffer_vertex_array, + sourcetridata->m_vertex_scalar_type, &buffer_triindex_array, + sourcetridata->m_index_scalar_type); + + ///always call this after create a buffer_array + GIM_BUFFER_ARRAY_DESTROY(buffer_vertex_array); + GIM_BUFFER_ARRAY_DESTROY(buffer_triindex_array); + } + + //If it has a Bounding volume tree, construct it + + if(gim_trimesh_data_has_bv_tree(source_trimesh_data)) + { + gim_trimesh_data_build_aabbtree(dest_trimesh_data); + } +} + + +void gim_trimesh_data_create_copy(GUINT source_trimesh_data,GUINT * dest_trimesh_data, char copy_by_reference) +{ + if(gim_trimesh_data_is_valid_manager()==0) return; + gim_trimesh_data_create_empty(dest_trimesh_data); + gim_trimesh_data_copy(source_trimesh_data,*dest_trimesh_data, copy_by_reference); +} diff --git a/Extras/GIMPACT/src/gim_trimesh_ray_collision.cpp b/Extras/GIMPACT/src/gim_trimesh_ray_collision.cpp new file mode 100644 index 000000000..5482b0400 --- /dev/null +++ b/Extras/GIMPACT/src/gim_trimesh_ray_collision.cpp @@ -0,0 +1,180 @@ + +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that 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, GIMPACT-LICENSE-ZLIB.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); + + if(trimesh->m_aabbset) + { + gim_aabbset_ray_collision(origin,dir,tmax,trimesh->m_aabbset, + &collision_result); + } + else if(gim_trimesh_get_bound_method(trimesh)==G_TRIMESH_BOUND_AABB_TREE) + { + vec3f torigin, tdir; + gim_trimesh_data_get(trimesh->m_trimesh_data_handle, + &trimesh->m_unlocked_trimesh_data); + + MAT_DOT_VEC_3X4(torigin,trimesh->m_inv_transform,dir); + MAT_DOT_VEC_3X3(tdir,trimesh->m_inv_transform,dir); + gim_aabbtree_ray_collision( + torigin,tdir, tmax, + &trimesh->m_unlocked_trimesh_data->m_bv_tree, &collision_result); + + trimesh->m_unlocked_trimesh_data = 0; + + } + + 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); + + if(trimesh->m_aabbset) + { + gim_aabbset_ray_collision(origin,dir,tmax,trimesh->m_aabbset, + &collision_result); + } + else if(gim_trimesh_get_bound_method(trimesh)==G_TRIMESH_BOUND_AABB_TREE) + { + vec3f torigin, tdir; + gim_trimesh_data_get(trimesh->m_trimesh_data_handle, + &trimesh->m_unlocked_trimesh_data); + + MAT_DOT_VEC_3X4(torigin,trimesh->m_inv_transform,dir); + MAT_DOT_VEC_3X3(tdir,trimesh->m_inv_transform,dir); + gim_aabbtree_ray_collision( + torigin,tdir, tmax, + &trimesh->m_unlocked_trimesh_data->m_bv_tree, &collision_result); + + trimesh->m_unlocked_trimesh_data = 0; + + } + + 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/Extras/GIMPACT/src/gim_trimesh_sphere_collision.cpp b/Extras/GIMPACT/src/gim_trimesh_sphere_collision.cpp new file mode 100644 index 000000000..83a9a8e2d --- /dev/null +++ b/Extras/GIMPACT/src/gim_trimesh_sphere_collision.cpp @@ -0,0 +1,198 @@ + +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that 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, GIMPACT-LICENSE-ZLIB.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(GIM_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_trimesh_midphase_box_collision(trimesh,&test_aabb,&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;imaxdeep)\ + {\ + 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);\ + }\ + }\ +}\ + + +static 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; + + if(tri2->m_has_planes==0) + { + TRIANGLE_PLANE(tri2->m_vertices[0], + tri2->m_vertices[1],tri2->m_vertices[2],tri2->m_planes.m_planes[0]); + } + //Fast overlapp + 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; + + if(tri1->m_has_planes==0) + { + TRIANGLE_PLANE(tri1->m_vertices[0],tri1->m_vertices[1], + tri1->m_vertices[2],tri1->m_planes.m_planes[0]); + } + //Fast overlapp + 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; + + /* + + if(tri1->m_has_planes==0) + { + EDGE_PLANE(tri1->m_vertices[0],tri1->m_vertices[1], + (tri1->m_planes.m_planes[0]),(tri1->m_planes.m_planes[1])); + + } + + + //Fast overlapp + CLASSIFY_TRI_BY_PLANE(tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2],tri1->m_planes.m_planes[1],out_of_face); + if(out_of_face==1) return 0; + + if(tri1->m_has_planes==0) + { + EDGE_PLANE(tri1->m_vertices[1],tri1->m_vertices[2], + (tri1->m_planes.m_planes[0]),(tri1->m_planes.m_planes[2])); + + } + + //Fast overlapp + CLASSIFY_TRI_BY_PLANE(tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2],tri1->m_planes.m_planes[2],out_of_face); + if(out_of_face==1) return 0; + + if(tri1->m_has_planes==0) + { + + EDGE_PLANE(tri1->m_vertices[2],tri1->m_vertices[0], + (tri1->m_planes.m_planes[0]),(tri1->m_planes.m_planes[3])); + + } + + //Fast overlapp + CLASSIFY_TRI_BY_PLANE(tri2->m_vertices[0],tri2->m_vertices[1],tri2->m_vertices[2],tri1->m_planes.m_planes[3],out_of_face); + if(out_of_face==1) return 0; + + if(tri2->m_has_planes==0) + { + EDGE_PLANE(tri2->m_vertices[0],tri2->m_vertices[1], + (tri2->m_planes.m_planes[0]),(tri2->m_planes.m_planes[1])); + EDGE_PLANE(tri2->m_vertices[1],tri2->m_vertices[2], + (tri2->m_planes.m_planes[0]),(tri2->m_planes.m_planes[2])); + EDGE_PLANE(tri2->m_vertices[2],tri2->m_vertices[0], + (tri2->m_planes.m_planes[0]),(tri2->m_planes.m_planes[3])); + }*/ + + if(tri1->m_has_planes==0) + { + EDGE_PLANE(tri1->m_vertices[0],tri1->m_vertices[1], + (tri1->m_planes.m_planes[0]),(tri1->m_planes.m_planes[1])); + EDGE_PLANE(tri1->m_vertices[1],tri1->m_vertices[2], + (tri1->m_planes.m_planes[0]),(tri1->m_planes.m_planes[2])); + EDGE_PLANE(tri1->m_vertices[2],tri1->m_vertices[0], + (tri1->m_planes.m_planes[0]),(tri1->m_planes.m_planes[3])); + } + + if(tri2->m_has_planes==0) + { + EDGE_PLANE(tri2->m_vertices[0],tri2->m_vertices[1], + (tri2->m_planes.m_planes[0]),(tri2->m_planes.m_planes[1])); + EDGE_PLANE(tri2->m_vertices[1],tri2->m_vertices[2], + (tri2->m_planes.m_planes[0]),(tri2->m_planes.m_planes[2])); + EDGE_PLANE(tri2->m_vertices[2],tri2->m_vertices[0], + (tri2->m_planes.m_planes[0]),(tri2->m_planes.m_planes[3])); + } + + 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); + + char swaped; + gim_trimesh_midphase_trimesh_collision(trimesh1,trimesh2,&collision_pairs,&swaped); + + 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 + GUINT *pairs = GIM_DYNARRAY_POINTER(GUINT,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; + aabb3f bound; + gim_trimesh_get_aabb(trimesh,&bound); + PLANE_CLASSIFY_BOX(plane,bound,classify); + if(classify>1) return; // in front of plane + + //Locks mesh + gim_trimesh_locks_work_data(trimesh); + //Get vertices + GUINT i, vertcount = gim_trimesh_get_vertex_count(trimesh); + vec3f vec; + + GREAL dist; + vec4f * result_contact; + + for (i=0;im_buffer_id); + GIM_BUFFER_ARRAY_INIT_TYPE(vec3f,(*vertex_buffer),vertex_buffer->m_buffer_id,vertex_count); +} + + +void gim_copy_vertex_buffers(GBUFFER_ARRAY * source_vertex_buffer,GUINT source_scalar_type,GBUFFER_ARRAY * dest_vertex_buffer,GUINT dest_scalar_type) +{ + GIM_PROCESS_VERTEX_BUFFER_ARRAY(0,(*source_vertex_buffer),(*dest_vertex_buffer),COPY_VEC3_KERNEL,source_scalar_type,dest_scalar_type); +} + + +void gim_transform_vertex_buffers(GBUFFER_ARRAY * source_vertex_buffer,GUINT source_scalar_type,GBUFFER_ARRAY * dest_vertex_buffer,GUINT dest_scalar_type, mat4f transform) +{ + GIM_PROCESS_VERTEX_BUFFER_ARRAY(transform,(*source_vertex_buffer),(*dest_vertex_buffer),MULT_MAT_VEC4_KERNEL,source_scalar_type,dest_scalar_type); +} + +void gim_process_vertex_buffers(GBUFFER_ARRAY * source_vertex_buffer,GUINT source_scalar_type,GBUFFER_ARRAY * dest_vertex_buffer,GUINT dest_scalar_type, void *uniform_data,gim_kernel_func kernel_func) +{ + GIM_PROCESS_VERTEX_BUFFER_ARRAY(uniform_data,(*source_vertex_buffer),(*dest_vertex_buffer),kernel_func,source_scalar_type,dest_scalar_type); +} diff --git a/Extras/GIMPACT/src/gimpact.cpp b/Extras/GIMPACT/src/gimpact.cpp new file mode 100644 index 000000000..58d5b5505 --- /dev/null +++ b/Extras/GIMPACT/src/gimpact.cpp @@ -0,0 +1,43 @@ + +/* +----------------------------------------------------------------------------- +This source file is part of GIMPACT Library. + +For the latest info, see http://gimpact.sourceforge.net/ + +Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. +email: projectileman@yahoo.com + + This library is free software; you can redistribute it and/or + modify it under the terms of EITHER: + (1) The GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at + your option) any later version. The text of the GNU Lesser + General Public License is included with this library in the + file GIMPACT-LICENSE-LGPL.TXT. + (2) The BSD-style license that is included with this library in + the file GIMPACT-LICENSE-BSD.TXT. + (3) The zlib/libpng license that is included with this library in + the file GIMPACT-LICENSE-ZLIB.TXT. + + This library is distributed in the hope that 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, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details. + +----------------------------------------------------------------------------- +*/ + +#include "GIMPACT/gimpact.h" + +void gimpact_init() +{ + gim_init_math(); + gim_init_buffer_managers(); + gim_trimesh_data_manager_init(); +} +void gimpact_terminate() +{ + gim_terminate_buffer_managers(); + gim_trimesh_data_manager_end(); +} diff --git a/Extras/GIMPACTBullet/Jamfile b/Extras/GIMPACTBullet/Jamfile new file mode 100644 index 000000000..e2fb763d9 --- /dev/null +++ b/Extras/GIMPACTBullet/Jamfile @@ -0,0 +1,10 @@ +SubDir TOP Extras GIMPACTBullet ; + +IncludeDir Extras/GIMPACTBullet ; + +Library GIMPACTBullet : [ Wildcard *.h *.cpp ] ; +CFlags GIMPACTBullet : [ FIncludes $(TOP)/Extras/GIMPACTBullet ] ; +LibDepends GIMPACTBullet : ; + + +InstallHeader [ Wildcard *.h ] : GIMPACTBullet ; diff --git a/Extras/GIMPACTBullet/btConcaveConcaveCollisionAlgorithm.cpp b/Extras/GIMPACTBullet/btConcaveConcaveCollisionAlgorithm.cpp new file mode 100644 index 000000000..a768fd5ee --- /dev/null +++ b/Extras/GIMPACTBullet/btConcaveConcaveCollisionAlgorithm.cpp @@ -0,0 +1,136 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +/* +Author: Francisco León Nájera +Concave-Concave Collision + +*/ + +#include "BulletCollision/CollisionDispatch/btManifoldResult.h" +#include "LinearMath/btIDebugDraw.h" +#include "btConcaveConcaveCollisionAlgorithm.h" +#include "BulletCollision/CollisionDispatch/btCollisionObject.h" +#include "btGIMPACTMeshShape.h" +#include "../Extras/GIMPACT/include/GIMPACT/gimpact.h" + + +btConcaveConcaveCollisionAlgorithm::btConcaveConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) +: btCollisionAlgorithm(ci) +{ +} + +btConcaveConcaveCollisionAlgorithm::~btConcaveConcaveCollisionAlgorithm() +{ + clearCache(); +} + +void btConcaveConcaveCollisionAlgorithm::clearCache() +{ + btPersistentManifold* mainfold; + for (size_t i=0;im_mainfoldsPtr.size() ; i++) + { + mainfold = m_mainfoldsPtr[i]; + m_dispatcher->releaseManifold(mainfold); + } + m_mainfoldsPtr.clear(); +} + +btPersistentManifold* btConcaveConcaveCollisionAlgorithm::newContactMainfold(btCollisionObject* body0,btCollisionObject* body1) +{ + btPersistentManifold* newmainfold; + newmainfold = m_dispatcher->getNewManifold(body0,body1); + m_mainfoldsPtr.push_back(newmainfold); + return newmainfold; +} + +void process_gimpact_contacts(GIM_CONTACT * pcontacts, + int contact_count, + btConcaveConcaveCollisionAlgorithm * algorithm, + btCollisionObject* body0, + btCollisionObject* body1, + btManifoldResult* resultOut) +{ + int i, ci = MANIFOLD_CACHE_SIZE;//Max point size + btPersistentManifold * current_mainfold = 0; + + for(i=0;i=MANIFOLD_CACHE_SIZE) + { + current_mainfold = algorithm->newContactMainfold(body0,body1); + resultOut->setPersistentManifold(current_mainfold); + ci=0; + } + + btVector3 cpoint(pcontacts->m_point[0],pcontacts->m_point[1],pcontacts->m_point[2]); + //Normal points to body0 + btVector3 cnormal(pcontacts->m_normal[0],pcontacts->m_normal[1],pcontacts->m_normal[2]); + + resultOut->addContactPoint(cnormal,cpoint,-pcontacts->m_depth); + + pcontacts++; + ci++; + } + +} + +void btConcaveConcaveCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + clearCache(); + if (body0->getCollisionShape()->getShapeType()==GIMPACT_SHAPE_PROXYTYPE && body1->getCollisionShape()->getShapeType()==GIMPACT_SHAPE_PROXYTYPE ) + { + btGIMPACTMeshShape* tri0b = static_cast( body0->getCollisionShape()); + btGIMPACTMeshShape* tri1b = static_cast( body1->getCollisionShape()); + + tri0b->prepareMeshes(body0->getWorldTransform()); + tri1b->prepareMeshes(body1->getWorldTransform()); + + size_t i,j; + size_t parts0 = tri0b->m_gim_trimesh_parts.size(); + size_t parts1 = tri1b->m_gim_trimesh_parts.size(); + + GIM_TRIMESH * trimesh0; + GIM_TRIMESH * trimesh1; + GDYNAMIC_ARRAY contacts; + GIM_CONTACT * pcontacts; + for(i=0;im_gim_trimesh_parts[i]; + trimesh1 = (GIM_TRIMESH * )tri1b->m_gim_trimesh_parts[j]; + + GIM_CREATE_CONTACT_LIST(contacts); + + gim_trimesh_trimesh_collision(trimesh0,trimesh1,&contacts); + + if(contacts.m_size>0) + { + pcontacts = GIM_DYNARRAY_POINTER(GIM_CONTACT,contacts); + process_gimpact_contacts(pcontacts,contacts.m_size,this,body0,body1,resultOut); + } + GIM_DYNARRAY_DESTROY(contacts); + } + } + } +} + + +float btConcaveConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +{ + return 1.f; + +} diff --git a/Extras/GIMPACTBullet/btConcaveConcaveCollisionAlgorithm.h b/Extras/GIMPACTBullet/btConcaveConcaveCollisionAlgorithm.h new file mode 100644 index 000000000..29ddc5632 --- /dev/null +++ b/Extras/GIMPACTBullet/btConcaveConcaveCollisionAlgorithm.h @@ -0,0 +1,60 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef BVH_CONCAVE_COLLISION_ALGORITHM_H +#define BVH_CONCAVE_COLLISION_ALGORITHM_H + +#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" +#include "BulletCollision/BroadphaseCollision/btDispatcher.h" +#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" +#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" +#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" +class btDispatcher; +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" +#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" + + +/// btConcaveConcaveCollisionAlgorithm supports collision between btBvhTriangleMeshShape shapes +class btConcaveConcaveCollisionAlgorithm : public btCollisionAlgorithm +{ +protected: + std::vector m_mainfoldsPtr; +public: + + btConcaveConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1); + + virtual ~btConcaveConcaveCollisionAlgorithm(); + + virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + float calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + + void clearCache(); + + btPersistentManifold* newContactMainfold(btCollisionObject* body0,btCollisionObject* body1); + + struct CreateFunc :public btCollisionAlgorithmCreateFunc + { + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) + { + return new btConcaveConcaveCollisionAlgorithm(ci,body0,body1); + } + }; + + + +}; + +#endif //BVH_CONCAVE_COLLISION_ALGORITHM_H diff --git a/Extras/GIMPACTBullet/btGIMPACTMeshShape.cpp b/Extras/GIMPACTBullet/btGIMPACTMeshShape.cpp new file mode 100644 index 000000000..16cd409af --- /dev/null +++ b/Extras/GIMPACTBullet/btGIMPACTMeshShape.cpp @@ -0,0 +1,533 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +//#define DISABLE_BVH + + +#include "btGIMPACTMeshShape.h" +#include "GIMPACT/gimpact.h" + +int g_gimpact_references = 0; +//Mechanism for initialize and terminate GIMPACT structures +void increase_gimpact_reference() +{ + g_gimpact_references++; + + if(g_gimpact_references >1 ) return; + + gimpact_init(); + +} + +void decrease_gimpact_reference() +{ + if(g_gimpact_references <=0 ) return; + g_gimpact_references--; + if(g_gimpact_references >0 ) return; + gimpact_terminate(); +} + +/////////////////////////// btGIMPACTMeshData class///////////////////////////////////////////////////////////// + +void btGIMPACTMeshData::clearMeshParts() +{ + for(size_t i = 0;igetLockedReadOnlyVertexIndexBase(&vertexbase, numverts,stype,vertexStride,&indexbase, + indexstride,numfaces,indicestype,part); + + GUINT int_type; + switch (indicestype) + { + case PHY_INTEGER: + int_type = G_STYPE_INT; + break; + case PHY_SHORT: + int_type = G_STYPE_SHORT; + break; + } + + GUINT vert_type; + switch (stype) + { + case PHY_FLOAT: + vert_type = G_STYPE_REAL; + break; + case PHY_DOUBLE: + vert_type = G_STYPE_REAL2; + break; + } + + GBUFFER_ARRAY buffer_vertex_array; + GBUFFER_ARRAY buffer_triindex_array; + GUINT trimesh_data_handle; + + //Create shared buffer for indices + + gim_create_shared_buffer_from_data( + vertexbase, numverts*vertexStride, + &buffer_vertex_array.m_buffer_id); + + GIM_BUFFER_ARRAY_INIT_OFFSET_STRIDE( + buffer_vertex_array,buffer_vertex_array.m_buffer_id, + numverts,0,vertexStride); + + //Create shared buffer for vertices + gim_create_shared_buffer_from_data(indexbase, + numfaces*indexstride, &buffer_triindex_array.m_buffer_id); + + GIM_BUFFER_ARRAY_INIT_OFFSET_STRIDE( + buffer_triindex_array,buffer_triindex_array.m_buffer_id, + numfaces,0,indexstride); + + //Create the trimesh data + gim_trimesh_data_create_from_arrays( + &trimesh_data_handle, + &buffer_vertex_array,vert_type, + &buffer_triindex_array,int_type); + + //always call this after create a buffer_array + GIM_BUFFER_ARRAY_DESTROY(buffer_vertex_array); + GIM_BUFFER_ARRAY_DESTROY(buffer_triindex_array); + + //Build Bounding volume tree + gim_trimesh_data_build_aabbtree(trimesh_data_handle); + + gim_trimesh_data_inc_ref(trimesh_data_handle); + + m_meshes.push_back(trimesh_data_handle); + +} + +void btGIMPACTMeshData::processMeshParts(btStridingMeshInterface* meshInterface) +{ + clearMeshParts(); + this->m_meshInterface = meshInterface; + int meshcount = meshInterface->getNumSubParts(); + for(int i = 0;im_meshdata = meshdata; + + BT_GIMPACT_TRIMESH_HANDLE gimhandle; + GIM_TRIMESH * ptrimesh; + + for(size_t i = 0;im_meshes.size();i++) + { + ptrimesh = (GIM_TRIMESH *)gim_alloc(sizeof(GIM_TRIMESH)); + gim_trimesh_create(ptrimesh,m_meshdata->m_meshes[i],1,0); + gimhandle = (BT_GIMPACT_TRIMESH_HANDLE) ptrimesh; + m_gim_trimesh_parts.push_back(gimhandle); + } +} + +btGIMPACTMeshShape::btGIMPACTMeshShape(btGIMPACTMeshData * meshdata) +{ + processMeshParts(meshdata); +} + +btGIMPACTMeshShape::~btGIMPACTMeshShape() +{ + clearMeshParts(); +} + +void btGIMPACTMeshShape::prepareMeshes(const btTransform & trans) const +{ + mat4f gim_trans; + IDENTIFY_MATRIX_4X4(gim_trans); + COPY_MATRIX_3X3(gim_trans,trans.getBasis()); + + btVector3 scaling = getLocalScaling(); + + SCALE_VEC_MATRIX_3X3(gim_trans,scaling,gim_trans); + MAT_SET_TRANSLATION(gim_trans,trans.getOrigin()); + + GIM_TRIMESH * ptrimesh; + + for(size_t i = 0;i ny && nx > nz ) + C = 0; + else + C = (ny > nz) ? 1 : 2; + + A = (C + 1) % 3; + B = (A + 1) % 3; + + // calculate face integrals + { + float w; + float k1, k2, k3, k4; + + //compProjectionIntegrals(f); + { + float a0, a1, da; + float b0, b1, db; + float a0_2, a0_3, a0_4, b0_2, b0_3, b0_4; + float a1_2, a1_3, b1_2, b1_3; + float C1, Ca, Caa, Caaa, Cb, Cbb, Cbbb; + float Cab, Kab, Caab, Kaab, Cabb, Kabb; + + P1 = Pa = Pb = Paa = Pab = Pbb = Paaa = Paab = Pabb = Pbbb = 0.0; + + for( int j = 0; j < 3; j++) + { + switch(j) + { + case 0: + a0 = v0[A]; + b0 = v0[B]; + a1 = v1[A]; + b1 = v1[B]; + break; + case 1: + a0 = v1[A]; + b0 = v1[B]; + a1 = v2[A]; + b1 = v2[B]; + break; + case 2: + a0 = v2[A]; + b0 = v2[B]; + a1 = v0[A]; + b1 = v0[B]; + break; + } + da = a1 - a0; + db = b1 - b0; + a0_2 = a0 * a0; a0_3 = a0_2 * a0; a0_4 = a0_3 * a0; + b0_2 = b0 * b0; b0_3 = b0_2 * b0; b0_4 = b0_3 * b0; + a1_2 = a1 * a1; a1_3 = a1_2 * a1; + b1_2 = b1 * b1; b1_3 = b1_2 * b1; + + C1 = a1 + a0; + Ca = a1*C1 + a0_2; Caa = a1*Ca + a0_3; Caaa = a1*Caa + a0_4; + Cb = b1*(b1 + b0) + b0_2; Cbb = b1*Cb + b0_3; Cbbb = b1*Cbb + b0_4; + Cab = 3*a1_2 + 2*a1*a0 + a0_2; Kab = a1_2 + 2*a1*a0 + 3*a0_2; + Caab = a0*Cab + 4*a1_3; Kaab = a1*Kab + 4*a0_3; + Cabb = 4*b1_3 + 3*b1_2*b0 + 2*b1*b0_2 + b0_3; + Kabb = b1_3 + 2*b1_2*b0 + 3*b1*b0_2 + 4*b0_3; + + P1 += db*C1; + Pa += db*Ca; + Paa += db*Caa; + Paaa += db*Caaa; + Pb += da*Cb; + Pbb += da*Cbb; + Pbbb += da*Cbbb; + Pab += db*(b1*Cab + b0*Kab); + Paab += db*(b1*Caab + b0*Kaab); + Pabb += da*(a1*Cabb + a0*Kabb); + } + + P1 /= 2.0; + Pa /= 6.0; + Paa /= 12.0; + Paaa /= 20.0; + Pb /= -6.0; + Pbb /= -12.0; + Pbbb /= -20.0; + Pab /= 24.0; + Paab /= 60.0; + Pabb /= -60.0; + } + + w = - VEC_DOT(n, v0); + + k1 = 1 / n[C]; k2 = k1 * k1; k3 = k2 * k1; k4 = k3 * k1; + + Fa = k1 * Pa; + Fb = k1 * Pb; + Fc = -k2 * (n[A]*Pa + n[B]*Pb + w*P1); + + Faa = k1 * Paa; + Fbb = k1 * Pbb; + Fcc = k3 * (gim_sqrt(n[A])*Paa + 2*n[A]*n[B]*Pab + gim_sqrt(n[B])*Pbb + + w*(2*(n[A]*Pa + n[B]*Pb) + w*P1)); + + Faaa = k1 * Paaa; + Fbbb = k1 * Pbbb; + Fccc = -k4 * (CUBE(n[A])*Paaa + 3*gim_sqrt(n[A])*n[B]*Paab + + 3*n[A]*gim_sqrt(n[B])*Pabb + CUBE(n[B])*Pbbb + + 3*w*(gim_sqrt(n[A])*Paa + 2*n[A]*n[B]*Pab + gim_sqrt(n[B])*Pbb) + + w*w*(3*(n[A]*Pa + n[B]*Pb) + w*P1)); + + Faab = k1 * Paab; + Fbbc = -k2 * (n[A]*Pabb + n[B]*Pbbb + w*Pbb); + Fcca = k3 * (gim_sqrt(n[A])*Paaa + 2*n[A]*n[B]*Paab + gim_sqrt(n[B])*Pabb + + w*(2*(n[A]*Paa + n[B]*Pab) + w*Pa)); + } + + T0 += n[0] * ((A == 0) ? Fa : ((B == 0) ? Fb : Fc)); + + + T[A] += n[A] * Faaa; + T[B] += n[B] * Fbbb; + T[C] += n[C] * Fccc; + } + + gim_trimesh_unlocks_work_data(trimesh); + +} + +void btGIMPACTMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia) +{ + btTransform t; + t.setIdentity(); + + btVector3 aabbMin; + btVector3 aabbMax; + + getAabb(t,aabbMin,aabbMax); + + //not yet, return box inertia + + btVector3 halfExtents = (aabbMax-aabbMin)*0.5f; + + btScalar lx=2.f*(halfExtents.x()); + btScalar ly=2.f*(halfExtents.y()); + btScalar lz=2.f*(halfExtents.z()); + const btScalar x2 = lx*lx; + const btScalar y2 = ly*ly; + const btScalar z2 = lz*lz; + const btScalar scaledmass = mass * 0.08333333f; + + inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2)); + + /* + //prepareMeshes(t); + inertia.setValue(0.0f,0.0f,0.0f); + vec3f T; + VEC_ZERO(T); + + //Process Every triangle + GIM_TRIMESH * ptrimesh; + + for(size_t i = 0;igetLocalScaling(); + + aabb3f test_aabb; + test_aabb.minX = aabbMin[0]/scalevec[0]; + test_aabb.minY = aabbMin[1]/scalevec[1]; + test_aabb.minZ = aabbMin[2]/scalevec[2]; + + test_aabb.maxX = aabbMax[0]/scalevec[0]; + test_aabb.maxY = aabbMax[1]/scalevec[1]; + test_aabb.maxZ = aabbMax[2]/scalevec[2]; + + for(i = 0;iprocessTriangle(btrivec,(int)i,(int)boxesresult[j]); + } + + ///unlocks + gim_trimesh_unlocks_work_data(ptrimesh); + + + GIM_DYNARRAY_DESTROY(collision_result); + } + +} + + diff --git a/Extras/GIMPACTBullet/btGIMPACTMeshShape.h b/Extras/GIMPACTBullet/btGIMPACTMeshShape.h new file mode 100644 index 000000000..3b4f92999 --- /dev/null +++ b/Extras/GIMPACTBullet/btGIMPACTMeshShape.h @@ -0,0 +1,114 @@ +/* +Bullet Continuous Collision Detection and Physics Library +Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/ + +This software is provided 'as-is', without any express or implied warranty. +In no event will the authors be held liable for any damages arising from the use of this software. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it freely, +subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef GIMPACT_MESH_SHAPE_H +#define GIMPACT_MESH_SHAPE_H + +#include "BulletCollision/CollisionShapes/btConcaveShape.h" +#include "BulletCollision/CollisionShapes/btStridingMeshInterface.h" +#include + +//#define GIMPACT_SHAPE_PROXYTYPE (MAX_BROADPHASE_COLLISION_TYPES + 1) + +//! Handle representation for each mesh part +/*! +Each mesh part must have a GIMPACT trimesh data (GIM_TRIMESH_DATA). +*/ +typedef unsigned long BT_GIMPACT_TRIMESH_DATA_HANDLE; + + +class BT_GIMPACT_TRIMESH_DATA_HANDLE_ARRAY: public std::vector +{ +public: + +}; + +class btGIMPACTMeshData +{ +protected: + void clearMeshParts(); + void addMeshPart(btStridingMeshInterface* meshInterface, int part); + void processMeshParts(btStridingMeshInterface* meshInterface); +public: + btStridingMeshInterface* m_meshInterface; + BT_GIMPACT_TRIMESH_DATA_HANDLE_ARRAY m_meshes; + + btGIMPACTMeshData(btStridingMeshInterface* meshInterface); + virtual ~btGIMPACTMeshData(); +}; + + +//! Handle representation for each mesh part +/*! +Each mesh part must have a GIMPACT trimesh (GIM_TRIMESH). +*/ +typedef void * BT_GIMPACT_TRIMESH_HANDLE; + + +class BT_GIMPACT_TRIMESH_HANDLE_ARRAY: public std::vector +{ +public: + +}; + +/// +///Uses an interface to access the triangles to allow for sharing graphics/physics triangles. +class btGIMPACTMeshShape : public ConcaveShape +{ +protected: + btGIMPACTMeshData * m_meshdata; + btVector3 m_scale; + + void clearMeshParts(); + void processMeshParts(btGIMPACTMeshData * meshdata); + +public: + BT_GIMPACT_TRIMESH_HANDLE_ARRAY m_gim_trimesh_parts; + + + btGIMPACTMeshShape(btGIMPACTMeshData * meshInterface); + + virtual ~btGIMPACTMeshShape(); + + + virtual int getShapeType() const + { + return GIMPACT_SHAPE_PROXYTYPE; + } + + + //! Function for retrieve triangles. + /*! + It gives the triangles in local space + */ + virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + + + //debugging + virtual char* getName()const {return "GIMPACT_SHAPE_PROXYTYPE";} + + virtual void prepareMeshes(const btTransform & trans) const; + + ///getAabb returns the axis aligned bounding box in the coordinate frame of the given transform t. + virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + + virtual void setLocalScaling(const btVector3& scaling) ; + virtual const btVector3& getLocalScaling() const ; + + virtual void calculateLocalInertia(btScalar mass,btVector3& inertia); + +}; + +#endif //GIMPACT_MESH_SHAPE_H diff --git a/Extras/Jamfile b/Extras/Jamfile index 615dfe77a..61d95c4b6 100644 --- a/Extras/Jamfile +++ b/Extras/Jamfile @@ -6,4 +6,6 @@ SubInclude TOP Extras LibXML ; #SubInclude TOP Extras EPA ; #SubInclude TOP Extras ExtraSolid35 ; #SubInclude TOP Extras quickstep ; +#SubInclude TOP Extras GIMPACT ; +#SubInclude TOP Extras GIMPACTBullet ; #SubInclude TOP Extras GPUphysics ; diff --git a/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h b/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h index 3462e6e47..7b35df09d 100644 --- a/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h +++ b/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h @@ -44,7 +44,9 @@ CONCAVE_SHAPES_START_HERE, TRIANGLE_MESH_SHAPE_PROXYTYPE, ///used for demo integration FAST/Swift collision library and Bullet FAST_CONCAVE_MESH_PROXYTYPE, - +///Used for GIMPACT Trimesh integration + GIMPACT_SHAPE_PROXYTYPE, + EMPTY_SHAPE_PROXYTYPE, STATIC_PLANE_PROXYTYPE, CONCAVE_SHAPES_END_HERE,